要求:使用51单片机,通过定时器实现数码管秒表计时功能,按下按键从零开始计时,再次按下按键暂停计时,第三次按下重新开始计时
首先需要一个标志
flag = 0;// 需要清零重新计数
flag = ~0;//暂停计数
共阴极数码管0~9的显示
unsigned char num[]={0x3F,0x06,0x5B,
0x4F,0x66,0x6D,0x7D,
0x07,0x7F,0x6F};
引脚的设置
sbit ds_pin = P0^3;
sbit stcp_pin = P0^4;
sbit shcp_pin = P0^5;
//按键中断部分
sfr P4 = 0xe8; //for 89C5xRC/RD+ series and 90C5xRc/RD+, location at 0E8H
sbit INT2 = P4^3;
sbit INT3 = P4^2;
sfr XICON = 0xc0; //for 89C5xRC/RD+ series and 90C5xRc/RD+, location at 0C0H
sbit PX3 = XICON^7;
sbit EX3 = XICON^6;
sbit IE3 = XICON^5;
sbit IT3 = XICON^4;
sbit PX2 = XICON^3;
sbit EX2 = XICON^2;
sbit IE2 = XICON^1;
sbit IT2 = XICON^0;
sbit key1 = P4^3;
还需要一个定时器0中断服务函数,定时器0溢出时,CPU会自动跳转到这个函数执行,每次定时器溢出代表时间过去10ms,cnt的值会+1
#define TIMS (65536 - 9216)
unsigned int cnt = 0;
void timer0() interrupt
{
if(cnt < 9900)
cnt++
TL0 = TIMS;
TH0 = TIMS >> 8;
}
按下按键后会发生的情况
static unsigned int flag = 0;
void exit2() interrupt 6
{
//按下按键
if(key1 == 0){
//进行清零处理
if(flag == 0){
cnt = 0;//清零
TR0 = 1;//定时器0开始计数
TL0 = TIMS;
TH0 = TIMS >> 8;
}
else
//进行暂停处理
TR0 = 0;//定时器0关闭计数
flag = ~flag;
delay_ms(10);
}
}
设置一个延时函数
void delay_ms(unsigned int xms) //@12MHz
{
unsigned int i, j;
for(i=xms;i>0;i--)
{
for(j=124;j>0;j--)
{}
}
}
通过 74HC595 移位寄存器 实现 串行数据输入,将 1 字节(8 位)的数据 逐位发送到 74HC595 芯片中
void hc595_send_byte(unsigned char byte)
{
unsigned int i;
for(i = 0;i < 8;i++){
if(byte & 0x80)//取最高位
ds_pin = 1;
else
ds_pin = 0;
//shcp每发生一次上升沿,hc595才会从当前引脚上取得数据
shcp = 0;
shcp = 1;
byte <<= 1;
}
}
实现要展示哪些内容以及在哪个数码管上显示
//num为展示内容,addr为在哪个数码管展示
void hc595_send_data(unsigned char num,unsigned char addr)
{
hc595_send_byte(num);//先发需要展示的数字
if(addr == 0)
hc595_send_byte(0xFE);//Q0数码管控制
else if(addr = 1)
hc595_send_byte(0xFD);//Q1数码管控制
//当移位寄存器的8位数据全部传输完毕后,制造一次锁存器时钟引脚的上升沿
stcp_pin = 0;
stcp_pin = 1;
]
主函数
#include <reg52.h>
void main()
{
IT2 = 1;
EX2 = 1;
EA = 1;
TMOD = 0x01;
TR0 = 1;
ET0 = 1;
TL0 = TIMS;
TH0 = TIMS >> 8;
while(1){
hc595_send_data(num[cnt/1000],0);
hc595_send_data(num[(cnt/100)%10],1);
}
}
新人学习单片机,记录成长过程,烧录软件烧录不进去程序,暂时还不知道结果是否有效,若有不足的地方还希望各位大佬可以指出来。
---------------------------------------------------------------------------------------------------------------------------------
烧录成功后发现第一次按下按键便归零了,所以flag的初值应该是
static unsigned int flag = ~0;