历史上的今天
今天是:2025年07月12日(星期六)
2018年07月12日 | 51单片机的中断与定时计数器尝试
2018-07-12 来源:eefocus
这是我的第一篇有关51单片机的博客,主要记录我的学习历程与中间遇到的问题,如有错漏请指出。
在我理解里面中断与定时计数器是这样的:
中断是通过检查P3.2(INT0)与P3.3(INT1)两个引脚来触发的
计数器是通过检查P3.4(T0)与P3.5(T1)两个引脚的状态,要达到一定的次数(一般是记脉冲数)才触发
定时器不需要检测引脚,直接计数
先说中断的代码
#include
#include
#define SDT P0//静态数码管定义
unsigned char temp;
unsigned char code SDT_map[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//静态数码管字模
void delay10ms(unsigned int c)
{
unsigned int i,j;
for(;c>0;c--)
for(i=38;i>0;i--)
for(j=130;j>0;j--);
}
void interCongf()
{
//设置中断0
IT0=1;//IT=0表示低电平触发 IT=1表示负跳变沿触发
EX0=1;//EX为外部中断的允许位
PX0=0;//PX=0表示低优先级 PX=1表示高优先级
//设置中断1
IT1=1;
EX1=1;
PX1=1;//中断1的优先级比中断0高
EA=1;//总中断允许位
}
void main()
{
unsigned char ininum=0;
interCongf();
SDT=0x00;
while(1){}
}
void inter0() interrupt 0 //外部中断0
{
EX0=0;
for(temp=0;temp<10;temp++) //中断内部无法定义函数
{
SDT=SDT_map[temp];
delay10ms(10);
}
EX0=1; //在开始和结尾关开中断,防止中断运行过程中误触
}
//void timer0() interrupt 1 {} //定时器中断0
void inter1() interrupt 2 //外部中断1
{
EX1=0;
SDT=0xff;
delay10ms(30);
EX1=1;
}
//void timer1() interrupt 3 {} //定时器中断1
//void serialport() interrupt 4 {} //串行口中断
其中,SDT为共阳极静态数码管,P3.2(INT0)与P3.3(INT1)两个引脚分别接两个共阴的开关K1与K2
这个程序的功能就是无按键时,数码管全亮(0x00),
当按下K1时,数码管从一走到九
当按下K2时,数码管熄灭600ms,如果在INT0的执行过程中按K2,INT0会被中断(其实是挂起),立刻执行INT1,完成INT1后再返回INT0
然后说说计数器
#include
#include
#define SDT P0//静态数码管定义
sbit pulse=P1^0;
unsigned char temp=0;
unsigned char code SDT_map[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//静态数码管字模
void delay10ms(unsigned int c)
{
unsigned int i,j;
for(;c>0;c--)
for(i=38;i>0;i--)
for(j=130;j>0;j--);
}
void timeConfg()
{
TMOD=0x05; //选用计数模式和 选用模式1
TH0=0xD8;
TL0=0xF6; //计数10000次
EA=1;
ET0=1;
TR0=1;
}
void main()
{
SDT=0xff;
timeConfg();
while(1)
{
pulse=0;
_nop_();
_nop_();
_nop_();
_nop_();
pulse=1;
_nop_();
_nop_();
_nop_();
_nop_();
}
}
//void inter0() interrupt 0 {} //外部中断0
void timer0() interrupt 1 //定时器中断0
{
TH0=0xD8;//如果不更新TH0与TL0的值,第二次计数将从0~65535+1
TL0=0xF6;
SDT=SDT_map[(temp++)%10];
}
//void inter1() interrupt 2 {} //外部中断1
//void timer1() interrupt 3 {} //定时器中断1
//void serialport() interrupt 4 {} //串行口中断
定时器
#include
#include
#define SDT P0//静态数码管定义
unsigned char temp=0, status=0;
unsigned char code SDT_map[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//静态数码管字模
void timeConfg()
{
TMOD=0x01; //选用定时器模式和 选用模式1
TH0=0xd8;
TL0=0xf0; //定时 计数10000次
EA=1;
ET0=1;
TR0=1;
}
void main()
{
SDT=SDT_map[temp];
timeConfg();
while(1)
{
if(status==100)
{
temp++;
status=0;
SDT=SDT_map[temp%10];
}
}
}
//void inter0() interrupt 0 {} //外部中断0
void timer0() interrupt 1 //定时器中断0
{
TH0=0xd8;//如果不更新TH0与TL0的值,第二次计数将从0~65535+1
TL0=0xf0;
status++;
}
//void inter1() interrupt 2 {} //外部中断1
//void timer1() interrupt 3 {} //定时器中断1
//void serialport() interrupt 4 {} //串行口中断
其实定时器和计数器很相似,只用在TMOD里修改就行
总结:
其实中断,计数器,定时器很相似
共用的寄存器:定时计数器控制寄存器TCON, 中断优先寄存器IP 和 中断允许寄存器IE
定时计数器特有的寄存器:工作方式寄存器TMOD
附一些有关这些寄存器的资料:
下一篇:51单片机中断设置
史海拾趣
|
wince 5 沙漏(Hourglass)显示问题:点击屏幕,沙漏才有漏沙效果. 刚刚发现的问题,wince 5中用EVC 写应用程序自己调用显示沙漏, 第一种情况:如下,在初始化时显示沙漏持续5s钟,实际效果是,我双击打开应用程序,什么也看不到,如果我点击下屏幕,就会显示出沙漏,如不笔离开屏幕,沙漏也立刻消失.好像只有在点击屏幕是才 ...… 查看全部问答> |
|
MINI2440开发板下为了支持动态修改分辨率,在S3C2440DISP:S3C2440DISP()中生成了一个2个元素的数组GPEModeEx m_ModeInfoEx[2],保存了2个显示模式的分辨率,NumModes()改为返回2,此外其他修改的源代码如下: SCODE S3C2440DISP::GetM ...… 查看全部问答> |
|
高手们: 在ARM中,哪个能写一个这个程序: 有一个数:123456789ABCDFE 又有一个数987654321FEDCBA 这两个数如何比较大小? … 查看全部问答> |
|
char *sIp=\"192.168.11.105\"; int nPort = 3000; int rc; WSADATA wsaData; //SOCKET nConnect; &nb ...… 查看全部问答> |
|
搞了好几天,总算有点眉目了,第一次画还希望大侠们提些宝贵意见哈。感觉过流保护还不完整,参数有的不会算,大侠们发现了就尽管说哈,教教小弟,多谢啦 [ 本帖最后由 yuelianghudie 于 2010-8-8 15:23 编辑 ]… 查看全部问答> |
|
最近在学习C语言,用C++调试程序的时候发现在一个问题,每次我单步运行的时候总会出现如图的东西,这就把我的MAIN程序看不到了,怎么让这个不要显示 [ 本帖最后由 zjjone1023 于 2011-4-18 23:59 编辑 ]… 查看全部问答> |
|
本帖最后由 jameswangsynnex 于 2015-3-3 20:02 编辑 用6410做了个平台,放着过一段时间,就死机了,不知道什么原因,我HOST USB没有,但没接15K,下拉,不知道,有没有关系 … 查看全部问答> |




