一、认知单片机中的“中断”
(1)中断的基本概念
在计算机执行程序的过程中,当出现某种情况时,由服务对象向CPU发出请求当前程序中断的信号,要求CPU暂时停止当前程序的执行,而转去执行相应的处理程序,待处理程序执行完毕后,再返回继续执行原来被中断的程序,这样的过程称为中断过程。引起中断的原因或触发中断请求的来源称为中断源。为实现中断而设置的各种硬件和软件称为中断系统。
(2)采用中断技术的优点
实行分时操作,提高了CPU的利用率。当服务对象向CPU发出中断请求时,才使CPU转向为该对象服务,否则不影响CPU的正常工作。这样,利用中断可以使CPU同时为多个对象服务,从而大大提高了整个单片机系统的工作效率。
实现实时处理,及时处理实时信息。在工业现场控制中,常常要求单片机系统对信号进行实时处理。利用中断技术,各服务对象可以根据需要随时向CPU发出中断请求,CPU及时检测并处理各对象的控制要求,已实现实时控制。
对难以预料的情况或故障进行及时处理。在单片机系统工作过程中,有时会出现一些难以预料的情况或故障,如电源掉电、运算溢出、传输错误等,此时可以利用中断进行相应的处理而不必停机。
(3)中断的处理流程

二、定时器
(1)定时器
定时器启动后,开始定时,定时时间到,则置相应的中断标志位,然后向CPU申请中断。定时器的定时功能是以计数的方式来工作的,此时是对单片机内部的脉冲进行加1计数,此脉冲的周期是机器周期分频后得到的,其公式如下:
(2)计数器
计数器启动后,对外部输入脉冲进行加1计数,计数器加满溢出时,将中断标志位置位,然后向CPU申请中断,其公式如下:
三、程序实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
| //加入包含文件 #include "../include.h" //定义系统常量 //定义全局变量 uint8 u8g_DisplayString[8]; uint8 u8g_DisplayPoint[8]; //主程序 int main(void) { //定义局部变量 uint8 i; //目标板初始化,该函数会自动初始化相应的外设文件 TARGET_Init(); //初始化全局变量 for (i = 0; i < 8; i++) { u8g_DisplayString[i] = 0x00; u8g_DisplayPoint[i] = 0x00; } //在上电时,执行的相应操作 //后台主循环 while(1) { /* ********************************** 在这里完成自己的项目逻辑 ********************************** */ for (i = 0; i < 8; i++) { u8g_DisplayString[i] = i; } TARGET_Delayms(500, 1); for (i = 0; i < 8; i++) { u8g_DisplayString[i] = 8 + i; } TARGET_Delayms(500, 1); /* ********************************** 喂狗语句,大部分工程项目都不应去除 ********************************** */ #if INTERNAL_PERIPHERAL_WDT_MODE != 0 TARGET_WatchDogReset(); #endif } return 0; //永不执行 } //串口0接收中断服务处理函数,接收到的数据存储在 UDR0 寄存器中 #if INTERNAL_PERIPHERAL_UART0_MODE != 0 ISR(USART__RX_vect) { uint8 u8_UartData; u8_UartData = UDR0; #if PROTOCOL_MINIUART_UART0_MODE !=0 miniUART_UartInterrupt(&miniUART_UART0, u8_UartData); #endif } #endif //定时器0溢出中断服务处理函数 #if INTERNAL_PERIPHERAL_TIMER0_MODE != 0 ISR(TIMER0_OVF_vect) { #if INTERNAL_PERIPHERAL_TIMER0_MODE == 1 //在此完成逻辑内容 static uint8 u8_Number; u8_Number++; if (u8_Number > 7) { u8_Number = 0; } NIXIETUBE_SelectLED(u8_Number); NIXIETUBE_DrawLED(u8g_DisplayString[u8_Number], u8g_DisplayPoint[u8_Number]); #if PROTOCOL_MINIUART_UART0_MODE !=0 miniUART_TimerInterrupt(&miniUART_UART0); #endif #if PROTOCOL_MINIUART_CH432T_UART0_MODE !=0 miniUART_TimerInterrupt(&miniUART_CH432T_UART0); #endif #if PROTOCOL_MINIUART_CH432T_UART1_MODE !=0 miniUART_TimerInterrupt(&miniUART_CH432T_UART1); #endif //为了提高运行速度,将此语句写在中断服务处理函数里,用户在使用时,可不理会下列语句 TCNT0 = TIMER0_TCNT0; #elif INTERNAL_PERIPHERAL_TIMER0_MODE == 2 #endif } #endif //定时器1溢出中断服务处理函数 #if INTERNAL_PERIPHERAL_TIMER1_MODE != 0 ISR(TIMER1_OVF_vect) { //在此完成逻辑内容 //为了提高运行速度,将此语句写在中断服务处理函数里,用户在使用时,可不理会下列语句 TCNT1H = TIMER1_TCNT1H; TCNT1L = TIMER1_TCNT1L; } #endif //外部中断0中断服务处理函数 #if INTERNAL_PERIPHERAL_INT0_MODE != 0 ISR(INT0_vect) { //如果使用了CH432T,则调用相应的中断处理函数 #if EXTERNAL_MODULE_CH432T_MODE != 0 CH432T_INT(); #endif } #endif //外部中断1中断服务处理函数 #if INTERNAL_PERIPHERAL_INT1_MODE != 0 ISR(INT1_vect) { //如果使用了CH432T,则调用相应的中断处理函数 #if EXTERNAL_MODULE_CH432T_MODE != 0 CH432T_INT(); #endif } #endif //CH432T扩展串口0,接收调用函数 #if EXTERNAL_MODULE_CH432T_MODE != 0 void CH432T_Uart0(uint8 u8_UartData) { #if PROTOCOL_MINIUART_CH432T_UART0_MODE != 0 miniUART_UartInterrupt(&miniUART_CH432T_UART0, u8_UartData); #endif } #endif //CH432T扩展串口1,接收调用函数 #if EXTERNAL_MODULE_CH432T_MODE != 0 void CH432T_Uart1(uint8 u8_UartData) { #if PROTOCOL_MINIUART_CH432T_UART1_MODE != 0 miniUART_UartInterrupt(&miniUART_CH432T_UART1, u8_UartData); #endif } #endif
|