1207 字
6 分钟
【51单片机】04 - 定时器和中断(下)
[51单片机] 第七节 定时器和中断总结<代码部分>
ps: 单片机的可位寻址/不可位寻址
- 可位寻址:可以对单个位赋值
- 不可位寻址:只能整体赋值
代码示例:
void Timer0_Init(){ TMOD=0x01; //0000 0001 TF=0;}定时器的快捷配置

晶振电路简介(这里所使用晶振为11.0592MHZ)

一、中断测试代码
#include <REGX52.H>#include "Tmier0.h"
// void Timer0_Init()//定时器配置// {// //TMOD=0x01; //0000 0001 //缺点:会影响到其他定时器// TMOD &= 0xF0;//把TMOD的低四位清零,高四位保持不变 //优点:不影响高四位(其他定时器的配置)// TMOD |= 0X01;//把TMOD的最低为置1,高四位保持不变// TF0=0; // Gate = 0;// TR0 = 1;//定时器0允许计数// //mark// TH0=64535/256;//16进制 取高八位// TL0=64535%256;//取低八位// ET0=1;//T0的中断溢出允许位// EA=1;//总的允许位// PT0=0;// IP// }
//mark//分析:如何计1s?//0~65535//每隔1us计数加一 12M 12分频//总共定时时间65535us//64535离计数器溢出差值1000,所以计时时间为1ms//最大计65ms,所以这里分出1ms比较合适,再定义其他变量进行秒的计数
void main(){ Timer0_Init();//定时器初始化,中断溢出会跳到 Timer0_Routine() interrupt 1 while(1) {
}}
//unsigned int T0Count;//全局变量void Timer0_Routine() interrupt 1 //中断子程序{
static unsigned int T0Count;//静态局部变量,保证退出函数之后不销毁 //TH0=64535/256;//计数器溢出中断后,计数会清理,所以每次进入中断后需要再赋初值 //TL0=64535%256; TL0 = 0x66; //设置定时初始值 TH0 = 0xFC; //设置定时初始值 T0Count++;//每次进入中断子程序,秒控制器自加一 if(T0Count>=1000)//每1s执行对P2_0的操作 { T0Count=0; P2_0 =~P2_0; }}ps: 中断执行模块不宜存在过于复杂的任务
二、基于中断系统的流水灯按键控制
#include <REGX52.H>#include "Timer0.h"#include "Key.h"#include <INTRINS.H>
// void Timer0_Init()//定时器配置// {// //TMOD=0x01; //0000 0001 //缺点:会影响到其他定时器// TMOD &= 0xF0;//把TMOD的低四位清零,高四位保持不变 //优点:不影响高四位(其他定时器的配置)// TMOD |= 0X01;//把TMOD的最低为置1,高四位保持不变// TF0=0; // Gate = 0;// TR0 = 1;//定时器0允许计数// //mark// TH0=64535/256;//16进制 取高八位// TL0=64535%256;//取低八位// ET0=1;//T0的中断溢出允许位// EA=1;//总的允许位// PT0=0;// IP// }
//mark//分析:如何计1s?//0~65535//每隔1us计数加一 12M 12分频//总共定时时间65535us//64535离计数器溢出差值1000,所以计时时间为1ms//最大计65ms,所以这里分出1ms比较合适,再定义其他变量进行秒的计数
unsigned char keynum,LEDMode;void main(){ P2=0xFE;//初始化,点亮第一个LED Timer0_Init();//定时器初始化,中断溢出会跳到 Timer0_Routine() interrupt 1 while(1) { keynum = Key(); if(keynum) { if(keynumcrol和cror函数区别于<<,>>移位操作符,具有“循环移位”的特性,不需要考虑移位“溢出”;
三、基于定时器的LCD数字时钟
#include <REGX52.H>#include "LCD1602.h"#include "Timer0.h"
unsigned int sec=55,min=59,hour=23; //秒时钟 分时钟 小时时钟 这里我们赋上初值
void main(){ LCD_Init(); LCD_ShowString(1,1,"CLOCK:");//字符串静态显示不需要放在while中 LCD_ShowString(2,3,": : "); //LCD_ShowNum(2,1,sec,2);//需要更新显示 Timer0_Init(); while(1) { LCD_ShowNum(2,1,hour,2);//思考:动态的信号需要更新显示,静态的信号一般不用放在while循环中 LCD_ShowNum(2,4,min,2); LCD_ShowNum(2,7,sec,2); }}
void Timer0_Routine() interrupt 1 //中断子程序 秒控制计数器{ static unsigned int T0Count;//静态局部变量,保证退出函数之后不销毁 //不定义为全局变量是为了作为子函数内容,方便调用这个函数模板 TL0 = 0x66; //设置定时初始值 TH0 = 0xFC; //设置定时初始值 T0Count++;//每次进入中断子程序,秒控制器自加一 if(T0Count>=1000)//每1s执行对P2_0的操作 { T0Count=0; P2_0=~P2_0; sec++; if(sec >=60) { sec=0; min++; } if(min >=60) { min=0; hour++; } if(hour >=24) { hour=0; } }}思考:Verilog/VHDL和单片机(c语言) 程序执行区别?
- c语言程序为顺序执行,而非并行执行,单片机中需要动态执行的任务要放在while循环体中
【51单片机】04 - 定时器和中断(下)
http://www.turinblog.cn/posts/51单片机04---定时器和中断下/