单片机定时器中断原理
#include "reg51.h"
//sbit OE=P2^3;
unsigned int SystemTime;
void timer0(void) interrupt 1 using 3 //中断部分代码,见下文的释疑
{
//
}
void main()
{
//根据下文的木桶比喻的话,如果TH0 = 0x00;TL0 = 0x00;则表示从桶底开始装水。
//TH0 = 0xdb;TL0 = 0xff;可以这样子理解相当于木桶里已经有部分液铅在里面,
//TH0和TL0这个两个值表示木桶里液铅的高度,即此时桶里只能从液铅的高度以上开始装水,
//TH0 = 0xff;TL0 = 0xff;即表示桶的最高位置.
//下面是个死循环,程序里每运行一步TH0和TL0都会增加,当增加到TH0 = 0xff;TL0 = 0xff;
//单片机会从死循环里退出,去执行中断部分的代码,即开始运行void timer0(void) interrupt 1 using 3{}
//运行完中断部分的代码后,接着继续执行死循环里的代码。
//注意:当TH0 = 0xff;TL0 = 0xff;再运行,TF0并没有从0变为1,个人猜测TF0=1;时触发了中断,并重新被置零。
//如把ET0 = 1;和EA=1;注释掉,当TH0 = 0xff;TL0 = 0xff;再运行,TF0会变为1,此时不会再执行中断部分代码。
}
释疑:void Timer0() interrupt 1 using 1
Timer0
interrupt
跟在interrupt
0
1
2
3
4
实际上编译的时候就是把你这个函数的入口地址方到这个对应中断的跳转地址
using
初始值算法:定时器是当总数达到FFFFH后产生中断吧!那你要让它计数10000,是不是用FFFF(16进制)减去10000(十进制)的数当计数初值啊?TH0=-(10000/256); TL0=-(10000%6)跟FFFF(16进制)减去10000(十进制)的数是一样的。从TH0=-(10000/256); TL0=-(10000%6)开始计数,计数到10000刚好满。跟用FFFF(16进制)减去10000(十进制)的数一样!!!写起来更简单,不用算!!!
看看原码、补码就知道。正数的补码是对应的二进制数,符号位为零,负数的补码是它的绝对值对应的二进制数按位取反再加一,符号位为一。无符号数不考虑符号,那么这个结果就跟用FFFF减去它的绝对值一样
我们学习了用指令延时闪灯,但是用指令方式闪灯有cpu不能做其他工作的缺点。
这一课,我们将学习如何使用定时器方式使灯闪烁。
中断的理解。
这里将涉及到单片机中断的应用,在cpu的一步步按照指令运行的过程中(主程序),可能会有其它的更紧急的需要做的事情(中断服务程序),需要cpu暂时停止当前的程序(主程序),做完了(中断服务程序)之后,又可以继续去运行先前的程序(主程序)。就像你正在吃饭,一边又在给水桶里放水,吃着吃着,水满了,你就得赶快去把水龙头关掉或者换一个空的水桶,再回来吃饭。
单片机的定时器就像是一个水桶,你让它启动了,也就是水龙头打开了;开始装水了;定时在每个机器周期不断自动加1,最后溢出了;水桶的水不断增加,最也就满出来了;定时器溢出时,你就要去做处理了;水桶的水满了,你也应该处理一下了;处理完后,单片机又可以回到刚刚开停止的地方继续运行;水桶处理了,先前你在做什么也可以继续去做什么了。
单片机的主程序是从0x0000开始运行的,单片机服务程序从哪里开始运行呢?在51里,有多个中断服务程序入口,0号入口是外中断0,地址在0x0003;1号入口是定时器0,在 0x000B;2号入口是外中断1;地址在0x0013,3号入口是定时器2;地址在0x001B,等等。当中断发生时,程序就记下当前运行的位置,跳到对应的中断入口去运行中断服务程序,运行完之后,又跳回到原来的位置
单片机定时器中断原 相关文章:
- 单片机定时器中断原理和C语言代码详解(11-23)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)