找回密码
 立即注册
查看: 336|回复: 12

有没tm1650的硬件写的驱动

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:34
  • 最近打卡:2025-03-16 18:14:50

6

主题

6

回帖

228

积分

中级会员

积分
228
发表于 2025-3-16 18:14:50 | 显示全部楼层 |阅读模式
用I2C的硬件和tm1650通讯,搞不好,到底是哪的问题需要定义io位开漏模式吗


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


    P_SW2 = 0x80;

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

   
    while (1)
回复

使用道具 举报 送花

3

主题

722

回帖

155

积分

等待验证会员

积分
155
发表于 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>[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:85
  • 最近打卡:2025-06-15 20:21:30

5

主题

25

回帖

69

积分

注册会员

积分
69
发表于 2025-4-10 22:11:16 | 显示全部楼层
怎样  有进展了没有? 我也一直想尝试用硬件IIC驱动tm01650  苦于一直没有成功
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:99
  • 最近打卡:2025-06-16 09:28:47

733

主题

1万

回帖

1万

积分

管理员

积分
16635
发表于 2025-4-10 22:14:21 | 显示全部楼层

在本坛搜索如下关键字
截图202504102213562803.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:459
  • 最近打卡:2025-06-16 00:13:00
已绑定手机

37

主题

2221

回帖

2658

积分

荣誉版主

积分
2658
发表于 2025-4-12 10:27:39 | 显示全部楼层
我这里有个ET6226的硬件I2C驱动代码,和TM1650、AIP650这些应该都是兼容的。
  1. #include "intrins.h"
  2. #include "main.h"
  3. #include "ET6226.h"
  4. #define ET6226_DISPLAY_BASE1 0x68 // 数码管0的地址
  5. #define ET6226_DISPLAY_BASE2 0x6A // 数码管1的地址
  6. #define ET6226_DISPLAY_BASE3 0x6C // 数码管2的地址
  7. #define ET6226_DISPLAY_BASE4 0x6E // 数码管3的地址
  8. #define ET6226_DCTRL_BASE    0x48 // 控制寄存器地址
  9. #define ET6226_KEYBOARD_BASE 0x4F // 键盘编码地址
  10. #define ET6226_DISPLAY_ON          0x09
  11. #define ET6226_DISPLAY_OFF  0x00
  12. #define ET6226_CHIP_SLEEP        0x04
  13. //code ET6226_BRIGHT_LEVEL [8] = {0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x01}; //输出亮度从低到高
  14. code ET6226_BRIGHT_LEVEL [8] = {0x19,0x29,0x39,0x49,0x59,0x69,0x79,0x09}; //输出亮度从低到高
  15. unsigned char key_value;  
  16. unsigned char key_flag;
  17. bit  busy;
  18. unsigned char key_scan(void);
  19. void Wait()
  20. {
  21.     while (!(I2CMSST & 0x40));
  22.     I2CMSST &= ~0x40;
  23. }
  24. void Start()
  25. {
  26.     I2CMSCR = 0x01;                             //发送START命令
  27.     Wait();
  28. }
  29. void SendData(char dat)
  30. {
  31.     I2CTXD = dat;                               //写数据到数据缓冲区
  32.     I2CMSCR = 0x02;                             //发送SEND命令
  33.     Wait();
  34. }
  35. void RecvACK()
  36. {
  37.     I2CMSCR = 0x03;                             //发送读ACK命令
  38.     Wait();
  39. }
  40. char RecvData()
  41. {
  42.     I2CMSCR = 0x04;                             //发送RECV命令
  43.     Wait();
  44.     return I2CRXD;
  45. }
  46. void SendACK()
  47. {
  48.     I2CMSST = 0x00;                             //设置ACK信号
  49.     I2CMSCR = 0x05;                             //发送ACK命令
  50.     Wait();
  51. }
  52. void SendNAK()
  53. {
  54.     I2CMSST = 0x01;                             //设置NAK信号
  55.     I2CMSCR = 0x05;                             //发送ACK命令
  56.     Wait();
  57. }
  58. void Stop()
  59. {
  60.     I2CMSCR = 0x06;                             //发送STOP命令
  61.     Wait();
  62. }
  63. void I2C_Init(void)
  64. {
  65.         P_SW2  |= 0x80;
  66.         I2CCFG  = 0xe0;                              //使能I2C主机模式
  67.         I2CMSST = 0x00;
  68.         SDA     = 1;
  69.         SCL     = 1;
  70. //        P_SW2  |= 0x00;                               //SCL/P1.5, SDA/P1.4        
  71.         P_SW2  |= 0x10;                               //SCL_2/P2.5, SDA_2/P2.4
  72. //  P_SW2  |= 0x30;                               //SCL_4/P3.2, SDA_4/P3.3
  73. }
  74. void ET6226_sendbyte(unsigned char add,unsigned char dat)
  75. {
  76.         char sfr_temp = P_SW2;
  77.         P_SW2 |= 0x80;               
  78.         Start();                                   //发送起始命令
  79.         SendData(add);               //发送控制地址
  80.         RecvACK();
  81.         SendData(dat);               //发送开显示指令
  82.         RecvACK();
  83.         Stop();
  84.         P_SW2 = sfr_temp;        
  85.         delay_ms(20);
  86. }
  87. void INT3_Isr() interrupt 11
  88. {
  89.         unsigned char key_code;
  90.         char sfr_temp = P_SW2;
  91.         LED_COMM = 0;        
  92.         P_SW2 |= 0x80;        
  93.         Start();                                    //发送起始命令
  94.         SendData(ET6226_KEYBOARD_BASE);                             //发送设备地址+写命令
  95.         RecvACK();
  96.         key_code =  RecvData();
  97.         SendNAK();
  98.         //RecvACK();
  99.         Stop();
  100.         P_SW2 = sfr_temp;        
  101.         if (key_code&0x40)
  102.         {            
  103.                 key_value =  key_code;  
  104.                 key_flag = 2;
  105.         }   
  106.         LED_COMM = 1;
  107. }
  108. unsigned char key_scan(void)
  109. {        
  110.         unsigned char key_code;
  111.         char sfr_temp = P_SW2;
  112.         P_SW2 |= 0x80;        
  113.         if(KEY_INT == 0)
  114.         {        
  115.                 Start();                                    //发送起始命令
  116.                 SendData(ET6226_KEYBOARD_BASE);                             //发送设备地址+写命令
  117.                 RecvACK();
  118.                 key_code =  RecvData();
  119.                 SendNAK();
  120.                 Stop();
  121.                 P_SW2 = sfr_temp;               
  122.                 if (key_code&0x40){   
  123.                         //key_code <<= 1;               
  124.                         //key_code &=  0x7F;  
  125.                 }
  126.         }
  127.         return         key_code;
  128. }
  129. extern void ET6226_Init(void)
  130. {
  131.         I2C_Init();
  132.         delay_ms(5);
  133.         ET6226_sendbyte(ET6226_DCTRL_BASE,ET6226_BRIGHT_LEVEL[5]);   //显示亮度最亮
  134.         ET6226_sendbyte(ET6226_DISPLAY_BASE1,0xFF);   //小7键背光
  135.         ET6226_sendbyte(ET6226_DISPLAY_BASE2,0xFF);   //启停键背光
  136.         
  137.         Start();                                    //发送起始命令
  138.         SendData(ET6226_KEYBOARD_BASE);                             //发送设备地址+写命令
  139.         RecvACK();
  140.         RecvData();
  141.         SendNAK();
  142.         Stop();         
  143.         
  144.         P_SW2 |= 0x80;
  145.         INTCLKO |= 0x20;                              //使能INT3中断        
  146. }
复制代码




睁开眼睛做场梦~~~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:61
  • 最近打卡:2025-06-12 11:08:32

12

主题

25

回帖

416

积分

中级会员

积分
416
发表于 2025-5-19 08:41:52 | 显示全部楼层
硬件I2C驱动TM1650成功了吗
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:166
  • 最近打卡:2025-06-16 09:42:32

122

主题

162

回帖

365

积分

中级会员

积分
365
发表于 2025-5-19 09:37:52 | 显示全部楼层
给你个我实验成功的代码,不过用的是89C52.
//功能:按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();
    }
}




//TM1650 C文件
#include<reg52.h>
#include"tm1650.h"
void Delay_us(uint i) //us延时
{
for(;i>0;i--)
{
_nop_();
// _nop_();
// _nop_();
// _nop_();
// _nop_();
}
}
void I2CStart(void) //开始信号
{
CLK_H;
DIO_H;
Delay_us(5);
DIO_L;
}
void I2Cask(void) //ACK信号
{
uchar timeout = 1;
CLK_H;
Delay_us(5);
CLK_L;
while((DIO)&&(timeout<=100))
{
  timeout++;
}
Delay_us(5);
CLK_L;
}
void I2CStop(void) //停止信号
{
CLK_H;
DIO_L;
Delay_us(5);
DIO_H;
}
void I2CWrByte(uchar oneByte) //写一个字节高位在前,低位在后
{
uchar i;
CLK_L;
Delay_us(1);
for(i=0;i<8;i++)
{
oneByte = oneByte<<1;
DIO = CY;
CLK_L;
Delay_us(5);
CLK_H;
Delay_us(5);
CLK_L;
}
}
uchar Scan_Key(void)   // 按键扫描
{
uchar i;
uchar rekey;
I2CStart();
I2CWrByte(0x49);//读按键命令
I2Cask();
//DIO_H;
for(i=0;i<8;i++)
{
   CLK_H;
   rekey = rekey<<1;
   if(DIO)
   {
    rekey++;
   }
   Delay_us(5);
   CLK_L;
}
I2Cask();
I2CStop();
return(rekey);
}
void TM1650_Set(uchar add,uchar dat) //数码管显示
{
//写显存必须从高地址开始写
I2CStart();
I2CWrByte(add); //第一个显存地址
I2Cask();
I2CWrByte(dat);
I2Cask();
I2CStop();
}



//TM1650 H文件
#ifndef __TM1650_H__
#define __TM1650_H__
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
sbit CLK = P1^0;
sbit DIO = P1^1;
#include<reg52.h>
#define CLK_H  CLK = 1
#define CLK_L  CLK = 0
#define DIO_H  DIO = 1
#define DIO_L  DIO = 0
void TM1650_Set(uchar add,uchar dat);
uchar Scan_Key(void);
#endif


132146zddkkd4ujb4k2u41.png
132123ainhqhcbq8f2afw8.png
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-06-15 15:05:22
已绑定手机

142

主题

1688

回帖

2559

积分

金牌会员

积分
2559
发表于 2025-5-26 14:48:27 来自手机 | 显示全部楼层
zhaoyun189911 发表于 2025-4-10 22:11
怎样  有进展了没有? 我也一直想尝试用硬件IIC驱动tm01650  苦于一直没有成功
...

好像1637之类的硬件iic有点问题。。之前在哪里看到过
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:85
  • 最近打卡:2025-06-15 20:21:30

5

主题

25

回帖

69

积分

注册会员

积分
69
发表于 2025-5-26 15:09:11 | 显示全部楼层
vb2*** 发表于 2025-5-26 14:48
好像1637之类的硬件iic有点问题。。之前在哪里看到过

是么 我试验几次一直没有成功 也不知道是不是无能力不行
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-06-15 15:05:22
已绑定手机

142

主题

1688

回帖

2559

积分

金牌会员

积分
2559
发表于 2025-5-26 15:21:56 来自手机 | 显示全部楼层
zhaoyun189911 发表于 2025-5-26 15:09
是么 我试验几次一直没有成功 也不知道是不是无能力不行

用io口的没问题。但是用iic硬件的就有点问题。
有人强行弄好过。但是现实有bug
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-16 12:53 , Processed in 0.140306 second(s), 114 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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