tm1650为啥一需要应答信号

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tm1650为啥一需要应答信号相关的知识,希望对你有一定的参考价值。

TM1650芯片驱动四位数码管 原创
2021-08-22 01:00:40
 6点赞

十方铺子 

码龄5年

关注
文章目录
自言自语
一、芯片图
二、通讯协议
开始信号
终止信号
发送一字节数据
获取TM1650的应答
三、TM1650的各个功能
数码管显示
数码管关闭
数码管显示数字
自言自语
今天上班被丢了块4位数码管过来,还有一份驱动数码管的芯片资料。还好只有十几页,哈哈哈。
大致浏览下手册,了解到这个芯片叫TM1650,然后是使用模拟IIC协议的。那也就是说,只需要SDA和SCL两条线就能驱动4位数码管!!!
想想好像比那种74HC595节省IO资源多了。所以记录下,哈哈哈~

一、芯片图

其中:
SCL:IIC的时钟线
SDA:IIC的数据线
DIGx:每个数码管的总开关,不开,怎么搞也不会亮滴,数码管1、2、3、4
A/K11~G/K17/DP/KP:因为只用了下数码管,所以建议不用键盘扫描的可以简化成如下:
A~G + DP:也就是一个数码管上的八个段。

下图是本人瞎画图,逻辑是这个逻辑,但是段和字母是我自己随性的哈。


二、通讯协议
TM1650采用的是IIC协议。使用SDA、SCL两条总线。

开始信号
保持SCL、SDA两条总线在高电平,这时候两条总线是在喝茶没事干滴。要让人家干活肯定得确定人家没事干啦。
然后SCL保持住高电平,SCL变成低电平,也就是SDA产生下降沿。这时候,起始信号就产生了。
当然啦,我们跟着要将SCL拉低,钳住总线,这样才能占住这份工,才能专心工作。因为前面说了,高电平人家在喝茶。

终止信号
在SCL保持高电平的时候,SDA先是低电平,然后拉高,也就是SDA产生上升沿,这时候,终止信号就产生了。
SCL、SDA都是高电平,就表示活干完了,两人继续喝茶没事干,就像临时工,哈哈哈~

发送一字节数据
IIC数据都是一位一位发送的,每一位数据都会有两个阶段:想清楚自己是个啥和确定自己是个啥。
在SCL低电平的时候,SDA的数据是可以改变的,也就是可以是1也可以是0,先想清楚自己是1还是0;
在SCL高电平的时候,SDA的数据是稳定的,是1就是1,是0就是0,也就是确定自己是个啥,不能改了。
之后,就会顺着SDA总线自动发送出去,追都追不回来。
TM1650的数据是高位先发送,也就是说0x90 — 1001 0010,先发送的是高位的1,而不是低位的0.
至于IIC协议是不是都这样,没记,所以不乱说。

发送一字节数据的话,就是发8位数据,写个for循环,将一字节数据左移>>加与&操作凑成个函数。

获取TM1650的应答
你跟人家聊天,不是舔狗的那种,肯定是你找人家说话,人家愿意回你,才能接着聊下一个话题啦。不然的话,哥也是有脾气的,不聊了,结束话题。
每次主机发送一字节数据,都会需要TM1650回应一个应答,主机接收到了,才会接着往下发下一个字节。
也就是说,每第9个数据,是用来给TM1650回应一个应答位的。
0就是收到了,1就是没收到,发送失败,没得玩。
当SCL第9个时钟为低电平时,TM1650如果接收到数据,就会将SDA抢过来,发一个低电平给主机,否则就是高电平。

三、TM1650的各个功能
数据命令设置:0x48,这个是告诉TM1650,我们要用点亮数码管的功能,而不是按键扫描的功能
显示命令设置:

这里实际是一个字节数据,只是不同位部分代表不同功能。
bit[6:4]:设置数码管亮度,注意,000是最亮哦。
bit[3]:设置要不要显示小数点
bit[0]:是不是要开启数码管的显示

数码管显示
比如说,8级亮度,不显示小数点,那就是0x05
起始信号 — 发送数据0x48 — 判断丛机应答 — 发送 数据0x05 — 判断丛机应答 — 终止信号
这样,数码管就打开显示了。
打开之后,在后面显示数字的时候,就不用重复发送数据0x48了,因为我们已经选好了数码管功能。

亮度和显示方式可以做成枚举,清晰,而且多个数据占一个地方,很节省空间,多爽~

数码管关闭
起始信号 — 发送数据0x48 — 判断丛机应答 — 发送 数据0x00 — 判断丛机应答 — 终止信号
这样,数码管就关闭显示了。

数码管显示数字
我们要显示数字,首先得告诉TM1650,显示的是哪个数码管的数字,下面的数据就对应好了哪个数码管:

然后我们就可以显示数字了,一个数据8个位,刚好对应8个段,1就是亮,0就是灭。
我的话,因为分不清哪个位对那个段,哈哈哈,所以我是循环按位点亮来理清哪个位对哪个段的。

比如点亮数码1显示8,那就是0x68,假设0x7f是8,哈哈哈,因为还有个位是小数点。
那就是:
起始信号 — 发送数据0x68 — 判断丛机应答 — 发送 数据0x7f — 判断丛机应答 — 终止信号

然后,顺利的话,就会在数码管1亮起一个8。

将0~9对应的值,做成一个数组,通过数组下标确定就比较方便了。

之后就可以将其完善成一个个小功能,用来显示数字、调节亮度、切换小数点、数码管切换了。

两条线控制4位数码管,很不错的设计~

打开CSDN,阅读体验更佳

基于STM32的常用数码管芯片TM1650驱动_Blucher_Ce的博客_stm...
void TM1650_stop() HAL_GPIO_WritePin(AnalonSCL_GPIO_Port, AnalonSCL_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(AnalonSDA_GPIO_Port, AnalonSDA_Pin, GPIO_PIN_RESET); HAL_Delay(1); ...
继续访问
TM1650驱动数码管以及按键扫描_memoff的博客
TM1650真是一款性价比很高的芯片,一个芯片就能够驱动4位8段数码管以及按键扫描。经过和STM32F030芯片的实验,达到了所有预期的效果。和以往的74HC595芯片对比,节省芯片一片,以往需要两片595芯片才能驱动4位数码管,闪烁控制,亮度控制完全...
继续访问
最新发布 数码管显示驱动芯片 CH450
提供DIP20 和SOP20 两种无铅封装,兼容RoHS,功能和引脚部分兼容CH455 芯片。高速2 线串行接口,时钟速度从0 到2MHz,兼容两线I2C 总线,节约引脚。提供低电平有效的键盘中断,提供按键释放标志位,可供查询按键按下与释放。内置时钟振荡电路,不需要外部提供时钟或者外接振荡元器件,更抗干扰。内置显示电流驱动级,段电流不小于15mA,字电流不小于80mA。支持低功耗睡眠,节约电能,可以被按键唤醒或者被命令操作唤醒。内置上电复位,可以为单片机提供高电平有效的复位输出。
继续访问
数码管显示模块tm1650
提供按键与数码管显示的解决方案,使用tm1650,可以减少对单片机IO口资源的占用,有利于产品开发。数码管显示程序更加简化,代码移植性强。
TM1650LED数码管驱动
TM1650LED数码管驱动,STM8S105 通过模拟IIC控制TM1650显示,按键获取
TM1650手册
TM1650是一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用IC, 内部集成有MCU 数字接口、数据锁存器、 LED驱动、键盘扫描等电路。 本产品质量可靠、稳定性好、抗干扰能力强。 主要适用于机顶盒、 家电设备(智能热水器、微波炉、 洗衣机、空调、电磁炉) 、电子称、智能电 表等数码管, 可适用于24小时长期连续工作的应用场合。
TM1650驱动数码管(模拟IIC)
TM1650可以节省单片机引脚驱动数码管利用时序图写出驱动程序。 void I2CStart(void)//开始信号 CLK_H; DIO_H; Delay_us(5); DIO_L; void I2Cask(void) //ACK信号 u8 timeout = 1; CLK_H; Delay_us(5); CLK_L; while((DIO)&&(timeout<=100)) timeout++; Delay_...
继续访问
STM32 TM1650数码管显示与按键识别
STM 32TM1650 控制程序(可移植) 这代码弄了好几天才弄好,现在给大家分享一下 #include "tm1650.h" void SDA_IN(void) GPIO_InitTypeDef GPIO_InitStructa; GPIO_InitStructa.GPIO_Pin = TM1650_SDA_pin; GPIO_InitStructa.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB,&GPIO_InitStructa);
继续访问
TM1650数码管驱动芯片
简介 TM1650是一款国产4位共阴数码管驱动芯片,它还带有矩阵按键扫码功能。它的基本参数如下: 工作电压:3~5V 数码管驱动模式:8段x4位共阴数码管 矩阵按键驱动模式:7x4矩阵按键,不支持组合键 通信接口:类IIC,使用了IIC相同的时序,但没有完全遵守IIC的协议,不带从机地址 引脚定义 SCL:串行通信时钟线 SDA:串行通信数据线 做数码管驱动使用时 DIGx:数码管的位选引脚,灌电流驱动,最大可吸收150mA电流 A~DP:数码管的段驱动引脚,拉电流驱动,最大可输出25m
继续访问

15.[STM32]一篇文章教会你使用75HC595芯片驱动四位数码管
74HC595驱动四位
参考技术A 每次主机发送一字节数据,都会需要TM1650回应一个应答,主机接收到了,才会接着往下发下一个字节。也就是说,每第9个数据,是用来给TM1650回应一个应答位的。0就是收到了,1就是没收到,发送失败,没得玩。当SCL第9

为啥 fread 循环需要额外的 Ctrl+D 来用 glibc 发出 EOF 信号?

【中文标题】为啥 fread 循环需要额外的 Ctrl+D 来用 glibc 发出 EOF 信号?【英文标题】:Why does an fread loop require an extra Ctrl+D to signal EOF with glibc?为什么 fread 循环需要额外的 Ctrl+D 来用 glibc 发出 EOF 信号? 【发布时间】:2019-03-11 11:01:39 【问题描述】:

通常,要向附加到 Linux 终端上的标准输入的程序指示 EOF,如果我只是按 Enter,则需要按一次 Ctrl+D,否则需要按两次。不过,我注意到patch 命令是不同的。有了它,如果我只是按 Enter,我需要按 Ctrl+D 两次,否则需要按 3 次。 (而不是cat | patch 没有这种奇怪之处。此外,如果我在输入任何实际输入之前按 Ctrl+D,它就没有这种奇怪之处。)深入研究patch 的源代码,我追踪这回the way it loops on fread。这是一个做同样事情的最小程序:

#include <stdio.h>

int main(void) 
    char buf[4096];
    size_t charsread;
    while((charsread = fread(buf, 1, sizeof(buf), stdin)) != 0) 
        printf("Read %zu bytes. EOF: %d. Error: %d.\n", charsread, feof(stdin), ferror(stdin));
    
    printf("Read zero bytes. EOF: %d. Error: %d. Exiting.\n", feof(stdin), ferror(stdin));
    return 0;

当完全按原样编译和运行上述程序时,以下是事件时间线:

    我的程序调用freadfread 调用read 系统调用。 我输入“asdf”。 我按 Enter。 read 系统调用返回 5。 fread 再次调用read 系统调用。 我按 Ctrl+D。 read 系统调用返回 0。 fread 返回 5。 我的程序打印Read 5 bytes. EOF: 1. Error: 0. 我的程序再次调用freadfread 调用read 系统调用。 我再次按 Ctrl+D。 read 系统调用返回 0。 fread 返回 0。 我的程序打印Read zero bytes. EOF: 1. Error: 0. Exiting.

为什么这种读取标准输入的方式会有这种行为,不像其他程序似乎读取它的方式?这是patch 中的错误吗?这种循环应该怎么写才能避免这种行为呢?

更新:这似乎与 libc 有关。我最初在 Ubuntu 16.04 的 glibc 2.23-0ubuntu3 上体验过它。 @Barmar 在 cmets 中指出它不会在 macOS 上发生。听到这个后,我尝试针对同样来自 Ubuntu 16.04 的 musl 1.1.9-1 编译相同的程序,但没有出现这个问题。在 musl 上,事件序列删除了第 12 步到第 14 步,这就是为什么它没有问题,但在其他方面是相同的(除了 readv 代替 read 的不相关细节)。

现在,问题变成了:glibc 的行为是错误的,还是 patch 错误地假设它的 libc 不会有这种行为?

【问题讨论】:

至少请参阅Canonical vs non-canonical terminal input。这提到点击“EOF”指示键可使所有缓冲输入对read() 可用。如果没有缓冲输入,它会提供零字节,读取的零字节表示 EOF。 @JonathanLeffler 这解释了为什么你必须在一行的开头输入 Ctl-D 来表示 EOF。但这并不能解释为什么他必须这样做两次。 @Barmar 另一个重要的细节:您需要输入一些输入而不是立即按 Ctrl+D,否则它可以正常工作。我也会补充的。 糟糕,当我以为我在 Linux 上进行测试时,我不在 Linux 上。它在 MacOS 上可以正常工作,但我在 Linux 上看到的和你一样。 它是 linux 实现的工件,以及 tty 的工作原理。第一个 CTRL+D 将 asdf\n 发送到您的程序,但 CTRL+D 实际上并没有关闭标准输入。 fread() 继续并且 read() 系统调用阻塞,因为标准输入并没有真正关闭。 fread() 决定放弃下一个 CTRL+D,因为 read() 返回 0 并且其内部缓冲区中没有任何内容。 【参考方案1】:

我已经设法确认这是由于 2.28 之前的 glibc 版本中存在明确的错误(提交 2cc7bad)。相关引用来自the C standard:

字节输入/输出函数——本小节中描述的那些执行 输入/输出:[...],fread

字节输入函数从流中读取字符,就好像连续 调用fgetc 函数。

如果设置了流的文件结束指示符,如果流处于文件结束位置,则设置流的文件结束指示符并且fgetc 函数返回 EOF。否则,fgetc 函数从stream 指向的输入流中返回下一个字符。

(强调“或”我的)

下面的程序用fgetc演示了这个错误:

#include <stdio.h>

int main(void) 
    while(fgetc(stdin) != EOF) 
        puts("Read and discarded a character from stdin");
    
    puts("fgetc(stdin) returned EOF");
    if(!feof(stdin)) 
        /* Included only for completeness. Doesn't occur in my testing. */
        puts("Standard violation! After fgetc returned EOF, the end-of-file indicator wasn't set");
        return 1;
    
    if(fgetc(stdin) != EOF) 
        /* This happens with glibc in my testing. */
        puts("Standard violation! When fgetc was called with the end-of-file indicator set, it didn't return EOF");
        return 1;
    
    /* This happens with musl in my testing. */
    puts("No standard violation detected");
    return 0;

为了演示错误:

    编译程序并执行 按 Ctrl+D 按 Enter 键

确切的错误是,如果设置了文件尾流指示符,但流不在文件尾,glibc 的 fgetc 将返回流中的下一个字符,而不是标准要求的 EOF .

由于fread是根据fgetc定义的,这就是我最初看到的原因。它之前被报告为 glibc bug #1190,并且自 2018 年 2 月提交 2cc7bad 以来一直被修复,该提交于 2018 年 8 月登陆 glibc 2.28。

【讨论】:

不幸的是,此错误修复会导致其他软件出现回归问题,例如 cups-filters。但我们决定keep the fix, at least for now。 是的,这是从 sysv unix 中的一个 bug 继承而来的一个非常古老、众所周知的 glibc 错误。现在大多数其他实现都没有这个错误,所以任何被 glibc 中的修复程序破坏的软件也将在大多数非 glibc(例如 BSD)系统上被破坏。 相反,hexdump 等软件被旧的 GNU C 库行为所破坏,并且可以与其他 C 库一起使用。 unix.stackexchange.com/q/517064/5132

以上是关于tm1650为啥一需要应答信号的主要内容,如果未能解决你的问题,请参考以下文章

涂鸦智能暖风机软件实现之利用TM1650实现显示功能

TM1650/AIP650数码管驱动显示STM32驱动程序HAL库

TM1650/AIP650数码管驱动显示STM32驱动程序HAL库

tm1651如何驱动数码管

为啥 struct tm 的 tm_gmtoff 字段未在手册页中记录?

为啥在传输和处理需要数字信号编成二进制码