这个程序写了好几次,但每次重写的时候,感觉又无从下手。
在写这个程序时,先把每个寄存器及其功能又全部熟记和理解,这个程序是凭自己的理解写出来的,每个步骤该干嘛,该解决哪些问题。
#include "reg51.h"
typedef unsigned int u16;
// 数字 0 ~ 9
unsigned char digit[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
/**
实现每隔3秒,数码管数字0~9
**/
/**
要设置中断,需要先解决一下问题:
(1) 要设置什么中断?
中断C51有5个: T1 T0 TI/RI INT0 INT1
定时器/计数器中断设置:
(1) 要使用哪个中断?T0 ? T1
由TMOD寄存器和TCON寄存器共同决定:
GATE=0 && (TR0=1 || TR1=1)
GATE=0 && (TR0=1 || TR1=1) && 外部中断(INT0/INT1)
(2) 使用哪个工作方式
由TMOD寄存器的M1和M1决定 (共4中方式可选择)
(3) 定时或记数多少? 即确定初始值
由时钟频率 和 要计数的值决定. 12个时钟周期为一个机器周期
(4) 打开中断:
a) 打开某个定时器中断
b) 打开总中断
(5) 启动定时器工作
(6) 设置中断函数
**/
void init()
{
// GATE: 0 ==> 哪个定时器有TCON的TRX决定
// C/T : 0 ==> 为定时器模式
// M0M1: 01 ==> 工作方式1 为16位定时器/计数器
TMOD = 0x01;
TH0 = 0x3C; // 初始值 定时50ms中断一次
TL0 = 0xB0;
ET0 = 1; // 打开t0中断
EA = 1; // 打开总中断
TR0 = 1; // 启动定时器1开始工作 (这个应该放到中断全部设置完毕后,作为一个开关再设置)
}
u16 index = 0;
// 显示数字
void Show()
{
P0 = digit[index];
}
void main()
{
init();
while(1){
Show();
}
}
// 中断处理函数
void timer0() interrupt 1
{
static u16 num = 0; // 一次中断50ms, 60次中断为3s
num++;
if(60 == num) {
num = 0;
index++;
if(index == 10)
index = 0;
}
}
本文为原创内容,作者:闲鹤,原文链接:https://blog.uwenya.cc/110.html,转载请注明出处。