zhaojingbo111 发表于 2025-3-16 18:14:50

有没tm1650的硬件写的驱动

用I2C的硬件和tm1650通讯,搞不好,到底是哪的问题需要定义io位开漏模式吗


oid main()
{
      P1M0 = 0xc0; P1M1 = 0xc0;


    P_SW2 = 0x80;

    I2CCFG = 0xff;                              //使能I2C主机模式
    I2CMSST = 0x00;

   
    while (1)

国芯人工智能 发表于 2025-3-16 18:18:00

在处理TM1650与I2C硬件的通讯问题时,首先需要确保硬件连接和配置正确。您提到的代码片段中,P1M0和P1M1的配置用于设置IO口的模式,但具体是否设置为开漏模式需要根据实际情况判断。对于I2C通讯,通常SDA(数据线)和SCL(时钟线)需要设置为开漏模式,以便实现双向通讯和总线仲裁。<br><br>以下是一些可能的问题排查步骤:<br><br>1. IO口模式设置:确保SDA和SCL引脚设置为开漏模式。对于8051系列单片机,可以通过PxM0和PxM1寄存器配置。例如,P1M0 = 0xC0; P1M1 = 0xC0; 将P1.6和P1.7设置为开漏模式。<br><br>2. I2C配置:检查I2C配置寄存器是否正确设置。I2CCFG = 0xFF; 可能配置了I2C主机模式,但具体寄存器定义需参考芯片手册。<br><br>3. TM1650初始化:TM1650需要初始化命令来设置显示模式和亮度。确保在通讯前发送正确的初始化命令。<br><br>4. 时序和信号完整性:检查I2C通讯的时序是否符合TM1650的要求,确保信号没有干扰或衰减。<br><br>5. 硬件连接:检查SDA和SCL的硬件连接是否正确,包括上拉电阻的阻值是否合适(通常为4.7kΩ)。<br><br>建议参考TM1650和单片机的手册,确保所有配置和连接正确。如果问题仍然存在,可以使用逻辑分析仪或示波器检查I2C信号,进一步排查问题。<br><br>[本文内容由国芯人工智能辅助生成,仅供参考]

zhaoyun189911 发表于 2025-4-10 22:11:16

怎样有进展了没有? 我也一直想尝试用硬件IIC驱动tm01650苦于一直没有成功

神农鼎 发表于 2025-4-10 22:14:21


在本坛搜索如下关键字

晓飛飛 发表于 2025-4-12 10:27:39

我这里有个ET6226的硬件I2C驱动代码,和TM1650、AIP650这些应该都是兼容的。

#include "intrins.h"
#include "main.h"
#include "ET6226.h"


#define ET6226_DISPLAY_BASE1 0x68 // 数码管0的地址
#define ET6226_DISPLAY_BASE2 0x6A // 数码管1的地址
#define ET6226_DISPLAY_BASE3 0x6C // 数码管2的地址
#define ET6226_DISPLAY_BASE4 0x6E // 数码管3的地址
#define ET6226_DCTRL_BASE    0x48 // 控制寄存器地址
#define ET6226_KEYBOARD_BASE 0x4F // 键盘编码地址

#define ET6226_DISPLAY_ON          0x09
#define ET6226_DISPLAY_OFF0x00
#define ET6226_CHIP_SLEEP      0x04

//code ET6226_BRIGHT_LEVEL = {0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x01}; //输出亮度从低到高
code ET6226_BRIGHT_LEVEL = {0x19,0x29,0x39,0x49,0x59,0x69,0x79,0x09}; //输出亮度从低到高

unsigned char key_value;
unsigned char key_flag;

bitbusy;
unsigned char key_scan(void);

void Wait()
{
    while (!(I2CMSST & 0x40));
    I2CMSST &= ~0x40;
}

void Start()
{
    I2CMSCR = 0x01;                           //发送START命令
    Wait();
}

void SendData(char dat)
{
    I2CTXD = dat;                               //写数据到数据缓冲区
    I2CMSCR = 0x02;                           //发送SEND命令
    Wait();
}

void RecvACK()
{
    I2CMSCR = 0x03;                           //发送读ACK命令
    Wait();
}

char RecvData()
{
    I2CMSCR = 0x04;                           //发送RECV命令
    Wait();
    return I2CRXD;
}

void SendACK()
{
    I2CMSST = 0x00;                           //设置ACK信号
    I2CMSCR = 0x05;                           //发送ACK命令
    Wait();
}

void SendNAK()
{
    I2CMSST = 0x01;                           //设置NAK信号
    I2CMSCR = 0x05;                           //发送ACK命令
    Wait();
}

void Stop()
{
    I2CMSCR = 0x06;                           //发送STOP命令
    Wait();
}

void I2C_Init(void)
{
      P_SW2|= 0x80;
      I2CCFG= 0xe0;                              //使能I2C主机模式
      I2CMSST = 0x00;
      SDA   = 1;
      SCL   = 1;
//      P_SW2|= 0x00;                               //SCL/P1.5, SDA/P1.4      
      P_SW2|= 0x10;                               //SCL_2/P2.5, SDA_2/P2.4
//P_SW2|= 0x30;                               //SCL_4/P3.2, SDA_4/P3.3
}

void ET6226_sendbyte(unsigned char add,unsigned char dat)
{
      char sfr_temp = P_SW2;
      P_SW2 |= 0x80;               
      Start();                                 //发送起始命令
      SendData(add);               //发送控制地址
      RecvACK();
      SendData(dat);               //发送开显示指令
      RecvACK();
      Stop();
      P_SW2 = sfr_temp;      
      delay_ms(20);
}


void INT3_Isr() interrupt 11
{
      unsigned char key_code;
      char sfr_temp = P_SW2;
      LED_COMM = 0;      
      P_SW2 |= 0x80;      
      Start();                                    //发送起始命令
      SendData(ET6226_KEYBOARD_BASE);                           //发送设备地址+写命令
      RecvACK();
      key_code =RecvData();
      SendNAK();
      //RecvACK();
      Stop();
      P_SW2 = sfr_temp;      
      if (key_code&0x40)
      {            
                key_value =key_code;
                key_flag = 2;
      }   
      LED_COMM = 1;
}

unsigned char key_scan(void)
{      
      unsigned char key_code;
      char sfr_temp = P_SW2;
      P_SW2 |= 0x80;      
      if(KEY_INT == 0)
      {      
                Start();                                    //发送起始命令
                SendData(ET6226_KEYBOARD_BASE);                           //发送设备地址+写命令
                RecvACK();
                key_code =RecvData();
                SendNAK();
                Stop();
                P_SW2 = sfr_temp;               
                if (key_code&0x40){   
                        //key_code <<= 1;               
                        //key_code &=0x7F;
                }
      }
      return         key_code;
}

extern void ET6226_Init(void)
{
      I2C_Init();
      delay_ms(5);
      ET6226_sendbyte(ET6226_DCTRL_BASE,ET6226_BRIGHT_LEVEL);   //显示亮度最亮
      ET6226_sendbyte(ET6226_DISPLAY_BASE1,0xFF);   //小7键背光
      ET6226_sendbyte(ET6226_DISPLAY_BASE2,0xFF);   //启停键背光
      
      Start();                                    //发送起始命令
      SendData(ET6226_KEYBOARD_BASE);                           //发送设备地址+写命令
      RecvACK();
      RecvData();
      SendNAK();
      Stop();         
      
      P_SW2 |= 0x80;
      INTCLKO |= 0x20;                              //使能INT3中断      
}




页: [1]
查看完整版本: 有没tm1650的硬件写的驱动