找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4761|回复: 5
收起左侧

新人求助,我修改的电子钟,如何让一个小数点在运行时闪烁,显示函数那段也没太懂

[复制链接]
ID:365390 发表于 2018-7-7 11:35 | 显示全部楼层 |阅读模式
#include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16;   //对数据类型进行声明定义
typedef unsigned char u8;
sbit k1=P3^1;  //定义P31口是k1
sbit k2=P3^0;  //定义P30口是k2
sbit k3=P3^2;  //定义P32口是k3
sbit k4=P3^3;  //定义P33口是k4
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;   
u16 smgwei[8]={5,5,10,9,5,10,3,2};
u8 setwei=0; //调整时间各位的位置参数,默认为0,即不调整任何位。
u16 times[8];//循环次数累计,累计指令条数,粗略估算时间,控制被调整位闪烁频率。

u8 code smgduan[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,//数码管段选,显示0~9的值
0x80};//0x40数码管显示是短横
/*******************************************************************************
* 函 数 名         : delay
* 函数功能     : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}

/*******************************************************************************
* 函 数 名         : keypros
* 函数功能     : 按键处理函数,判断按键K1是否按下
*******************************************************************************/


void keypros()
{
if(k1==0)    //检测按键K1是否按下
{  
  delay(1000);   //消除抖动 一般大约10ms
  if(k1==0)  //再次判断按键是否按下
  {
        setwei++;
     if(setwei>8)
      setwei=0;
     TR0=0;
  }
  while(!k1);  //检测按键是否松开
   

}  
     if(k2==0)    //检测按键k2是否按下
{
  delay(1000);   //消除抖动 一般大约10ms
  if(k2==0)  //再次判断按键是否按下
  {
     switch(setwei)   //先判断调整时间中的哪一位,然后被选中位的数值自减
{ //减法可能越界,所以需要根据不同各位的进制来控制越界
case(1):smgwei[0]--;if(smgwei[0]==-1&&smgwei[1]==0) {smgwei[0]=9;smgwei[1]=5;}
else if(smgwei[0]==-1)  {smgwei[0]=9;smgwei[1]--; }break;
case(2):smgwei[1]--;if(smgwei[1]==-1) {smgwei[1]=5;smgwei[3]--;}break;
case(3):;break;
case(4):smgwei[3]--;if(smgwei[3]==-1&&smgwei[4]==0) {smgwei[3]=9;smgwei[4]=5;}
else if(smgwei[3]==-1)  {smgwei[3]=9;smgwei[4]--; }break;
case(5):smgwei[4]--;if(smgwei[4]==-1) {smgwei[4]=5;smgwei[6]--;}break;
case(6):;break;
case(7):smgwei[6]--;if(smgwei[7]==0&&smgwei[6]==-1)
{smgwei[6]=3;smgwei[7]=2;}
else if(smgwei[6]==-1)  
{smgwei[6]=9;smgwei[7]--; }
break;
case(8):smgwei[7]--;if(smgwei[7]==-1) smgwei[7]=2;break;
}   
     
  }
  while(!k2);  //检测按键是否松开
}
      if(k3==0)    //检测按键K1是否按下
{
  delay(1000);   //消除抖动 一般大约10ms
  if(k3==0)  //再次判断按键是否按下
  {
         switch(setwei) //和减法类似,也是先判断被选中的位。再修改其值。
{ //不过加法的越界问题在main秒数递增进位过程中处理了
case(1):smgwei[0]++;break;
case(2):smgwei[1]++;break;
case(3):;break;
case(4):smgwei[3]++;break;
case(5):smgwei[4]++;break;
case(6):;break;
case(7):smgwei[6]++;break;
case(8):smgwei[7]++;break;
}
     
  }
  while(!k3);  //检测按键是否松开
}
  if(k4==0)    //检测按键K1是否按下
{
  delay(1000);   //消除抖动 一般大约10ms
  if(k4==0)  //再次判断按键是否按下
  {
TR0=1;   
     setwei=9;
  }
  while(!k4);  //检测按键是否松开
}   
}
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
void show()   //修改后数码管显示函数
{
u8 j;
P2|=0x1c;   //8个数码管 ,使用for循环,轮流选通这8个数码管并传送不同的数据给P0
for (j=0;j<8;j++)
{ //同时根据条件,选择数码管常亮或者闪烁
P2+=4;
P0=(setwei==(j+1)&&times[j]>500)?0x00:smgduan[smgwei[j]];
times[j]++;
if (times[j]>1000) times[j]=0;   
delay(10);P0=0x00;
}
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能   : 主函数
* 输    入       : 无
* 输    出      : 无
*******************************************************************************/
void main()
{
   Timer0Init();  //定时器0初始化
while(1)
{
  keypros();  //按键处理函数
if(smgwei[0]==10) {smgwei[0]=0;smgwei[1]+=1;}
if(smgwei[1]==6) {smgwei[1]=0;smgwei[3]+=1;}
if(smgwei[3]==10) {smgwei[3]=0;smgwei[4]+=1;}
if(smgwei[4]==6) {smgwei[4]=0;smgwei[6]+=1;}
if(smgwei[6]==10) {smgwei[6]=0;smgwei[7]+=1;}
if((smgwei[7]*10+smgwei[6])>=24) {smgwei[6]=0;smgwei[7]=0;}
     show();
}  
}
      void Timer0() interrupt 1
{
static u16 i;
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
i++;
if(i==1000)
{
i=0;
smgwei[0]++;
}
}

回复

使用道具 举报

ID:7485 发表于 2018-7-7 15:52 | 显示全部楼层
用定时器中断,然后设置一个标志位,每0.5秒标志位取反一次。在显示函数里,根据标志位个位数加0x80(这是常见的数码管),也就是加上小数点。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:365390 发表于 2018-7-7 17:07 | 显示全部楼层
ahshmj 发表于 2018-7-7 15:52
用定时器中断,然后设置一个标志位,每0.5秒标志位取反一次。在显示函数里,根据标志位个位数加0x80(这是 ...

嗯嗯,懂了
回复

使用道具 举报

ID:142045 发表于 2018-7-7 13:31 | 显示全部楼层
初看你的程序段 没有驱动点的程序啊 如果让小点闪烁可以接在秒信号上 用硬件电路实现
回复

使用道具 举报

ID:365390 发表于 2018-7-7 14:45 | 显示全部楼层
上善-若水 发表于 2018-7-7 13:31
初看你的程序段 没有驱动点的程序啊 如果让小点闪烁可以接在秒信号上 用硬件电路实现

如果要加一段让点闪烁的程序,该怎么加
回复

使用道具 举报

ID:111634 发表于 2018-7-7 15:20 | 显示全部楼层
本帖最后由 zl2168 于 2018-7-7 16:12 编辑

小数点闪烁?给你几个参考案例,里面都有。
张志良编著的:《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行,可演示,可观测,程序语句条条有注解。
   实例10  模拟交通灯
带限行时间显示模拟交通灯.jpg 带限行时间显示模拟交通灯.jpg
实例29 模拟交通灯.rar (35.12 KB, 下载次数: 10)

评分

参与人数 1黑币 +5 收起 理由
上善-若水 + 5 赞一个!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表