数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 3183|回复: 17

[C51] 小白自学C51单片机编程,4位数码管时钟分钟,增加按键,改进问题

[复制链接]
发表于 2023-12-22 15:43:58 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
学习了各位网友的建议,对上一个程序做了改进,解决了按键加一实际加多个一的问题,
修改后的代如下:


#include <reg52.h>        //头文件
typedef unsigned char uchar;  //类型定义
typedef unsigned int uint;

sbit led_a=P1^0;    //数码管个位
sbit led_b=P1^1;    //十位
sbit led_c=P1^2;    //百位
sbit led_d=P1^3;    //千位        
sbit led5=P1^4;         //以下4个LED
sbit led6=P1^5;
sbit led7=P1^6;
sbit led8=P1^7;
sbit key4=P3^7;        //声明一个按键,用于调时

uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f};

uint time=0;  // 秒钟
uint fen=0;   // 分钟
uint shi=0;   // 时钟
uint xms;    //延时ms
uchar dingshi=0; //定时次数
bit time0_flag=0;  //定时到1秒的标志位

/*采用了多个子函数,使程序看起来容易一点
void display(time);   //声明显示子函数
void delay(xms);    //声明延时子函数
void time0init();   //声明定时器子函数
void key_scan();   //声明按键子函数
void jishi();     //声明计时子函数,计时到1秒就执行

void main ()      //主函数
{
    time0init();       //调用定时器初始化函数
    while(1)
    {
        if(time0_flag==1)    //如果计时到了就执行以下程序,没有就接着显示
        {
            time0_flag=0;  //
            jishi();     //计时子函数
        }
        key_scan();         //检测是否有按键
        display(time);     //调用显示函数
    }
}

void display(time)      //显示函数
{
     P0=table[fen%10];      //送出段选信号
     led_a=0;                 //打开个位位选
     delay(5);
     led_a=1;

     P0=table[fen/10%10];      //送出段选信号
     led_b=0;                   //打开十位位选
     delay(5);
     led_b=1;

     P0=table[shi%10];      
     led_c=0;
     delay(5);
     led_c=1;

     P0=table[shi/10%10];     
     led_d=0;
     delay(5);
     led_d=1;

     P0=table[10];        //显示中间的点
     led_c=0;
     delay(5);
     led_c=1;
     
}


void delay(xms)        //延时函数
{
     uchar i;
    while(xms--)
    {
         for(i=0;i<113;i++);
    }
}

void key_scan()        //按键函数
{
     if(key4==0)
    {
         delay(5);
        if(key4==0)
        {
             shi+=1;      //按一下key4时钟加1
            if(shi>=24)
            {
             shi=shi-24;
            }
            while(key4==0);  //按键松开才往下执行
        }
    }
}


void time0init()     //定时器初始化函数
{
    EA=1;        //开总中断
    ET0=1;        //开定时器0        
    TR0=1;        //定时器0开始
    TMOD=0X01;    // 定时器模式1
    TH0=(65536-50000)/256;      //50ms初值高8位
    TL0=(65536-50000)%256;      //50ms初值低8位
    EX1=1;        //开外部中断1
    IT1=0;        //低电平有效
}

void jishu ()interrupt 1    //定时器中断函数
{   
    TH0=(65536-45872)/256;
    TL0=(65536-45872)%256;
   
     if(dingshi==20)      //如果定时满了20次
    {
         dingshi=0;     //次数清零,循环
        time0_flag=1;    //1秒标志位
    }   
        dingshi++;         //如果定时没满20次,就加一次
}     

void jishi()   //计时子函数,定时次数到了就执行
{
         time++;        //秒加一次
        if(time==60)
        {
             time=0;
            fen++;      //到了60秒,分加一次
            if(fen==60)
            {
                 fen=0;
                shi++;     ////到了60分,时加一次
                if(shi==24)
                {
                    shi=0;
                }
            }
        }      
        led5=~led5;      //亮一秒灭一秒
        led6=~led6;
        led7=~led7;
        led8=~led8;   
}

void key_int()interrupt 2  //外部中断1
{
    delay(300);     //如果不延时,按一下按钮可能加了好几个5
    fen+=5;    //加5分,可以理解为fen=fen+5
    if(fen>=60)      
    {
    fen=fen-60;
    }
}


 楼主| 发表于 2023-12-22 15:46:30 | 显示全部楼层
自学还是有点难度,网上的例程很多看不明白,店家给的资料又太简单,
回复 支持 反对

使用道具 举报

发表于 2023-12-22 16:21:37 | 显示全部楼层
本帖最后由 kpj001 于 2023-12-22 16:26 编辑

几十年前,没有选择的年代,点亮数码管是必由之路。
现在折腾数码管的也只有老年人和老年音乐播放器等极度节约成本的产品。
WiFi 时钟+本地温度-CSDN博客 这个虽然谈不上有多少技术,但是不到100行代码,零件大概20元,立即掌握 网络 传感器 显示 时钟 等多个“关键技术”,为后续其他搭建铺路。
回复 支持 反对

使用道具 举报

发表于 2023-12-22 16:53:25 | 显示全部楼层
下一步学习加入ds1302 、 ds1307、 ds2312等时钟芯片,就能做出一个时间精准的万年历了
回复 支持 反对

使用道具 举报

发表于 2023-12-22 17:14:29 来自手机浏览器 | 显示全部楼层
新手?年龄多大了?如果是高中生以后得年纪,就放弃51吧。直接用ARM。能搞懂寄存器,基本上啥单片机都会了。FPGA是另一种东西。需要重新学。
回复 支持 反对

使用道具 举报

发表于 2023-12-24 09:15:48 | 显示全部楼层
本帖最后由 devcang 于 2023-12-24 09:21 编辑
hellozwt 发表于 2023-12-22 15:46
自学还是有点难度,网上的例程很多看不明白,店家给的资料又太简单,

还是没有搞懂小数点的显示。  


        P0=table[shi%10] & table[10];        //此位带小数点
        led_c=0;
        delay(5);
        led_c=1;

        P0=table[shi/10%10];     
        led_d=0;
        delay(5);
        led_d=1;

        // P0=table[10];                        //显示中间的点
        // led_c=0;
        // delay(5);
        // led_c=1;



另外,2个按键,很多51单片机应该有3个外部中断,所以用中断、而不用扫描。

回复 支持 反对

使用道具 举报

发表于 2023-12-24 12:02:10 | 显示全部楼层
kpj001 发表于 2023-12-22 16:21
几十年前,没有选择的年代,点亮数码管是必由之路。
现在折腾数码管的也只有老年人和老年音乐播放器等极度 ...

层主说的“折腾数码管的也只有老年人**”这句很赞,我曾经做过各种版本的时钟、闹钟、日历,如今案头上在用的真的就是一个数码管时钟,原因很简单,就这货能看清楚字符,5”TFT屏使用96*96字符离远了看着都马虎。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-24 14:21:04 | 显示全部楼层
本帖最后由 hellozwt 于 2023-12-24 15:18 编辑
devcang 发表于 2023-12-24 09:15
还是没有搞懂小数点的显示。  

谢谢指导,回头我试试
我想要中间的点1秒闪一次,还不知道怎样实现
回复 支持 反对

使用道具 举报

发表于 2023-12-26 10:58:13 来自手机浏览器 | 显示全部楼层
hellozwt 发表于 2023-12-24 14:21
谢谢指导,回头我试试
我想要中间的点1秒闪一次,还不知道怎样实现

定时器500ms取反就可以
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-26 20:22:44 | 显示全部楼层
1065307738 发表于 2023-12-22 17:14
新手?年龄多大了?如果是高中生以后得年纪,就放弃51吧。直接用ARM。能搞懂寄存器,基本上啥单片机都会了 ...

已过不惑之年,学这个纯粹就是想尝试一下,并没有什么实质的项目要做
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-26 20:25:20 | 显示全部楼层
xfdr0805 发表于 2023-12-26 10:58
定时器500ms取反就可以

中间的点跟第百位数码管是一起的,点闪的时候数字会不会有影响
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-2-27 20:40:55 | 显示全部楼层
89C52单片机的晶振是11.0592MHz,
1S可产生的机器周期数  11.0592MHz / 12 = 921600 个,
定时50 ms,需要921600 * 0.05 = 46080个机器周期。
定时器模式1 是16位,最大值为 2^16=65536,
所以初值设置为  65536-46080 = 19456。
19456二进制为01001100 00000000
16进制为4c 00
  十六进制写法为:
        TH0 = 0X4c;   高8位
        TL0 = 0x00;   低8位
  十进制写法为:
        TH0 = (65536-46080)/256;
        TL0 = (65536-46080)%256;
        (16位二进制数对256求模得到的是高八位,同理求余得到的是低八位)
回复 支持 反对

使用道具 举报

发表于 2024-4-19 11:35:49 | 显示全部楼层
想法比代码重要。不会编程不重要,关键还是要有解决问题的方向,有了方向,GPT帮你写代码
回复 支持 反对

使用道具 举报

发表于 2024-4-20 09:44:02 | 显示全部楼层
可以用 STC-ISP V6.94D 帮你减轻 开发的压力







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

发表于 2024-4-20 09:46:46 | 显示全部楼层
还有大量的51演示程序供直接套用


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

发表于 2024-4-30 19:03:57 来自手机浏览器 | 显示全部楼层
南天音乐 发表于 2024-4-19 11:35
想法比代码重要。不会编程不重要,关键还是要有解决问题的方向,有了方向,GPT帮你写代码 ...

GPT写的东西还有很多问题,得会改才行
回复 支持 1 反对 0

使用道具 举报

发表于 2024-4-30 19:08:29 来自手机浏览器 | 显示全部楼层
俺喜欢点屏幕,尤其是喜欢通过各种屏幕看小姐姐跳舞
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2024-6-29 05:58:39 | 显示全部楼层
想法比代码重要。不会编程不重要,关键还是要有解决问题的方向,有了方向,GPT帮你写代码
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-23 16:10 , Processed in 0.390000 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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