/*******************************************************************
Experiment name and content: Speed display LCD screen
Supporting book: "Introduction to STM8 MCU, Advanced and Application Examples"
Experimental platform and programmer: hardcore novice
/ #include "iostm8s208mb.h" //header file /port/pin definition
of the main control chip / #define LCDRS_SET PF_ODR|=0x01 //Set PF0 #define LCDRS_CLR PF_ODR&=0xFE //Clear 0PF0 #define LCDRW_SET PF_ODR|=0x08 //Set PF3 #define LCDRW_CLR PF_ODR&=0xF7 //Clear 0PF3 #define LCDEN_SET PF_ODR|=0x10 //Set PF4 #define LCDEN_CLR PF_ODR&=0xEF //Clear 0PF4 /Common data type definitions/ #define u8 uint8_t #define u16 uint16_t #define u32 uint32_t typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned long uint32_t; unsigned int long CNT; unsigned int long SPEED; unsigned int long VALUE; /User-defined area/ const unsigned char table1[]=“VALUE”; //LCD1602 displays string array 1 display effect const unsigned char table2[]=“FIGNTING”; //LCD1602 displays string array 2 display effect /global variable definition/ unsigned char PWM =0; //Define global variables to control duty cycle unsigned char num; //Define loop variable NUM /Function initialization definition/ void delay(u16 Count); //Delay function void TIM2_PWM_Init(void); //PWM initialization function void KEY_Init(void); //Key port function void KEY_Scan(void); //Key scan function void TIM4_Init(void); //TIM4 initialization function void Exti_Init(void); //External interrupt initialization function void Write_Com(unsigned char com); //Declaration of function to write command to 1602 LCD void Write_Inf(unsigned char inf); //Declaration of function to write data to 1602 LCD void LCD_Init(void); //1602 LCD initialization function declaration /**********************************************************/ int main(void) { //If the main clock source in CLK_CMSR is HSI, then CLK_CMSR=0xE1 //If the main clock source in CLK_CMSR is LSI, then CLK_CMSR=0xD2 //If the main clock source in CLK_CMSR is HSE, then CLK_CMSR=0xB4 CLK_CKDIVR = 0x00; if(CLK_CMSR!=0xE1) //Judge whether the main clock source in the main clock status register CLK_CMSR is HSI, if not, enter the if program segment { CLK_SWCR |= 0x01; //1. First, configure the clock switching enable bit SWEN=1 to enable the switching process CLK_SWR = 0xE1; //2. Select the main clock source and write the clock to be switched to the main clock switching register CLK_SWR while((CLK_SWCR & 0x08)==0); //3. Wait for the switching interrupt flag bit SWIF=1 in the clock switching control register CLK_SWCR CLK_SWCR=0; //4. Clear the relevant flag bits }LCD_Init(); //1602 LCD function initialization
TIM2_PWM_Init();
TIM4_Init();
KEY_Init();
Exti_Init();
for(num=0;num<16;num++)
{ Write_Inf(table1[num]);//Write string delay(50)
in the first line of LCD ; }
for(num=0;num<16;num++)
{
Write_Com(0x80+0x40+num); //Set the address to the second line of LCD
Write_Inf(table2[num]);
delay(50);
}
asm("rim"); //The priority of the MAIN program is reduced from level 3 to level 0 (turn on the main interrupt) while(1)12
{
Write_Com(0x18);
TIM2_PWM_Init();
KEY_Scan();
}}
/TIM2_PWM_Init() function***********/
void TIM2_PWM_Init(void)
{
TIM2_CR1 =0x80; //Preload enable, edge alignment, count up, disable counting
TIM2_PSCR=0x07; //Count period prescaler 8, count period 1us
TIM2_ARRH=0; //Preload value 100, PWM frequency is 10KHZ
TIM2_ARRL=250; //Read and write 16-bit registers, read and write high bits first
TIM2_CCMR2=0x78; //Channel 2 is PWM mode 1, preload CCR
TIM2_CCR2H=0;
TIM2_CCR2L=PWM; //Duty cycle 50
TIM2_CCER1=0x30; //Channel 1 is off, channel 2 is on
TIM2_CCER2=0x00; //Close channel 3
//TIM2_EGR=0x01; //Generate update event, initialize register
TIM2_CR1|=0x01; //Enable counter CEN=1
}
/TIM4_PWM_Init() function**********/
void TIM4_Init(void)
{
TIM4_CR1=0x80;//Preload enable, edge alignment, count up, disable count
TIM4_PSCR=0x07;//Counter prescaler value 128, counting cycle 1us
TIM4_ARR=250;//Preload value 250, interrupt every 2ms
TIM4_IER=0x01;//Enable update interrupt
asm("rim");//Switch interrupt
TIM4_EGR=0x01;//Generate update event, initialize register
TIM4_CR1|=0x01;//Enable counter CEN=1
}
/External interrupt initialization function*****/
void Exti_Init(void)
{
PE_DDR=0x00; //Set PE port as input
PE_CR1=0x00;
PE_CR2=0x04; //PE2 port floating input (enable external interrupt)
EXTI_CR1=0x20; //PE port only triggers interrupt on falling edge
}
/********************************************************************/
//Delay function delay(), with parameter count used to control the number of executions of the delay function, no return value
/***********************************************************/
void delay(u16 Count)
{
u8 i,j;
while (Count–)//Count parameter controls the number of delays
{
for(i=0;i<50;i++)
for(j=0;j<20;j++);
}
}
/KEY_Init() function*******/
void KEY_Init(void)
{
PG_DDR&=0x00; //Set PG port as input
PG_CR1|=0x30;//Set PG4 and PG5 as pull-up input
PG_CR2&=0x00;
}
/KEY_Scan() function/
void KEY_Scan(void)
{
unsigned char KEYNUM;
static unsigned char KeyNumFor;
KEYNUM=PG_IDR&0x30; //Read PG port, keep PG4 and PG5 two bits
delay(100);
if (KEYNUM0x20&&KeyNumFor0x30) //s1 pressed
{
PWM++;
if(PWM>=250) { PWM=250; }1234
}
else if (KEYNUM0x10&&KeyNumFor0x30&&PWM>0) //s2 is pressed
{
PWM–;
if(PWM<=1)
{
PWM=1;
}
}
KeyNumFor=KEYNUM;
}
/LCD1602 initialization function********/
//LCD1602 initialization function LCD1602_DIS, no return value, invisible parameter
//
/Function to write command to 1602 LCD****/
//Function to write command to 1602 LCD, with visible parameter com, no return value
//
void Write_Com(unsigned char com)
{
LCDRW_CLR;//Clear R/W to indicate write operation
LCDRS_CLR;//Clear R/S to indicate write command
PB_ODR=com;//Command is sent from PORTB
delay(50);
LCDEN_SET;//Set E to high
delay(50);
LCDEN_CLR;//Set E to low to generate falling edge, command is written
}
/Function to write command to 1602 LCD****/
//Function to write data to 1602 LCD, with parameter inf, no return value
//
void Write_Inf(unsigned char inf)
{
LCDRW_CLR; //Clear R/W to indicate write operation
LCDRS_SET; //Set RS to 1 to indicate write data
PB_ODR=inf; //Command is sent out by PORTB
delay(50);
LCDEN_SET; //Set E to high
delay(50);
LCDEN_CLR; //Set E to low to generate falling edge, command is written
}
/Initialize 1602 LCD****/
//Initialize 1602 LCD
//
void LCD_Init(void);
{
PF_DDR|=0x19; //Set PF0 PF3 PF4 to push-pull output
PF_CR1|=0x19;
PF_CR2|=0x00;
PB_DDR|=0xFF; //Set the PB port to push-pull output
PB_CR1|=0xFF;
PB_CR2|=0x00;
LCDRS_CLR;
LCDRW_CLR;
LCDEN_CLR;
Write_Com(0x38); //Configure 162 display, 8-bit data line format, 57 dot matrix
Write_Com(0x0F); //Set display on, no cursor
Write_Com(0x06); //Address automatically increases by 1 after writing characters
Write_Com(0x01); //Display clears to 0, data pointer clears to 0
}
/Interrupt function ******************/
#pragma vector=0x05
__interrupt void EXTI_PORTA_IRQHandler(void)
{
}
#pragma vector=0x06
__interrupt void EXTI_PORTB_IRQHandler(void)
{
}
#pragma vector=0x07
__interrupt void EXTI_PORTC_IRQHandler(void)
{
}
#pragma vector=0x08
__interrupt void EXTI_PORTD_IRQHandler(void)
{
}
#pragma vector=0x09
__interrupt void EXTI_PORTE_IRQHandler(void)
{
CNT++;
}
#pragma vector=0x0A
__interrupt void CAN_RX_IRQHandler(void)
{
}
#pragma vector=0x0B
__interrupt void CAN_TX_IRQHandler(void)
{
}
#pragma vector=0x0C
__interrupt void SPI_TX_IRQHandler(void)
{
}
#pragma vector=0x0D
__interrupt void TIM1_UP_OV_IRQHandler(void)
{
}
#pragma vector=0x0E
__interrupt void TIM1_CAPTURE_IRQHandler(void)
{
}
#pragma vector=0x0F
__interrupt void TIM2_UP_OV_IRQHandler(void)
{
}
#pragma vector=0x10
__interrupt void TIM2_CAPTURE_IRQHandler(void)
{
}
#pragma vector=0x11
__interrupt void TIM3_UP_OV_IRQHandler(void)
{
}
#pragma vector=0x12
__interrupt void TIM3_CAPTURE_IRQHandler(void)
{
}
#pragma vector=0x13
__interrupt void UART1_TX_IRQHandler(void)
{
}
#pragma vector=0x14
__interrupt void UART1_RX_IRQHandler(void)
{
}
#pragma vector=0x15
__interrupt void I2C_IRQHandler(void)
{
}
#pragma vector=0x16
__interrupt void UART3_TX_IRQHandler(void)
{
}
#pragma vector=0x17
__interrupt void UART3_RX_IRQHandler(void)
{
}
#pragma vector=0x18
__interrupt void ADC_IRQHandler(void)
{
}
#pragma vector=0x19
__interrupt void TIM4_UP_OV_IRQHandler(void)
{
TIM4_SR&=0xFE;//Clear 0 update flag
SPEED=CNT;
CNT=0;
VALUE=SPEED30000/500;
}
#pragma vector=0x1A
__interrupt void FLASH_END_IRQHandler(void)
{
}
//******************************************************************
This program uses the size of PWM to adjust the duty cycle.
An external load DC motor is connected. The DC motor has 500 turns and 1 turn is 500 pulses.
Because 2ms is 4 pulses, the channel button adjusts the maximum duty cycle to 250, and the frequency is 500HZ. It is calculated that the motor rotation is 2ms4 pulses, then 1min=(250060)/500
is equal to 240 turns/min.
Then the problem comes. The program system of my display screen reminds me that
I have declared it before, why is it still showing like this? Please help me, thank you!!!
This problem has been solved. There is an extra ":" in the upper layer where I took the screenshot, so it is a program error. It seems that I need to be more careful next time. Finally, the display screen shows it.
Previous article:B-1.19 Protocol Analysis--STM8 uses its own bootloader
Next article:About iar for stm8: iar Fatal Error
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- How to turn on the internal enable of Panasonic servo drive?
- What is the rigidity setting of Panasonic servo drive?
- How to change the inertia ratio of Panasonic servo drive
- What is the inertia ratio of the servo motor?
- Is it better for the motor to have a large or small moment of inertia?
- What is the difference between low inertia and high inertia of servo motors?
- The price of domestic chip substitutes is only 1/5 of imported ones. Will domestic companies have a great opportunity?
- TI reference circuit solution for electric vehicle power management
- S digital receiving channel architecture
- The role of adding a reverse diode to the be pole of the transistor
- Sub-library: Motion Algorithm Library
- TI radar technology is changing three trends in the in-cockpit sensing market
- Prize-giving event: Blind box delivery | Murata’s Pet Pink Month is officially launched!
- AD packaging for self-use HR911105A 100M and HR911130A 1000M network ports
- Serial port expansion
- Design of TPS53355 ripple injection circuit