标题:
单片机中断与数码管动态扫描(含按键控制方法)仿真和源码
[打印本页]
作者:
kinggm
时间:
2018-5-17 23:07
标题:
单片机中断与数码管动态扫描(含按键控制方法)仿真和源码
利用中断与定时器来实现99秒的秒表
按键可以暂停
当然也可以清零 可以参照我上一个帖子自己再给按键加一些功能
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
(13.62 KB, 下载次数: 44)
下载附件
2018-5-18 03:37 上传
0.jpg
(28.65 KB, 下载次数: 32)
下载附件
2018-5-18 03:37 上传
单片机源程序如下:
#include <reg52.h>
sbit p1=P1^0;
sbit p2=P1^1;
sbit k1=P1^7;
unsigned char code LedChar[] = { //数码管显示字符转换表
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6]= { //数码管显示缓冲区,初值 0xFF 确保启动时都不亮
0xc0,0xc0
};
char scan[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
unsigned char i = 0; //动态扫描的索引
unsigned int cnt = 0;
bit flag=0;//记录 T0 中断次数
unsigned long sec = 0; //记录经过的秒数
void debouncer();
void main(){
EA = 1; //使能总中断
TMOD = 0x01; //设置 T0 为模式 1
TH0 = 0xFC; //为 T0 赋初值 0xFC67,定时 1ms
TL0 = 0x18;
ET0 = 1; //使能 T0 中断
TR0 = 0;
ET1=1;
TR1=0;
TH1=0xfc;
TL1=0x18;
k1=1; //启动 T0
while (1){
if(k1==0&&flag==0){ //按键按下不放 开始计时 松开立即停止计时,示数定在当前计数数值
debouncer();
TR0=1; //打开定时器中断0
TR1=1; //打开定时器中断1
flag=1;
while(k1==0); /*这两句防止在 按键按下的短时间内程序跑飞到下一个if语句*/
debouncer();
}
if(k1==0&&flag==1){ //此时 k1==0,可以实现第二次功能 若k1==1即为按键松开产生动作
debouncer();
TR1=0; //关闭定时器中断1 使得程序停止在当前时刻
flag=0;
while(k1==0);
debouncer();
}
}
}
/* 定时器 0 中断服务函数 控制位 并显示对应数值 */
void InterruptTimer0() interrupt 1{
TH0 = 0xFC; //重新加载初值
TL0 = 0x18;
cnt++; //中断次数计数值加 1
//以下代码完成数码管动态扫描刷新
P2 = 0xFF;
//显示消隐
switch (i){
case 0: p2=1;p1=0; i++; P2=LedBuff[0]; break; //打开个位,关闭其他位,并给P2端口赋个位相应数值断码
case 1: p1=1;p2=0; i=0; P2=LedBuff[1]; break; //打开十位,关闭其他位,并给P2端口赋十位相应数值断码
default: break;
}
}
void InterruptTimer1() interrupt 3{ /* 定时器 1 中断服务函数 控制段并 将要显示的数值断码 赋值到数组中等待调用 */
TH1=0xc0;
TL1=0x18;
if (cnt >=800){ //判断 T0 溢出是否达到 1000 次 此处理论上写1000,但是实际写800是因为为了消除计时误差 800这个数
cnt = 0; //达到 1000 次后计数值清零
sec++; //秒计数自加 1
if(sec>99)sec=0;
//以下代码将 sec 按十进制位从低到高依次提取并转为数码管显示字符
LedBuff[0] = LedChar[sec%10];
LedBuff[1] = LedChar[sec/10];
}
}
void debouncer(){ //延时20ms按键消抖
int i;
for(i=0;i<2400;i++);
}
复制代码
所有资料51hei提供下载:
中断与数码管动态扫描.rar
(15.26 KB, 下载次数: 24)
2018-5-17 23:07 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
xiaoyu.
时间:
2018-5-18 15:12
这个是独立按键控制的
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
sbit K1=P3^4;
sbit K2=P3^5;
sbit K3=P3^6;
sbit K4=P3^7;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uint aa;
uchar num1,num2,shi1,ge1,shi2,ge2;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void display(uchar num1,uchar num2)
{
shi1=num1/10;
ge1=num1%10;
shi2=num2/10;
ge2=num2%10;
dula=1;
P0=table[shi1];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(1);
dula=1;
P0=table[ge1];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(1);
dula=1;
P0=table[shi2];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay(1);
dula=1;
P0=table[ge2];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
delay(1);
}
void key()
{
if(K1==0)
{
delay(5);
if(K1==0)
{
TR0=0;
while(!K1);
}
}
if(K2==0)
{
delay(5);
if(K2==0)
{
if(num1==0)
{
num1=60;
}
num1--;
while(!K2);
}
}
if(K3==0)
{
delay(5);
if(K3==0)
{
num1++;
if(num1>=60)
{
num1=num1-60;
}
while(!K3);
}
}
if(K4==0)
{
delay(5);
if(K4==0)
{
TR0=1;
while(!K4);
}
}
}
void inint()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void main()
{
inint();
while(1)
{
key();
display(num1,num2);
}
}
void zhongduan()interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
if(aa==20)
{
aa=0;
num2++;
if(num2==60)
{
num2=0;
num1++;
if(num1==60)
num1=0;
}
}
}
作者:
0609
时间:
2019-3-17 19:58
谢谢,收益
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1