历史上的今天
今天是:2025年03月12日(星期三)
2020年03月12日 | 任务12:中断与定时器
2020-03-12 来源:eefocus
本系列教程以AVR单片机为对象,介绍单片机的快速开发方法。
参考教材:《单片机技术及应用项目教程》 栾秋平 电子工业出版社 2019.6 第1版
本文介绍中断与定时器。

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

二、定时器
(1)定时器
定时器启动后,开始定时,定时时间到,则置相应的中断标志位,然后向CPU申请中断。定时器的定时功能是以计数的方式来工作的,此时是对单片机内部的脉冲进行加1计数,此脉冲的周期是机器周期分频后得到的,其公式如下:
定时时间 = (溢出值 – 计数初值)× 内部脉冲
定时器可以用来实现很多功能,例如我们可以产生时间;可以在检测系统中,对被检测点进行定时取样;可以在读按键状态时,产生一个消抖时间等等。
(2)计数器
计数器启动后,对外部输入脉冲进行加1计数,计数器加满溢出时,将中断标志位置位,然后向CPU申请中断,其公式如下:
计数脉冲个数 = 溢出值 – 计数初值
计时器在很多应用场合都发挥着作用;例如在工业生产线上,对零件和产品进行计数;在大桥和高速公路上对车流量进行统计等等。
三、程序实现
//加入包含文件
#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
史海拾趣
|
本帖最后由 jameswangsynnex 于 2015-3-3 19:54 编辑 由于各型号手机所附带的充电器插口不同,以造成各手机充电器之间不能通用。当用户手机充电器损坏或丢失后,无法修复或购不到同型号充电器,使手机无法使用。万能充电器厂家看到这样的商机,就 ...… 查看全部问答> |
|
最近买了个usb接口键盘,老是要重插才能用,按照网上所说把设备管理-》usb room hub-》电源管理-》允许计算机关闭设别以节约电源停掉了。好像也不是qq冲突问题,在qq目录中找不到网上所说的的那两个文件。如果我把液晶显示其关掉,让机器开着, ...… 查看全部问答> |
|
我的发送程序 #include \"vxWorks.h\" #include \"fioLib.h\" #include \"stdio.h\" #include \"unistd.h\" #include \"string.h\" #include \"usrLib.h\" #include \"errnoLib.h\" #include \"hostLib.h\" #include \"sockLib.h\" #incl ...… 查看全部问答> |
|
大家好。本人对于UCOS还是新手。想找UCOS的系统移植到C51上,遇到一些问题。希望大家来帮忙解决一下。 (在网上下载了一个移植实例有些看不太明白) 问题一:实例代码如下 ;定义重定位段 ...… 查看全部问答> |
|
近日小弟准备用两组MC3486/MC3487实现数据通讯,但不知道MC3486/3487该怎么使用,接口电路怎么画?是否需要进行阻抗匹配?是否需要光藕隔离? 还望各位大哥小弟们赐教.谢谢~~~~~… 查看全部问答> |
|
请教:UCOS-II在TI的VC33移植时需要保存和恢复的全部寄存器都是那些、正确顺序是? 我正在研究UCOS-II在TI的VC33移植,但从33资料中确定不了以上问题,请有经验的高手指教,小弟不胜感激啊!! 我对TI公司的DSP(包括2812、c33、2407)的开发都有一定的经验了,欢迎和大家交流,我的的qq号是:61225451。… 查看全部问答> |
|
大家好,碰到一个问题想和大家讨论下,我用的LPC2478芯片内存是64k, 现在想从中分配出一段内存来做缓冲区。要的是绝对地址,和寄存器地址一样的那种。请问如何分配。求指导… 查看全部问答> |




