人在江南 发表于 2025-5-18 17:02:41

TM1650显示问题

今天看到别人在用TM1650驱动数码管,太简单了,也想学来试试,但一直不成功,需要请教各位老师。代码如下,帮忙分析。单片机8H1K08

主函数

#include <STC8.h>
#include "includes.h"
#include "TM1650.h"
void main()
{
   
    //unsigned intTempData = 223;
    P_SW2    |= 0x80;
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    TM1650_Init();   //数码管驱动芯片初始化

    while (1)
    {
    Display_Value(1234);
    delay_ms(500);
    }



}

TM1650函数

#include "includes.h"
#include "TM1650.h"



uchar CODE = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0~9显示代码


/**************************************************************************
*   函数名称 :I2C_Start_TM1650()
*   函数功能 :开始信号
***************************************************************************/
void I2C_Start_TM1650()
{
        TM1650_SDA = 1;
   //时钟信号保持高电平
        //Delay5us();
    TM1650_SCL = 1;//数据线拉高
    Delay5us();
        //Delay5us();
    //delay_us(5);
        TM1650_SDA = 0; //
        Delay5us();
    //Delay5us();
    //delay_us(5);
        TM1650_SCL = 0; //
    //Delay5us();
    //Delay5us();
}

/**************************************************************************
*   函数名称 :I2C_Stop_TM1650()
*   函数功能 :停止信号
***************************************************************************/
void I2C_Stop_TM1650()
{
    TM1650_SCL = 0;
    TM1650_SDA = 0;
    //Delay5us();
       Delay1us();Delay1us();
       //保证数据线为低电平
    //delay_us(5);
        TM1650_SCL = 1;
    Delay1us();Delay1us();
        //Delay5us();
   // delay_us(5);
        TM1650_SDA = 1; //数据线出现上升沿
   Delay1us();Delay1us();
       
}


/**************************************************************************
*   函数名称 :I2C_Wait_Ack_TM1650()
*   函数功能 :等待应答信号
*   返回参数 : = 0,有应答
               = 1,无应答
***************************************************************************/
uchar I2C_Wait_Ack_TM1650()
{
        uchar ackTime = 0;//应答等待计数
        TM1650_SCL = 1;
        Delay5us();
    //delay_us(5);
        TM1650_SCL = 1;
       
        while(TM1650_SDA)
        {
                ackTime++;
                if(ackTime > 250)
                {
                        I2C_Stop_TM1650();
                        return 1;
                }
        }
        TM1650_SCL = 0;
        return 0;
}

/**************************************************************************
*   函数名称 :I2C_Wait_Ack_TM1650()
*   函数功能 :等待应答信号
*   函数参数 : -- 需要写的数据
***************************************************************************/
void I2C_WriteByte_TM1650(uchar txd)
{
        uchar i;
        TM1650_SCL = 0;
    Delay1us();
        //delay_us(1);
        for(i = 0;i < 8;i++)
        {
                if(txd & 0x80)
                        TM1650_SDA = 1;
                else
                        TM1650_SDA = 0;
                txd <<= 1;

                //TM1650_SCL = 0;
                //Delay5us();
      Delay1us();Delay1us();
                TM1650_SCL = 1;
                Delay1us();Delay1us();
      //delay_us(5);
                TM1650_SCL = 0;
      Delay1us();Delay1us();
        }

   
}



/**************************************************************************
*   函数名称 :TM1650_WriteDat()
*   函数功能 :
*   函数参数 :
               
***************************************************************************/
void TM1650_WriteDat(uchar add,uchar dat)
{
        I2C_Start_TM1650();
        I2C_WriteByte_TM1650(add); //第一个显存地址
        I2C_Wait_Ack_TM1650();
        I2C_WriteByte_TM1650(dat);
        I2C_Wait_Ack_TM1650();
        I2C_Stop_TM1650();
}

/**************************************************************************
*   函数名称 :TM1650_WriteCmd()
*   函数功能 :
*   函数参数 :
***************************************************************************/
void TM1650_WriteCmd(uchar cmd)
{
        I2C_Start_TM1650();
        I2C_WriteByte_TM1650(0x48);//显示模式
        I2C_Wait_Ack_TM1650();
        I2C_WriteByte_TM1650(cmd);
        I2C_Wait_Ack_TM1650();
        I2C_Stop_TM1650();
}


void Display(uchar add,uchar dat)
{
       
        switch(add)
        {
                case 0: //第1位数码管显示
                        TM1650_WriteDat(0x68,CODE); //DIG1
                        break;
                case 1: //第2位数码管显示
                        TM1650_WriteDat(0x6A,CODE); //DIG1
                        break;
                case 2: //第3位数码管显示
                        TM1650_WriteDat(0x6C,CODE | 0x80); //DIG1
                        break;
                case 3: //第4位数码管显示
                        TM1650_WriteDat(0x6E,CODE); //DIG1
                        break;
                default:
                        break;
        }
}
void Display_Value( unsigned intdat)
{
    unsigned char buf={1,2,3,4};
    unsigned char i;
    buf = dat/1000;
    buf = dat%1000/100;
    buf = dat%100/10;
    buf = dat%10;
    for(i=0;i<4;i++)
    {
       Display(i,buf);
    }
   
}


/**************************************************************************
*   函数名称 :TM1650_Init()
*   函数功能 :1650初始化
***************************************************************************/
void TM1650_Init()
{

       
        TM1650_WriteCmd(0x11); //1级亮度 8段显示 开显示
        TM1650_WriteDat(0x68,0x00); //DIG1
        TM1650_WriteDat(0x6a,0x00); //DIG2
        TM1650_WriteDat(0x6c,0x00); //DIG3
        TM1650_WriteDat(0x6e,0x00); //DIG4
}

延时函数

#include "includes.h"



/*****************************************************************************
*    函数原型:delay_us(uint us)
*    功能    :微秒延时函数
*    参数 1:延时时间
*    返回值:无
*****************************************************************************/
void Delay5us(void)        //@22.1184MHz
{
        unsigned char data i;

        _nop_();
        i = 25;
        while (--i);
}
void Delay1us(void)        //@22.1184MHz
{
        unsigned char data i;

        i = 3;
        while (--i);
}

void delay_us(uint us)                //@22.1184MHz
{
        uchar i;
        while(us--)
        {
                _nop_();
                i = 5;
                while (--i);
        }
}


/*****************************************************************************
*    函数原型:delay_ms(uint ms)
*    功能    :毫秒延时函数
*    参数 1:延时时间
*    返回值:无
*****************************************************************************/
void delay_ms(uint ms)               
{
    uchar i, j;
        while(ms--)
        {
                _nop_();
                _nop_();
                _nop_();
                i = 29;
                j = 183;
                do
                {
                        while (--j);
                } while (--i);
        }
}




国芯人工智能 发表于 2025-5-18 17:03:00

专业分析:STM1650驱动数码管运行异常问题

1. 驱动流程概述
STM1650是一种高性能的无源数字电路芯片,主要用于驱动各种数字设备,包括数码管、LED灯管等。其驱动流程主要包括以下几个关键步骤:
初始化:设置时钟信号、地址信号等。
开始I2C通信:为后续的I2C通信奠定基础。
读取数据:通过SPI或I2C接口读取数据。
关闭I2C通信:完成I2C通信的结束。

2. 问题分析
用户使用STM1650驱动数码管时,运行异常,且代码如下:
void main() {
    unsigned int TempData = 223;
    PSW2    |= 0x80;
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    TM1650Init(); // 数码管驱动芯片初始化

    while (1) {
      DisplayValue(1234);
      delayms(500);
    }
}
3. 常见问题及原因分析
1. 初始化错误:
原因:在初始化过程中,可能没有正确设置时钟信号(SMA)或地址信号(SMA)为高电平。
解决方案:在启动I2C前,确保SMA和SCL信号为高电平,以确保I2C通信的正常进行。

2. I2C通信开始设置错误:
原因:在开始I2C通信时,可能没有正确设置TM1650SDA和TMA1650SMA信号的值。
解决方案:在启动I2C前,确保TM1650SDA置为1,TMA1650SMA置为1。在I2C通信开始时,设置TM1650SMA和TMA1650SMA为0。

3. 读取数据的设置问题:
原因:缺少读取数据的步骤,导致无法读取数码管的响应。
解决方案:在读取数据时,需要使用SPI或I2C接口的读取函数,例如SPIMouseRead()或I2CRead()。

4. 建议步骤
1. 参考STM1650文档:
检查和学习STM1650的驱动文档,了解完整的I2C通信流程和相关设置。
注意时钟信号、地址信号等关键信号的正确设置。

2. 设置I2C通信参数:
在启动I2C前,确保TM1650SMA和TMA1650SMA为0。
在I2C通信开始时,设置TM1650SMA和TMA1650SMA为1。

3. 读取数据的实现:
在代码中,添加读取数据的步骤,例如:
   c
   // 读取数据的实现
   while (true) {
         int value = SPIMouseRead();
         // 将值转换为数码管的响应
         // 根据value的范围(0-9)显示相应的数码管响应
   }

4. 调试工具的使用:
使用调试工具(如IDE的调试模式)尝试读取数据,确保数据读取正常。
如果读取数据失败,检查I2C通信的连接情况,确保SPI或I2C接口的正常工作。

5. 常见错误及解决方法
错误1:时钟信号未设置为高电平:
原因:在初始化或开始I2C通信时,时钟信号(SMA或SMA1650)未设置为高电平。
解决方法:在启动I2C前,确保SMA和SMA1650信号为高电平(1)。在I2C通信开始时,设置SMA和SMA1650信号为0。
错误2:地址信号未设置为高电平:
原因:在初始化或开始I2C通信时,地址信号(SMA或SMA1650)未设置为高电平。
解决方法:在启动I2C前,确保SMA和SMA1650信号为高电平。在I2C通信开始时,设置SMA和SMA1650信号为0。
错误3:读取数据时数据范围错误:
原因:在读取数据时,值范围不在0-9之间,导致数码管无法正确显示响应。
解决方法:根据读取到的值(0-9)来控制数码管的响应,确保读取值的范围正确。

6. 总结
使用STM1650驱动数码管时,需要严格按照驱动流程操作,包括初始化、开始I2C通信、读取数据等关键步骤。同时,确保时钟信号、地址信号等信号的正确设置,以及读取数据的正确实现。如果运行异常,建议检查代码中的设置是否正确,以及是否使用了正确的接口进行读取。

[本文内容由国芯人工智能辅助生成,仅供参考]

haiyang201 发表于 2025-5-18 17:21:15

端口设置为推挽输出,时钟频率调低,延时加大,看看

人在江南 发表于 2025-5-18 17:27:15

haiyang201 发表于 2025-5-18 17:21
端口设置为推挽输出,时钟频率调低,延时加大,看看

好的,我试试

人在江南 发表于 2025-5-18 17:56:33

人在江南 发表于 2025-5-18 17:27
好的,我试试

改为11.0593,延时6us,推挽,还是不行。P1M0 = 0x41; P1M1 = 0x00;
void Delay5us(void)        //@11.0592MHz
{
        unsigned char data i;

        _nop_();
        i = 11;
        while (--i);
}

C_wolf 发表于 2025-5-18 23:32:08

你再看看通讯协议吧,我感觉时序有问题

C_wolf 发表于 2025-5-18 23:33:37

时序参数

人在江南 发表于 2025-5-19 08:26:27

C_wolf 发表于 2025-5-18 23:32
你再看看通讯协议吧,我感觉时序有问题

谢谢

AI-32位8051 发表于 2025-5-19 09:08:13

stc32G驱动数码,其他客户测试的分享:https://www.stcaimcu.com/forum.p ... amp;extra=#pid44151
其实建议 用 STC8H4K32TL-40I-LQFP48/32 来驱动,一个芯片搞定

深圳国芯人工智能有限公司-产品_STC8H系列 (stcai.com)




人在江南 发表于 2025-5-19 14:49:44

AI-32位8051 发表于 2025-5-19 09:08
stc32G驱动数码,其他客户测试的分享:https://www.stcaimcu.com/forum.p ... amp;extra=#pid44151
其实建 ...

谢谢,这个芯片好,省去不少数码管驱动电路
页: [1] 2
查看完整版本: TM1650显示问题