上篇笔记记录到51单片机的中断允许寄存器、定时器/计数器工作方式寄存器(TMOD)、定时器/计数器控制寄存器(TCON)各位的作用。这些寄存器都是用来为编写定时器中断程序编写的初始化部分而服务的。然后今天再这里补填中断函数的编写格式,以后就可以编写定时器中断程序了。
1.中断服务程序的写法
C51的中断函数格式如下:
void 函数名() 中断号 using 工作组
{
中断服务程序内容
}
与一般的C语言程序相比,中断服务程序有一下特点
- 中断函数不能返回任何值,所以函数名前用void;
- 函数名随便起,但不能与C51语言中的关键字同名(同C语言函数要求)
- 中断函数不能带任何参数,故函数名后的括号内为空
- 中断号是指单片机中的几个中断源的序号,列表如下(红方框内内容)
图1.51单片机中的中断源
此序号是编译器识别不同中断的唯一符号,在程序编写中定要写正确。
- “using 工作组”是指这个中断函数使用单片机内存中4组工作寄存器中的哪一组,C51编译器在编译程序时会自动分配工作组,因此这句话经常被省略不写。
2.定时器1中断程序编写
#include
#define uint unsigned int
#define MANY_KEY_DELAY 1
#define TOTAL_TIME_NUM 5
#define ONE_SECOND 20
uint num;
uint num1;
uint flag_key;
//流水灯的第一列
sbit led1 = P1^0;
//第一个按钮位
sbit key = P3^1;
//按钮的接地端
sbit h_key6 = P3^6;
//函数申明
void T1_end_AND_change_status();
void delayms(uint xms);
void init_timer();
void data_init();
void key_scan();
void main()
{
//初始化数据变量
data_init();
//初始化T1定时器
init_timer();
while(1){
//不断检测此按钮是否被按下
key_scan();
//检测一个大周期定时是否完成
//使按下按钮后相应的位发生电平反转
T1_end_AND_change_status();
}
}
//自定义函数:数据初始化
void data_init()
{
num = 1;
num1 = 1;
flag_key = 0;
h_key6 = 0;
}
//自定义函数:初始化TMOD、TCON、中断寄存器,并装入计数初值
void init_timer()
{
//选中定时器1
TMOD = 0x10;
//定时器1的初值
TH1 = (65536 - 45872) / 256;
TL1 = (65536 - 45872) % 256;
//开总中断,
//定时器1中断
EA = 1;
ET1 = 1;
}
//自定义函数:延迟xms ms
void delayms(uint xms)
{
uint i, j;
for(i = xms; i > 0; i--)
for(j = 110; j > 0; j--);
}
//自定义函数:检测哪一个按键被按下
void key_scan()
{
if(key == 0){
//<1>.待按钮被按下后的稳定状态
delayms(10);
//<2>.操作:
//开启定时器,由T1时间到达关闭T1定时器
TR1 = 1;
//记住按钮已被按下
flag_key = 1;
//点亮响应的流水灯
led1 = 0;
//<3>.等待按键的释放
while(!key);
}
}
void T1_end_AND_change_status()
{
//T1计时完成
if(num >= TOTAL_TIME_NUM * ONE_SECOND){
num = 0;
//检测有哪些按钮被按下,结束其高低电平的转换
if(flag_key){
flag_key = 0;
//按钮信号以低电平结束
led1 = 1;
//一旦检测到总的计时时间到则关闭定时功能
//当有任何按钮再次被按下时,T1定时器再被开启
//需要在按钮被按下的前提下设置此语句,防止没有任何按钮按下时到达定时器时间设置
TR1 = 0;
}
}
//按钮的电平反转
if(num1 >= MANY_KEY_DELAY * ONE_SECOND){
num1 = 0;
if(flag_key){
led1 = ~led1;
}
}
}
//中断函数编写
void T1_time() interrupt 3
{
TH1 = (65536 - 45872) / 256;
TL1 = (65536 - 45872) % 256;
num++;
num1++;
}
此源程序经编译链接生成可执行文件后,下载到单片机中,按下key对应的按键时,流水灯1就会以1s的高低电平交换显示。照片一张作为纪念:
图2.闪烁的流水灯
3.程序分析
程序从main函数出开始运行。自在main函数中对个寄存器初始化后,待按键按下(TR1=1)时,定时器1开始从当前值开始计时,当计数计满溢出时,TCON的TF1向CPU申请中断从而进入中断函数内执行中断函数内的语句,当把中断函数内的语句执行完毕后,再返回到main函数开始中断处。当在中断函数中重新给定时器赋新值后(若不赋新值,则从0开始计),则将又会过与原来一样长的时间后发生中断。
此程序的中断周期是50ms(晶振频率为11.0592)。此程序随时等待按钮被按下,只有按钮被按下时才开始计时,中断程序才会生效。定时器被启动后,将会以50ms的周期进行中断产生,当计满1s时,流水灯的状态反转一次。当计满5s后定时器再次被关闭。程序重新等待按钮被按下。
4.总结
使用定时器中断的方式可以得到以高低电平反转的方波。在现实生活中我们可以用这种方波做很多事情,如红外遥控器就是采用的此种原理对不同按钮进行编码,经发射电路将此方波发射出去,再由相应的接收电路接受此方波,然后对其进行解码,得到原信号进而可以判断此信号是想要做出什么样的操作。
当然,使用单片机编写程序不再是单纯的写代码,还需要会阅读各种电路图和电器件的特性。
关键字:定时器 中断程序
引用地址:
定时器中断程序编写
推荐阅读最新更新时间:2024-03-16 14:54
定时器中断—频率计程序
/*注:定时器中断的例子,简单的频率计,初学者留意各引脚电 压极性和电压值,不可超出5V,我们只是做学习实验,不要 超出51hei单片机学习板的承受范围,否则要求对电子非常熟悉, 不然会烧坏芯片, 版权:www.51hei.com,注意:P1.3与P1.7要相连接 如果是测量外部频率要共地. */ #include reg52.h //头文件 #include intrins.h #define uchar unsigned char//宏定义 #define uint unsigned int sbit Fin=P1^3; //测量频率管脚 sbit Fout=P1^7; //发生频率管脚 uchar code table =
[单片机]
【STM32】HAL库 STM32CubeMX教程六----定时器中断
前言: 今天我们来学习定时器,32的定时器有着非常丰富的功能, 输入捕获/输出比较,PWM,中断等等。是我们学习STM32最频繁使用到的外设之一,所以一定要掌握好,这节我们讲解定时器中断,本系列教程将对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片: STM32F407ZET6/STM32F103ZET6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 5 知识概括: 通过本篇博客您将学到: SMT32定时器原理 STM32CubeMX创建定时器例程 HAL库TIM定时器函数库 定时器
[单片机]
【STM32】TIM---基本定时器
一、TIM 简介 定时器最基本功能:定时 定时发送 USART 数据 定时采集 AD 数据等 定时器与 GPIO 结合 测量输入信号脉冲宽度 产生输出波形 等 ▲ 各个定时器的特性 二、基本定时器 基本定时器 :TIM6 和 TIM7 ,基本功能完全一样,但所占资源彼此完全独立。 ▲ 基本定时器的功能框图 基本定时器时钟只能来自内部时钟 基本定时器的内部时钟(CK_INT)频率为 84MHz 基 本定时器还专门用于 DAC 转换触发 只要设置 CK_PSC 和 TIMx_ARR 这两个寄存器的值就可以控制事件生成的时间 三、定时器周期计算 T o u t ToutTout:溢出时间,即定时多长时间
[单片机]
STM32在定时器中控制步进电机
写WEB程序的时候,发现如果加上步进电机控制的话,就会出现问题。原因是如果把电机控制放在uip循环中处理的话,因为控制电机涉及到时间问题。所以必须解决,想到的方法就是多任务的思想。把步进电机的处理放在定时器中断里面。这样的话就能避免问题了。顺便学习了库函数操作定时器。这里用到的定时器功能简单,只需要产生更新中断。 下面是定时器初始化代码 //定时器3初始化 //arr:定时重装值 //psc:分频值 void TIM3_Init(uint16_t arr, uint16_t psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_
[单片机]
STM32F103mini教程通用定时器
一.通用定时器的基本原理 1.三种STM32定时器区别 2.通用定时器功能特点描述 (1)STM32 的通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定时器功能特点包括: ①位于低速的APB1总线上(APB1) ②16 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。 ③16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数 为 1~65535 之间的任意数值。 ④4 个独立通道(TIMx_CH1~4),这些通道可以用来作为: (每个定时器都有四个通道,互不影响) 输入捕获 输出比较 PWM 生成(边缘或中间对齐模式) 单脉冲模式输出 ⑥可使用外
[单片机]
PIC单片机引脚中断程序的设计技巧
1 简 述
所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7"RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。
在设计引脚中断程序时,有三个需要特别注意的地方。一是,在清除P0RTB中断标志位RBIF之前,必须安排一条必不可少的,以PORTB端口数据寄存器PORTB为源寄存器的读操作指令。放置这一指令的目的有时并不只是为了读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF标志位,为下一次中断做好准备。二是,由于端口PORTB是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要的虚假
[单片机]
STM32学习总结之Sysstick(系统滴答定时器)
学习内容: 1、Cortex-M3 在内核部分 包含了一个简单的定时器——SysTick timer STM32内核有一个定时器。 2、有定时器就需要有时钟源,时钟源可以是内部的还可以是外部的,需要阅读使用手册确定什么作为时钟源。 在STM32 中SysTick 以 HCLK(AHB 时钟)或HCLK/8 作为运行时钟 3、SysTick 是一个24 位的定时器,即一次最多可以计数2^24 个时钟脉冲,这 个脉冲计数值被保存到 当前计数值寄存器STK_VAL(SysTick current value register) 中,只能向下计数,每接收到一个时钟脉冲STK_VAL 的值就向下减1,直至0,当STK_VAL 的值被
[单片机]
MSP430f2272单片机中断控制4X4键盘程序
#include msp430f2272.h int yu ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; int i,j,k,temp,dat,ms; void delay(int ms) { while(ms--) for(i=0;i 2;i++); } int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P1DIR |=0x0f; P2DIR
[单片机]