51单片机学习19-简易秒表
前面几篇我们说到了 LED灯,数码管,按键等内容,按键和数码管组合可以设计出简易秒表。
硬件组成:单片机最小系统+数码管显示电路+3个按键
功能:一个开始键,一个暂停键,一个复位键。数码管显示的精度是00:00--59:99
仿真图:
程序:
程序内容比较多,详细的参考源代码
源代码:
#include<reg52.h> //头文件
#define uint unsigned int
#define uchar unsigned char
uchar qian;
uchar bai;
uchar shi;
uchar ge;
//共阴数码管0-F 编码表
uchar smg_dm[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,};
uchar smg_dm1[]={0xbf,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,}; //0. 1. 2.----9.段码表
uchar smg_wm[]={0Xef,0Xdf,0xbf,0x7f}; //位选
uchar Display_buffer[4]={0,0,0,0}; //数码管显示缓存
sbit key1=P2^0; //开始键
sbit key2=P2^1; //暂停键
sbit key3=P2^2; //复位键
void delay_ms(uint z) //延时子程序
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void key(void)
{
if(key1==0)
{
delay_ms(10);
if(key1==0)
{
TR0=1;
}
while(!key1);
}
if(key2==0)
{
delay_ms(10);
if(key2==0)
{
TR0=0;
}
while(!key1);
}
if(key3==0)
{
delay_ms(10);
if(key3==0)
{
TR0=0;qian=0;bai=0;shi=0;ge=0;
}
while(!key1);
}
}
void msg_display(void)
{
uchar i;
Display_buffer[0]=qian;
Display_buffer[1]=bai;
Display_buffer[2]=shi;
Display_buffer[3]=ge;
for(i=0;i<=3;i++)
{
if(i==1)
{
P2=smg_wm[i];//选位码
P1=smg_dm1[Display_buffer[i]];//选段码
delay_ms(5);
//P2=0XFF; //消影仿真这句加不加都一样
}
else
{
P2=smg_wm[i];//选位码
P1=smg_dm[Display_buffer[i]];//选段码
delay_ms(5);
//P2=0XFF; //消影
}
}
}
void main()
{
TMOD=0X01;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
EA=1;
ET0=1;
while(1)
{
key();
msg_display();
}
}
void time0() interrupt 1
{
uchar num;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
num++;
if(num==1)
{
num=0;
ge++;
if(ge==10)
{
ge=0;
shi++;
if(shi==10)
{
shi=0;
bai++;
if(bai==10)
{
bai=0;
qian++;
if(qian==6)
{
qian=0;
}
}
}
}
}
}
仿真结果:
单片机秒表实例
下面是用单片机来实现秒表功能的一个例子, 该源程序已在实验板上调试通过,可直接引用,并可利用软件编程的灵活性,加以拓展,实现更为复杂的功能。
#include <pic.h>
#include <math.h>
//此程序实现计时秒表功能,时钟显示范围 00.00~95.99 秒,分辨度:0.01 秒
unsigned char s0,s1,s2,s3;
//定义 0.01 秒、0.1 秒、1 秒、10 秒计时器
unsigned char s[4];
unsigned char k ,data ,sreg;
unsigned int i;
const table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90};
//不带小数点的显示段码表
const table0[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
//带小数点的显示段码表//TMR0 初始化子程序
void tmint()
{
T0CS=0;//TMR0 工作于定时器方式
PSA=1;//TMR0 不用分频
T0IF=0;//清除 TMR0 的中断标志
T0IE=1;//TMR0 中断允许
}
//spi 显示初始化子程序
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
//设置 SPI 的控制方式,允许 SSP 方式,并且时钟下降沿发送。与"74HC595,当其//SCLK 从低到高跳变时,串行输入寄存器"的特点相对应
TRISC=0xD7;//SDO 引脚为输出,SCK 引脚为输出
TRISA5=0;//RA5 引脚置为输出,输出显示锁存信号
}
//系统其它部分初始化子程序
void initial()
{
TRISB1=0;
TRISB2=0;
TRISB4=1;
TRISB5=1;//设置与键盘有关的各口的输入输出方式
RB1=0;
RB2=0;//建立键盘扫描的初始条件
}
//SPI 传输数据子程序
void SPILED(data)
{
SSPBUF=data;//启动发送
do {
;
}while(SSPIF==0);
SSPIF=0;
}
//显示子程序,显示 4 位数
void dispaly()
{
RA5=0;//准备锁存
for(k=4;k>0;k--)
{
data=s[k-1];
if(k==3) data=table0[data];//第二位需要显示小数点
else data=table[data];
SPILED(data);//发送显示段码
}
for(k=0;k<4;k++)
{
data=0xFF;
SPILED(data);//连续发送 4 个 DARK,使显示好看一些
}
RA5=1;//最后给锁存信号,代表显示任务完成
}
//软件延时子程序
void DELAY()
{
for(i = 3553;--i ;) continue;
}
//键扫描子程序
void KEYSCAN()
{
while(1){
while(1)
{
dispaly();//调用一次显示子程序
if ((RB5==0)||(RB4==0)) break;
}
DELAY();//若有键按下,则软件延时
if ((RB5==0)||(RB4==0)) break;
//若还有键按下,则终止循环扫描,返回
}
}
//等键松开子程序
void keyrelax()
{
while(1){
dispaly();//调用一次显示子程序
if ((RB5==1)&&(RB4==1)) break;
} //为防止按键过于灵敏,每次等键松开才返回
}
//系统赋值初始化子程序
void inizhi()
{
s0=0x00;
s[0]=s0;
s1=0x00;
s[1]=s1;
s2=0x00;
s[2]=s2;
s3=0x00;
s[3]=s3;//s0=s1=s2=s3=0,并放入显示缓冲数组中
sreg=0x00;//tmr0 中断次数寄存器清 0
}
//中断服务程序
void interrupt clkint(void)
{
TMR0=0X13;
//对 TMR0 写入一个调整值。因为写入 TMR0 后接着的
//两个周期不能增量,中断需要 3 个周期的响应时间,
//以及 C 语言自动进行现场保护要消耗周期
T0IF=0;//清除中断标志
CLRWDT();
sreg=sreg+1;//中断计数器加 1
if(sreg==40) //中断次数为 40 后,才对 S0,S1,S2,S3 操作
{
sreg=0;
s0=s0+1;
if(s0==10){
s0=0 ;
s1=s1+1;
if(s1==10){
s1=0 ;
s2=s2+1;
if(s2==10){
s2=0;
s3=s3+1;
if(s3==10) s3=0 ;
}
}
}
}
s[0]=s0;
s[1]=s1;
s[2]=s2;
s[3]=s3;
}
//主程序
main()
{
OPTION=0XFF;
tmint();//TMR0 初始化
SPIINIT();//spi 显示初始化
initial();//系统其它部分初始化
di();//总中断禁止
while(1) {
inizhi();//系统赋值初始化
KEYSCAN();//键扫描,直到开始键按下
keyrelax();//等键松开
ei();//总中断允许
KEYSCAN();//键扫描直到停止键按下,在键扫描时有显示
keyrelax() ;//等键松开
di();//总中断禁止
KEYSCAN();//键扫描到清 0 键按下,在键扫描时有显示
keyrelax() ;//等键松开
}
}
相关问答
51 单片机秒表 程序主体是显示---中断---显示循环着你只要在定义一个10分位的秒寄存器就可以了,秒寄存器到10后,让10分位的秒寄存器加1就可以做到00--99。显示在加...
51 单片机 秒表 设计 怎么用按钮控制开始 停止和清零?-ZOL问答chartable[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳极//chartable[10]={0x3f,0x06...
关于MCS-51 单片机 、你们懂得!以下是是MCS-51 单片机 的数字时...[最佳回答]#include"reg51.h"unsignedcharcodedisptab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0...
单片机秒表 显示实验中,提高计时精度的方法有哪些?单片机秒表显示实验中,提高计时精度的方法只有一个(因晶振频率误差也影响计时精度,但是不能调,所以,这不能算一个方法),就是调整定时器的计数的初始值。都...
在座的大佬,请问一下!! 单片机 ( 秒表 制作)?,制作 单片机 服务...[回答]我之前有在他们家设计的单片机,也去现场看过,用下还还算可以。可以去咨询看看服务热情,公司环境设备先进,价格合理品控做的不错,据说他们生意做的也...
单片机秒表 怎么存储读取数据?在单片机中实现秒表功能并存储读取数据的方法有多种,以下是其中一种常用的方法:1.设定一个计数变量:在单片机的程序中,首先需要定义一个计数变量,用于记录...
在座的老铁,我想知道, 单片机 ( 秒表 制作)?,制作 单片机 费用...[回答]我有一个秒表程序,是用郭天祥的TX-1C板子写的,你要么开发过产品,给你个网址http://www.mcu-development.com,环境设备先进,价格合理品控做的不错,...
0秒的定时器作用?用于精确定时,如秒表,时钟。还有就是在单片机正常工作时,如果调用延时函数来延时的话,那么单片机在此期间就无法处理其他任务了,如探测其他的一些数据变化量...
漏电开关测试仪使用方法是什么- 一起装修网[回答]漏电流的降压器其初级输入电压由电位器调节端控制,也就是说通过电位器调节,输入变压器初级的电压从零逐步增加,变压器次级输出模拟漏电流,也...漏...
漏电开关测试仪使用方法是什么_土巴兔装修问答漏电保护器开关测试仪主要用于测试漏电保护器的漏电动作电流、漏电不动作电流以及漏电动作时间。该测试仪为手持式,体积小,重量轻,便于携带,是各种...