设计需求:
秒表(定时中断)设计需求:使用定时器中断,实现每秒共阳极数码管自加1。
流程:
1.代码
1.1定义头文件
1.2定义主函数
1.3定义全局量与初始化
1.4定义中断
1.4.1IE寄存器(中断允许控制)(interrupt enable)
1.4.2IP寄存器
1.4.3定时控制寄存器TCON ( Timer control register )
1.4.42.定时/计数器工作方式控制寄存器TMOD
1.4.5真-定义中断
1.4.6定义中断子程序
1.5显示与重置
1.6完整代码
2.仿真
3.效果
首先我们定义单片机头文件
//单片机头文件
#include
因为是单片机,所以不需要返回值,所以用void main来定义主函数。
//主函数
void main()
{
}
定义我们需要的两个变量与一个存放0~15共阳极数码管字符码的字符组。
//定义一个记次数-5毫秒一次
int time_sum = 0;
//定义一个显示数0~15
int number = 0;
//定义0~15共阳极数码管字符码
const unsigned char led[] = { 0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E };
首先我们先了解亿点点中断知识。
EXO(IE.0) | 外部中断0允许位;(interrupt controller of external interrupt) |
ETO(IE.1) | 定时/计数器TO中断允许位 (interrupt controller of Timer0 interrupt) |
EX1(IE.2) | 外部中断0允许位 |
ET1(IE.3) | 定时/计数器T1中断允许位 |
ES (IE.4) | 串行口中断允许位; (interrupt controller of serial port) |
EA(IE.7) | CPU 中断允许(总允许)位(global all interrupt ) |
PXO (IP.0) | 外部中断0优先级设定位 |
PTO (IP.1) | 定时/计数器TO优先级设定位 |
PX1 (IP.2) | 外部中断0优先级设定位 |
PT1 (IP.3) | 定时/计数器T1优先级设定位 |
PS (IP.4) | 串行口优先级设定位 |
PT2 (IP.5) | 定时/计数器T2优先级设定位(80C52 的T2) |
ITO (TCON.0) | 外部中断0触发方式控制(interruput-0 type control bit ) |
ITO=0 | 为电平触发方式 |
IT0=1 | 为边沿触发方式(下降沿有效) |
IEO (TCON.1) | 外部中断0中断请求标志位(external interrupt-0 flag) |
IT1 (TCON.2) | 外部中断1触发方式控制位 |
IE1 (TCON.3) | 外部中断1中断请求标志位 |
TRO (TCON.4) | 定时/计数器TO运行控制位( timer0 run control bit) |
TR1 (TCON.6) | 定时/计数器T1运行控制位 |
TFO(TCON.5) | 定时/计数器TO溢出中断请求标志位 |
TF1 (TCON.7) | 定时/计数器T1溢出中断请求标志位( timer1 overflow flag ) |
TMOD用于设定定时/计数器的工作方式:
低4位用于控制TO,高4位用于控制T1。
OK,我们这中断知识了解这亿点点就可够了。
{
//定义内部中断
//只打开TR0的模式01
TMOD = 0x01;
//定义定时时间
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
//中断全开
IE = 0xFF;
//打开TR0
TR0 = 1;
}
当然我们给配合子程序来用。
interrupt 0 |
指明是外部中断0 |
interrupt 1 | 指明是定时器中断0 |
interrupt 2 | 指明是外部中断1 |
interrupt 3 | 指明是定时器中断1 |
interrupt 4 | 指明是串行口中断 |
//TR0设置
void MSAdd() interrupt 1
{
//定义定时时间
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
//每进一次-记次数自加1
time_sum++;
//记次数自加到20次(过了一秒)
if (time_sum == 20)
{
//记次数重置为0
time_sum = 0;
//显示数自加一
number++;
}
}
//死循环
while (1)
{
//在数码管上显示0~15
P2 = led[number];
//防止数值溢出
if (number == 16)
//当显示数为16重置为0
number = 0;
}
//定义单片机头文件
#include
//定义一个记次数-5毫秒一次
int time_sum = 0;
//定义一个显示数0~15
int number = 0;
//定义0~15共阴极数码管字符码
const unsigned char led[] = { 0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E };
//定义主函数
void main()
{
//定义内部中断
//只打开TR0的模式01
TMOD = 0x01;
//定义定时时间
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
//中断全开
IE = 0xFF;
//打开TR0
TR0 = 1;
//死循环
while (1)
{
//在数码管上显示0~15
P2 = led[number];
//防止数值溢出
if (number == 16)
//当显示数为15重置为0
number = 0;
}
}
//TR0设置
void MSAdd() interrupt 1
{
//定义定时时间
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
//每进一次-记次数自加1
time_sum++;
//记次数自加到20次(过了一秒)
if (time_sum == 20)
{
//记次数重置为0
time_sum = 0;
//显示数自加一
number++;
}
}
因为这次程序非常简单,所以只需要3个元件:
Component Mode中的7SEG-COM-AN-BL(共阳极数码管)与AT89C51(单片机)。
Terminals Mode中的POWER(正极)。
制作不易,请三连。
简易秒表