This post was last edited by ZXDSCCD on 2018-3-29 06:02 //Timer initialization and startup void TIM2_Init(void) { CLK_PCKENR1_PCKEN10=1; //Turn on the timer 2 peripheral clock TIM2_PSCR=0x0f; //No frequency division TIM2_ARRH = 0x27; // Automatic reload register, 10000 TIM2_ARRL = 0x10; //Counting starts from the beginning when the count reaches this value (update) TIM2_CNTRH =0x00; //Set the counter start value (this program is added after an exception occurs) TIM2_CNTRL =0x00; TIM2_IER = 0x01; //Allow update interrupt TIM2_SR1_UIF=0; //Clear interrupt flag (this code is added after an exception occurs, the exception remains the same) TIM2_CR1 = 0x85; // Enable overflow interrupt and start counting } // Below is the timer 2 interrupt program // TIM2 overflow interrupt, sampling time is timed #pragma vector = TIM2_OVR_UIF_vector __interrupt void EXIT_TIM2_OVR(void) //Interrupt service function { TIM2_SR1_UIF=0; // Clear interrupt flag TIM2_CR1 = 0x00; // Stop counter 2 TIM2_CNTRH = 0x13; // Set the counter start value, 5000 (this program is added after an exception occurs) TIM2_CNTRL = 0x88; TIM2_CR1 = 0x85; // Enable overflow interrupt and start counting } #include
//Main function int main( void ) { asm("rim"); TIM2_Init(); while(1); } According to the above program, it can enter the interrupt when counting to 10000, but the problem is that the timer enters the interrupt first (starting counting from 5000) when it starts, and then enters the interrupt again after counting to 10000. The same situation occurs when changing to timer 3, timer 4, and timer 5. Whether it is to clear the interrupt flag first and then start the timer, or to clear the interrupt flag immediately after starting the timer, the effect is the same. The effect is the same when adjusting the initialization order back and forth. I have been tossing around all night and still haven't figured it out.
This post was last edited by ZXDSCCD on 2018-4-10 19:55 No one has replied~~!! I will reply myself. #include
#include
void TIM2_Init(void) { CLK_PCKENR1_PCKEN10=1;//Turn on the timer 2 peripheral clock TIM2_PSCR = 0x07;//Use the internal clock, divided by 4//TIM2_CNTRH = 0x00; //TIM2_CNTRL = 0x00; TIM2_ARRH = 0x23;//Auto-reload value 9000, when counting to this value, the counter starts counting again from 0 TIM2_ARRL = 0x28; TIM2_CNTRH = 0x00; TIM2_CNTRL = 0x00; TIM2_CCR1H = 0xff; TIM2_CCR1L = 0xff; TIM2_CCR2H = 0xff; TIM2_CCR2L = 0xff; //TIM2_ARRH = 0xC0; // Automatic reload register, reset default value is 0xff, so no need to set //TIM2_ARRL = 0x00; // Count reaches this value and restarts counting (update) TIM2_IER = 0x01; // Allow update interrupt TIM2_SR1_UIF = 0; //TIM2_CR1 = 0x81; // Start counting } void LCD_Init(void) { CLK_PCKENR2_PCKEN22=1; // Turn on RTC clock, LCD refresh frequency is related to this clock CLK_PCKENR2_PCKEN23=1; // Turn on LCD clock, read and write LCD registers using this clock LCD_CR1=0x06; // Flash off // 8 division, // 1/4 duty, 1/3 bias LCD_CR2=0xFE;//Per pixel pause time 7clk, high drive, high voltage, internal voltage LCD_FRQ=0x08;//Frequency division coefficient LCD_PM0=0xFF;//Write data directly to the address of LCD_PM0 register LCD_PM1=0xFF;//Write data directly to the address of LCD_PM1 register LCD_PM2=0x1f;//Write data directly to the address of LCD_PM2 register LCD_CR4=0x02;//LCD_RAM page switching, 1/8duty, 1/4bias LCD_CR3=0x41;//Enable LCD function } void fuhaoxianshi(unsigned char number,unsigned char value) { switch(number) { case 1: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM7_S202=value;//S1 MMHG break; case 2: LCD_CR4|=0x04;//Switch register 4567 LCD_RAM0_S004=value; //S2 heart rate hundreds break; case 3: LCD_CR4|=0x04;//Switch register 4567 LCD_RAM4_S104=value;//S3 heartbeat symbol break; case 4: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM7_S205 =value;//S4 irregular heartbeat break; case 5: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM11_S309=value;//S5 sound symbol break; case 6: LCD_CR4|=0x04;//Switch register 4567 LCD_RAM1_S009=value;//S6 power break; case 7: LCD_CR4|=0x04;//Switch register 4567 LCD_RAM4_S109=value;// S7 battery break; case 8: LCD_CR4|=0x04;// switch register 4567 LCD_RAM2_S019=value;//90 break; case 9: LCD_CR4&=0xFB;// switch register 0123 LCD_RAM12_S319=value;//120 break; case 10: LCD_CR4&=0xFB;// switch register 0123 LCD_RAM9_S219=value;//150 break; case 11: LCD_CR4&=0xFB;// switch register 0123 LCD_RAM9_S218=value;// memory break; case 12: LCD_CR4&=0xFB;// switch register 0123 LCD_RAM5_S118=value;// double 2 break; case 13: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM2_S018=value;//Double 1 break; case 14: LCD_CR4|=0x04;//Switch register 4567 LCD_RAM5_S119=value;// break; case 15: LCD_CR4|=0x04;//Switch register 4567 LCD_RAM2_S020=value; break; case 16: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM13_S320=value; break; case 17:LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM9_S220=value; break; case 18: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM6_S120=value; break; case 19: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM2_S020=value; break; case 20://COL LCD_CR4|=0x04;//Switch register 4567 LCD_RAM6_S120=value; break; case 21: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM8_S214=value; break; case 22: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM5_S114=value; break; case 23: LCD_CR4|=0x04;//Switch register 4567 LCD_RAM5_S113=value; break; case 24: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM1_S014=value; break; case 25: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM12_S316=value; break; case 26: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM12_S318=value; break; case 27: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM2_S019=value; break; case 28: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM5_S119=value; break; case 29: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM7_S203=value; break; } } void shuzixianshi(unsigned char number,unsigned char value) { unsigned char A=0; // A unsigned char B=0; // FGB unsigned char C=0; // EC unsigned char D=0; // D unsigned char E=0; unsigned char F=0; unsigned char G=0; switch(value) { case 0: A=1; B=1; C=1; D=1; E=1; F=1; break; case 1: B=1; C=1; break; case 2: A=1; B=1; D=1; E=1; G=1; break; case 3: A=1; B=1; C=1; F=1; G=1; break; case 6: A=1; C=1; D=1; E=1; F=1; G=1; break; case 7: A=1; B=1; C=1; break; case 8: A=1; B=1; C=1; D=1;A=1; B=1; C=1; D=1; F=1; G=1; break; case 10: A=1; D=1; E=1; F=1; G=1; break; } switch(number) { case 1: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM7_S200=A; LCD_RAM10_S300=B; LCD_RAM10_S301=F; LCD_CR4|=0x04;//switch register 4567 LCD_RAM0_S000=C; LCD_RAM3_S100=D; LCD_RAM3_S101=E; LCD_RAM0_S001=G; break; case 2: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM10_S303=A; LCD_RAM10_S302=B; LCD_RAM11_S304=F; LCD_CR4|=0x04;//Switch register 4567 LCD_RAM0_S002=C; LCD_RAM3_S102=D; LCD_RAM3_S103=E; LCD_RAM0_S003=G; break; case 3: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM7_S206=A; LCD_RAM11_S305=B; LCD_RAM11_S306=F; LCD_CR4|=0x04;//Switch register 4567 LCD_RAM4_S105=C; LCD_RAM4_S106=D; LCD_RAM0_S006=E; LCD_RAM0_S005=G; break; case 4: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM7_S207=A; LCD_RAM11_S307=B; LCD_RAM11_S308=F; LCD_CR4|=0x04;//switch register 4567 LCD_RAM0_S007=C; LCD_RAM4_S107 =D; LCD_RAM4_S108=E; LCD_RAM1_S008=G; break; case 5: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM0_S001=A; LCD_RAM0_S000=B; LCD_RAM3_S100=C; LCD_RAM7_S201=D; LCD_RAM3_S102=E; LCD_RAM0_S002=F; LCD_RAM3_S101=G; break; case 6: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM0_S004=A; LCD_RAM0_S003=B; LCD_RAM3_S103=C; LCD_RAM7_S204=D; LCD_RAM4_S105=E; LCD_RAM0_S005=F; LCD_RAM4_S104=G; break; case 7: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM0_S006=A; LCD_RAM4_S106=B; LCD_RAM4_S107=C; LCD_RAM8_S208=D; LCD_RAM4_S108=E; LCD_RAM1_S008=F; LCD_RAM0_S007=G; break; case 8: LCD_CR4&=0xFB;//switch register 0123 LCD_RAM11_S311=A; LCD_CR4|=0x04;//switch register 4567 LCD_RAM1_S010=B; LCD_RAM4_S110=C; LCD_RAM4_S111=D; LCD_RAM5_S112=E; LCD_RAM1_S012=F; LCD_RAM1_S011=G; break; case 9:LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM12_S314=A; LCD_RAM12_S313=B; LCD_CR4|=0x04;//Switch register 4567 LCD_RAM1_S013=C; LCD_RAM5_S114=D; LCD_RAM5_S115=E; LCD_RAM1_S015=F; LCD_RAM1_S014=G; break; case 10: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM12_S317=A; LCD_CR4|=0x04;//Switch register 4567 LCD_RAM2_S016=B; LCD_RAM5_S116=C; LCD_RAM5_S117=D; LCD_RAM5_S118=E; LCD_RAM2_S018=F; LCD_RAM2_S017=G; break; case 11: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM1_S010=A; LCD_RAM4_S110=B; LCD_RAM8_S210=C; LCD_RAM11_S310=D; LCD_RAM8_S211=E; LCD_RAM1_S011=F; LCD_RAM4_S111=G; break; case 12: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM1_S012=A; LCD_RAM5_S112=B; LCD_RAM8_S212=C; LCD_RAM12_S312=D; LCD_RAM8_S213=E; LCD_RAM1_S013=F; LCD_RAM5_S113=G; break; case 13: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM1_S015=A; LCD_RAM5_S115=B; LCD_RAM8_S215=C; LCD_RAM12_S315=D; LCD_RAM9_S216=E; LCD_RAM2_S016=F; LCD_RAM5_S116=G; break; case 14: LCD_CR4&=0xFB;//Switch register 0123 LCD_RAM5_S117=A; LCD_RAM2_S017=B; LCD_RAM9_S217=C; break; } } void port_init(void) { PC_DDR=0x00;//All pins are input, with 32k pins and I2C, PC2 dual control, PC3 ON/OFF, PC4 memory, PC7 set PC_CR1=0xff; // input pull-up PC_CR2=0x08; // PC3 level interrupt enable, ON/OFF PD_ODR=0x00; // data output register, corresponding output port level PD_DDR=0x80; // PD7 is motor drive, other pins are all input, PD4, PD5 are COM4, COM5, other pins are floating PD_CR1=0xff; // push-pull output, input pull-up PD_CR2=0x00; // disable external interrupt PE_ODR=0x00; // data output register, corresponding output port level PE_DDR=0x40; // PE6 is output drive solenoid valve, other pins are all input PE_CR1=0xff; // push-pull output, input pull-up PE_CR2=0x00; // output mode maximum 2MHZ PF_DDR=0x00;//All input pins are input, PD4, PD5 are COM4, COM5, other pins are floating PF_CR1=0xff;//Input pull-up PF_CR2=0x00;//Disable external interrupt PG_DDR=0x00;//All input pins are input,PD4, PD5 are COM4, COM5, other pins are left floating PG_CR1=0xff; //Pull up input PG_CR1=0x00; //Disable external interrupt } void CLOCK_Init(unsigned char i) { if(i==1) //High frequency operation { CLK_ICKCR|=0x04; //Turn on internal low speed clock CLK_CRTCR=0x10; //RTC clock, use external low speed clock, no frequency division CLK_SWR=0x04; //Select external high speed crystal as main clock CLK_SWCR|=0x02; //Switch clock source CLK_CKDIVR=0x00; //12MHZ no frequency division } else //Low frequency operation { CLK_ICKCR|=0x04;//Turn on the internal low-speed clock CLK_CRTCR=0x04;//RTC clock, using the internal low-speed clock, no frequency division CLK_SWR=0x08;//Select the external low-speed oscillator as the main clock CLK_SWCR|=0x02;//Switch the clock source CLK_CKDIVR=0x00; //32k no frequency division} } #pragma vector = TIM2_OVR_UIF_vector __interrupt void EXIT_TIM2_OVR(void) //Interrupt service function { TIM2_SR1_UIF =0;//Clear interrupt flag TIM2_CR1 = 0x00; //Stop counter 1 TIM2_CNTRH =0x11;//Counter is assigned 4500, and starts counting from 4500 TIM2_CNTRL =0x94; TIM2_CR1 = 0x81;//Start counting PD_ODR^=0x80;//External motor drive port, high level drive} void main(void) { unsigned int j=0; asm("sim");//Turn off global interrupt CLOCK_Init(0);//Low frequency, internal low speed clock port_init();//Initialize IO port LCD_Init();//Initialize LCD TIM2_Init();//Initialize tim2 j=TIM2_SR1&0xC7;//Read TIM2 interrupt flag register shuzixianshi(10,1);//Display serial number 1 shuzixianshi(3,j/100);//Display TIM interrupt register value shuzixianshi(2,j%100/10); shuzixianshi(1,j%10); j=TIM2_CNTRH;//Read TIM counter value j=(j<<8)+TIM2_CNTRL; shuzixianshi(8,j%10000/1000);//Display counter valueshuzixianshi(7,j%1000/100); shuzixianshi(6,j%100/10); shuzixianshi(5,j%10); asm("rim");//Open global interruptshuzixianshi(10,2);//Display serial number 2 j=TIM2_SR1&0xC7;//Read TIM2 interrupt flag registershuzixianshi(3,j/100);//Display interrupt flag register valueshuzixianshi(2,j%100/10); shuzixianshi(1,j%10); j=TIM2_CNTRH;//Read counter valuej=(j<<8)+TIM2_CNTRL; shuzixianshi(8,j%10000/1000);//Display counter valueshuzixianshi(7,j%1000/100); shuzixianshi(6,j%100/10); shuzixianshi(5,j%10); TIM2_CR1 = 0x81; //Start countingwhile(1)//Loop read counter interrupt flag register and count value and display { shuzixianshi(10,3); j=TIM2_SR1&0xC7; shuzixianshi(3,j/100); shuzixianshi(2,j%100/10); shuzixianshi(1,j%10); j=TIM2_CNTRH; j=(j<<8)+TIM2_CNTRL; shuzixianshi(8,j%10000/1000); shuzixianshi(7,j%1000/100); shuzixianshi(6,j%100/10); shuzixianshi(5,j%10); } } The above is the single-step debugging of the complete program. The serial numbers 1, 2, and 3 are all normal. The counter starts counting from 0 and counts to 9000, generating an overflow interrupt (update).PD7 port outputs high level, and the motor runs. Segmented debugging also runs normally, but if the MCU is allowed to run by itself, the value of the interrupt register is 0x07 when the counter reaches segment number 3, indicating that both comparison interrupts and overflow interrupt flags are set, and the counter enters the interrupt program. Then the counter starts counting from 4500, PD7 directly outputs high level, the motor runs, and the motor stops after counting to 9000, and then starts counting from 4500 again, and counts to 9000 again, and the motor stops. From the phenomenon, the program can enter the interrupt normally when the timer overflows, but it is still the old problem, why does the timer enter the timer overflow interrupt as soon as it is started, and then it can run normally afterwards, and the same situation occurs after adjusting the start counting command and the global interrupt command position,