找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

TM1650 4KEY4LED计数器(总减+移位+减1+加1)

查看数: 800 | 评论数: 7 | 收藏 5
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2025-3-24 13:20

正文摘要:

用模块资料+豆包AI+自己修改生成的C代码,调试OK,奉献给大家 TM1650 4KEY4LED计数器(总减+移位+减1+加1)C代码 //TM1650四按键四数码管数据调整实验OK //功能:按TM1650四按键四LED数码管模块第二 ...

回复

ID:383215 发表于 2025-4-6 18:03
cjtdz 发表于 2025-4-5 16:02
你说的对,只要段码能显示的,你想让它显示什么就可以显示什么。我不是否定你的做法,我说的意思是:实际 ...

哦,你以为我做测试没有实用价值,我的习惯是使用任何一个元器件或者模块,只要有条件,就先做测试,这次对TM1650驱动四位数码管做的测试很有收获,TM1650驱动四位数码管,3.3V的驱动电压显示正常,没有其它IC3.3V驱动数码管亮度不够的情况,而且和5V驱动的亮度基本一致,位驱动和段驱动画图的时候没有必要一一对应,PCB里怎么顺就怎么连,唯一缺点是八级亮度应该够了,最暗的一级在全黑的夜晚有些偏亮,要是再暗一半就完美了。
做测试就好好做测试,没有必要显示一些不必要的内容,我在我的试验板上加一个18B20,肯定就可以显示温度,加一个时钟IC,就可以显示时间,这样做有何意义?画蛇添足,只要能显示1到9,A到F就足够了,足以证明我的电路没有错,程序没有错。

这次用TM1650驱动四位数码管,主要显示RDA5807调频收音机的频率,电路板已经做好,只要能显示1到9就够了,亮度太亮没有影响,调完频率之后就熄灭显示。RDA5807调频收音机也做过测试,可以设置任意频率收台,这次是增加数码管显示频率和手动调台,我所有测试做完以后再设计电路,成功率相当高,如果不做测试,万一哪一步出了问题,从头再来花费的精力更大。
做好的TM1650驱动四位数码管的电路以后肯定还有用处,下一步我要用K型热电偶测试一个小电炉的最高温度,大概是两三百度,用这个电路做测试非常合适。
ID:33548 发表于 2025-4-5 16:02
kmsj 发表于 2025-4-4 16:33
TM1860只要能显示1234,7段码基本上用完了,要显示什么都可以,只要能显示1234,必然可以显示5678、90Ab、 ...

你说的对,只要段码能显示的,你想让它显示什么就可以显示什么。我不是否定你的做法,我说的意思是:实际应用时,不是按你指定的段码显示的呀?比如接一个温度传感器,要显示一天的温度,它显示的温度数是随机的,不是你指定的。从零下几度到三十多度,都有可能。
ID:383215 发表于 2025-4-4 16:33
cjtdz 发表于 2025-4-1 15:46
你这只能显示1234这几个固定数字,只能做简单的实验,没有实用价值。在实际应用中,有些是需要调整可变的 ...

TM1860只要能显示1234,7段码基本上用完了,要显示什么都可以,只要能显示1234,必然可以显示5678、90Ab、CdEF,无非就是增加段码数组而已。

我就做一个GIF动画,让你看看除了显示1234,还可以显示5678、90Ab、CdEF,第一次做GIF动画,不知道会不会动态显示,估计你根本没有用过TM1860,TM1860驱动数码管,是通过I2C发数据给TMM1860,只要能显示1234,所有需要的内容都可以显示。
ID:33548 发表于 2025-4-1 15:51
本帖最后由 cjtdz 于 2025-4-1 16:04 编辑
kmsj 发表于 2025-3-28 18:47
前段时间画了一个TM1650测试四位数码管的单面板,第一次用TM1650,老老实实的按照TM1650的数据手册画图 ...

沙发那一层,只要在主程序里添加一个端口,去控制一个继电器,就可做一个最长时间为9999秒,可以任意设定的定时器。比如:你设定为120,也就是2分钟,当从120递减到0时,你可以让P0.0输出高电平或低电平,通过电阻、三极管,驱动继电器,去控制什么电器的开启与关闭。在前面做好位定义,比如:sbit kaiguan=P1^0;在主程序相应的地方(主循环里)添加kaiguan=0;或者kaiguan=1;(根据你的硬件配置),这不一个递减定时器不就做成了?!
ID:33548 发表于 2025-4-1 15:46
kmsj 发表于 2025-3-28 18:47
前段时间画了一个TM1650测试四位数码管的单面板,第一次用TM1650,老老实实的按照TM1650的数据手册画图 ...

你这只能显示1234这几个固定数字,只能做简单的实验,没有实用价值。在实际应用中,有些是需要调整可变的。
ID:383215 发表于 2025-3-28 18:47


前段时间画了一个TM1650测试四位数码管的单面板,第一次用TM1650,老老实实的按照TM1650的数据手册画图,TM1650和四位数码管之间的四个公共端管脚连接和7个段码输出+小数点输出管脚连接,严格按照数据手册提供的原理图连接。


一共买了四种四位数码管,0.28寸的和0.36寸的各两种。

手工做的单面板可以测试两种四位数码管。
  
  
按照TM1650数据手册编程,两种数码管都可以正常显示数字,只是编完程序之后才发现,TM1650的公共端和段码输出小数点和数码管的公共端和段码输出小数点,根本没有必要一一对应,只要公共端和段码输出之间不要搞错就可以了。
看了楼主的程序好复杂,很多看不懂,我只是显示数字,没有用到按键检测,TM1650的数据手册在我认知以内,我编的程序很简单。

后来又画了一个TM1650驱动四位数码管的双面板,用来显示调频收发模块的频率,这次画图,TM1650和数码管之间,公共端和段码小数点输出之间的顺序按实际画图,怎么顺就怎么连。


也就是TM1650与数码管之间的驱动连接,DIG是1接4、3接2、2接3、1接4,段码和小数点是a接a、g接c、f接f、e接b……,除了a接a、f接f是对应的,其它都是按PCB布线方便决定的连接,我相信我编程的时候只要注意公共端扫描的顺序,重新编一下段码表,正确显示数字应该不是问题,用豆包AI可以实现吗?

ID:33548 发表于 2025-3-25 13:56
程序再添新功能。上面的TM1650头文件和C文件不变,把模块的第一个按键改成递减开始/暂停功能
//TM1650四按键四数码管数据调整实验2OK

//功能:按TM1650四按键四LED数码管模块第二个键,个位闪烁,第三个键数值减小,第四个键数值增大
//按第一个按键时,4位LED总显示数值递减计数,再按一次,暂停。

#include<reg52.h>
//#include<intrins.h>
#include"tm1650.h"

#define uchar unsigned char
#define uint  unsigned int

// 新增全局变量声明
bit flash_flag;         // 闪烁标志
uchar flash_counter;    // 闪烁计时器
uchar adjust_mode = 0;  // 新增调整模式状态
uchar digits[4] = {0,0,0,0}; // 新增数值存储数组
uint combined_value;    // 4位LED显示总数值
bit counting_down = 0;  // 倒计时标志
bit pause_flag = 0;     // 暂停标志

// 显示编码表(带小数点控制位)
uchar CODE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

// 声明 Scan_Key 函数
uchar Scan_Key();

// 定时器0初始化(原代码功能不变)
void Timer0_Init() {
    TMOD |= 0x01;      // 模式1
    TL0 = 0x18;        // 1ms定时
    TH0 = 0xFC;
    ET0 = 1;           // 中断使能
    TR0 = 1;
    EA = 1;
}

// 显示更新函数(优化小数点处理)
void Update_Display()
{
    uchar seg_data;
    // 千位(地址0x68)
    seg_data = (adjust_mode==4 && flash_flag) ? 0x00 : CODE[digits[0]];
    TM1650_Set(0x68, seg_data | (adjust_mode==4 ? 0x80 : 0x00));
    // 百位(地址0x6A)
    seg_data = (adjust_mode==3 && flash_flag) ? 0x00 : CODE[digits[1]];
    TM1650_Set(0x6A, seg_data | (adjust_mode==3 ? 0x80 : 0x00));
    // 十位(地址0x6C)
    seg_data = (adjust_mode==2 && flash_flag) ? 0x00 : CODE[digits[2]];
    TM1650_Set(0x6C, seg_data | (adjust_mode==2 ? 0x80 : 0x00));
    // 个位(地址0x6E)
    seg_data = (adjust_mode==1 && flash_flag) ? 0x00 : CODE[digits[3]];
    TM1650_Set(0x6E, seg_data | (adjust_mode==1 ? 0x80 : 0x00));

    // 计算总数值
    combined_value = digits[0] * 1000 + digits[1] * 100 + digits[2] * 10 + digits[3];
}

// 定时器0中断服务(原代码功能不变)
void Timer0_ISR() interrupt 1
{
    static uint counter = 0;
    TH0 = 0xFC;        // 重装初值
    TL0 = 0x18;
    if(++counter >= 500) { // 500ms周期
        flash_flag = !flash_flag;
        counter = 0;
    }
}

// 定时器1初始化
void Timer1_Init() {
    TMOD |= 0x10;      // 定时器1,模式1
    TH1 = 0xFC;        // 1ms定时
    TL1 = 0x18;
    ET1 = 1;           // 定时器1中断使能
    TR1 = 0;           // 先不启动定时器1
    EA = 1;
}

// 定时器1中断服务
void Timer1_ISR() interrupt 3
{
    static uint counter = 0;
    TH1 = 0xFC;        // 重装初值
    TL1 = 0x18;
    if (++counter >= 1000) { // 1000ms = 1s
        counter = 0;
        if (counting_down &&!pause_flag && combined_value > 0) {
            combined_value--;
            // 将总数值拆分为各个数位
            digits[0] = combined_value / 1000;
            digits[1] = (combined_value / 100) % 10;
            digits[2] = (combined_value / 10) % 10;
            digits[3] = combined_value % 10;
            Update_Display();
        }
    }
}

// 按键处理(增加边界保护)
void Process_Key(uchar key)
{
    static uchar last_key = 0;
    if(key == last_key) return;
   
    // 模式切换键处理
    if(key == 0x54)   // 0x54是TM1650的按键代码之一
    {
        adjust_mode = (adjust_mode < 4) ? adjust_mode+1 : 0;
        flash_flag = 0;    // 强制显示稳定
    }
    if(key == 0x5c)       // 0x5c是TM1650的按键代码之一
    {
        if(combined_value > 0) {
            if (!counting_down) {
                counting_down = 1;  // 开始倒计时
                TR1 = 1;            // 启动定时器1
                pause_flag = 0;     // 开始时不暂停
            } else {
                pause_flag =!pause_flag; // 切换暂停状态
            }
        }
    }
   
    // 数值调整(带范围限制)
    if(adjust_mode > 0)
    {
        uchar *p = &digits[4 - adjust_mode];
        if(key == 0x4C) *p = (*p - 1 + 10) % 10; // 循环减,0x4c是TM1650的按键代码之一
        if(key == 0x44) *p = (*p + 1) % 10;      // 循环加,0x44是TM1650的按键代码之一
    }
    last_key = key;
}

// 主函数(修正初始化逻辑)
void main()
{
    Timer0_Init();
    Timer1_Init();
    TM1650_Set(0x48, 0x51);        // 显示控制:5级亮度
    Update_Display(); // 初始化显示

    while(1)
    {
        Process_Key(Scan_Key());
        Update_Display();
    }
}

评分

参与人数 1黑币 +40 收起 理由
admin + 40 共享资料的黑币奖励!

查看全部评分

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

Powered by 单片机教程网

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