![]() |
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型热电偶测试一个小电炉的最高温度,大概是两三百度,用这个电路做测试非常合适。 |
kmsj 发表于 2025-4-4 16:33 你说的对,只要段码能显示的,你想让它显示什么就可以显示什么。我不是否定你的做法,我说的意思是:实际应用时,不是按你指定的段码显示的呀?比如接一个温度传感器,要显示一天的温度,它显示的温度数是随机的,不是你指定的。从零下几度到三十多度,都有可能。 |
cjtdz 发表于 2025-4-1 15:46 TM1860只要能显示1234,7段码基本上用完了,要显示什么都可以,只要能显示1234,必然可以显示5678、90Ab、CdEF,无非就是增加段码数组而已。 ![]() 我就做一个GIF动画,让你看看除了显示1234,还可以显示5678、90Ab、CdEF,第一次做GIF动画,不知道会不会动态显示,估计你根本没有用过TM1860,TM1860驱动数码管,是通过I2C发数据给TMM1860,只要能显示1234,所有需要的内容都可以显示。 |
本帖最后由 cjtdz 于 2025-4-1 16:04 编辑 kmsj 发表于 2025-3-28 18:47 沙发那一层,只要在主程序里添加一个端口,去控制一个继电器,就可做一个最长时间为9999秒,可以任意设定的定时器。比如:你设定为120,也就是2分钟,当从120递减到0时,你可以让P0.0输出高电平或低电平,通过电阻、三极管,驱动继电器,去控制什么电器的开启与关闭。在前面做好位定义,比如:sbit kaiguan=P1^0;在主程序相应的地方(主循环里)添加kaiguan=0;或者kaiguan=1;(根据你的硬件配置),这不一个递减定时器不就做成了?! |
kmsj 发表于 2025-3-28 18:47 你这只能显示1234这几个固定数字,只能做简单的实验,没有实用价值。在实际应用中,有些是需要调整可变的。 |
![]() 前段时间画了一个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可以实现吗? |
程序再添新功能。上面的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(); } } |