历史上的今天
今天是:2025年05月13日(星期二)
2018年05月13日 | 中断及定时器实现时钟功能
2018-05-13 来源:eefocus
中断及定时器实现24时 时钟,程序如下:
#include
#define PORTLEN P0
sbit bit_select = P2^0;
sbit seg_select = P2^1;
unsigned char src[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char qrc[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char second1[8];
unsigned char shi = 0;
unsigned char fen = 0;
unsigned char miao = 0;
void timer0_init(void)
{
EA = 1; //打开总中断
TMOD |= 0x01; //设置工作方式
TH0 = (65536 - 20000) / 256;
TL0 = (65536 - 20000) % 256; //设置定时器初值,1ms产生一次中断
ET0 = 1; //打开定时器中断
TR0 = 1; //打开定时器,开始每隔1ms加1
} //打开计时器开始加1,当TH0 =0xff,TL0=0xff时,TF0(单片机内部定时器的溢出标志位,一般无需手动置位)由0置1,触发中断,并重新置0.
然后向cpu请求中断,cpu响应的话就跳转到中断函数,即void timer0_isr() interrupt 1
void timer1_init(void)
{
EA = 1;
TMOD |= 0x10;
TH1 = (65536 - 1000) / 256;
TL1 = (65536 - 1000) % 256;
ET1 = 1;
TR1 = 1;
}
void main()
{
timer0_init();
timer1_init();
while(1);
}
//while(1)相当于死循环,这边有个注意点,两个timer放while里外的区别,后文中具体讲解。
void display()
{
static unsigned char i = 0;
PORTLEN = 0x0; //消重影
seg_select = 1;
seg_select = 0;
PORTLEN = 0xff;
bit_select = 1;
bit_select = 0;
PORTLEN = second1[i];
seg_select = 1;
seg_select = 0;
PORTLEN = qrc[i];
bit_select = 1;
bit_select = 0;
i++;
if(8 == i)
{
i = 0;
}
}
void timer0_isr() interrupt 1
{
static unsigned char i = 0;
TH0 = (65536 - 20000) / 256;
TL0 = (65536 - 20000) % 256; //设置定时器初值,每隔20ms产生一次中断
i++;
if(50 == i)
{
i = 0;
miao++;
if(60 == miao)
{
miao = 0;
fen++;
if(60 == fen)
{
fen = 0;
shi++;
if(24 == shi)
{
shi = 0;
}
}
}
}
second1[0] = src[shi / 10];
second1[1] = src[shi % 10];
second1[2] = 0x40;
second1[3] = src[fen / 10];
second1[4] = src[fen % 10];
second1[5] = 0x40;
second1[6] = src[miao / 10];
second1[7] = src[miao % 10];
}
void timer1_isr() interrupt 3
{
TH1 = (65536 - 1000) / 256;
TL1 = (65536 - 1000) % 256;
display();
}
//interrupt x跟在interrupt 后面的x值是中断号,就是说这个函数对应第几个中断端口,在51中0 外部中断0 ; 1 定时器0 ;2 外部中断1 ;3 定时器1 ;4 串行中断
实际上编译的时候就是把你这个函数的入口地址方到这个对应中断的跳转地址
————————————————————————————————
接下来来讲讲while了,用A,B分别代替timer0_init time1_init 两个函数,A+,B+表示两个中断服务程序。
①A,B执行完继续执行A,但要注意的是,A,B的执行 只是在执行的最后打开了定时器,可以近乎当作A结束开始定时器累加,然后同理B,但是B一结束又到A,A中TH,TL重新给值导致一直在中断,并未进入中断服务函数,这里要修改的话,就需要加入一个自己的delay延时函数,给他时间进入中断服务程序,但是这样意义也不是多大不如第二种
②第二种的话,则是,A,B,执行完,就一直在while里,等到A,B发出中断响应,按照优先级进入中断服务程序,等中断服务程序按其内中断结束,返回while里,(在中断服务程序里已再次给初值,定时器开启后不自动关)B一直在刷新display,A则是给temp数组给值。
上图右侧 看作执行时间是错误的,忘了改了,中断服务程序里的1ms和20ms只是再次赋初值
上一篇:51单片机定时器中断程序
下一篇:中断定时器与流水灯
史海拾趣
|
Freescale 2009 seminar之十Hands-on Workshop CodeWarrior™ CodeWarrior for the Controller Continuum ►What is Eclipse? ►CW MCU v10.0 Features ►Basic Eclipse Terms ►C/C++ Perspective ►Debug Perspective ►Demonstration ►Lab 1 –Create a new pro ...… 查看全部问答> |
|
请教高手93C46的8位、16位读写程序怎么区分 SB+OP1=10B,OP0+写允许=01100000B 比如93C46的写允许8位是 1001100000既 00000010,01100000(0X02,0X60)   ...… 查看全部问答> |
|
看了quanzxhttps://bbs.eeworld.com.cn/viewthread.php?tid=86872&extra=&page=3 的帖子。似乎超过36V就很危险了… 查看全部问答> |
|
我在WinCE下作GSM打电话程序,有CreateFile可以打开串口,但是在串口接收线程里用ReadFile读数据却不成功 但是CreateFiel打开串口确实成功了啊,用GetLastError得到的错误码是:〖6〗-句柄无效。为什么 下面是我的程序 BOOL fReadState = ReadFi ...… 查看全部问答> |
|
程序错在哪里啊,请高手指点一下,都写了一天了,还不知道错在哪里 //保存为1.h #ifndef lcd1602_h #define lcd1602_h sbit rs= P2^7; //定义接口 sbit rw= P2^6; sbit e = P2^5; #define shuju P0 #define unch unsigned char #define unin unsigned int void shortdelay(unin m); //延时 vo ...… 查看全部问答> |
|
祝贺STM32赢得《2008年度EDNChina创新奖》的最佳产品奖 感谢广大网友的厚爱,意法半导体的基于ARM Cortex-M3的微控制器STM32产品系列,被业内专家和EDN China资深编辑组成的专家委员会推选为《2008年度EDN China创新奖》的候选产品,并经过EDN China读者和网站会员投票成为“微 ...… 查看全部问答> |




