数码之家

 找回密码
 立即注册
搜索
查看: 6430|回复: 23

[PIC] tm1650数码管不能显示

[复制链接]
发表于 2019-8-6 12:17:36 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
麻烦高手给看看哪里出问题了,调不出来。
#include<pic.h>
//#include<intrins.h>
__CONFIG(0X3B31);
#define uchar unsigned char
#define uint  unsigned int
#define nop() asm("nop")
void Delay_us(uint i);
#define SCL  RB1        //SHUJU
#define SDA RB2                //SHIZHONG
#define SCL_H  SCL = 1
#define SCL_L  SCL = 0
void Tube_DisNum(uint Num);
#define SDA_H  SDA = 1
#define SDA_L  SDA = 0
void Delay_ms(uint x);
void I2CStart(void);
void I2Cask(void) ;
void I2CStop(void);
void TM1650_Set(uchar add,uchar dat);
void I2CWrByte(uchar oneByte);

//uchar Scan_Key(void);

uchar CODE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0~9显示代码
//uchar CODE[11] = {0xFC,0x84,0xBA,0xAE,0xC6,0x6E,0x7E,0xA4,0xFE,0xEE,0x00}; //0~9显示代码
/******************delay*****************/
void Delay_ms(uint x)
{
        int i,j;
        for(i=0;i<x;i++)
          {
                  for(j=0;j<71;j++);
                 }
}

void Tube_DisNum(uint Num)
{
    uchar Temp[4];

    /*数据分离*/
    Temp[0] = Num%1000/100;
    Temp[1] = Num%100/10;
    Temp[2] = Num%10;
    Temp[3] = Num%10;

    /*显示*/
    TM1650_Set(0x68, CODE[Temp[0]]);
        I2Cask();
        I2CStop();
    TM1650_Set(0x6A, CODE[Temp[1]]);
        I2Cask();
        I2CStop();
    TM1650_Set(0x6C, CODE[Temp[2]]);
        I2Cask();
        I2CStop();
    TM1650_Set(0x6E, CODE[Temp[3]]);
        I2Cask();
        I2CStop();
}


void main()
{
TRISB=0x00;
PORTB=0X00;
        TRISC=0X00;
TRISD=0X00;
Delay_us(150);
//uchar key;

Delay_us(1);
PORTD=0Xff;
Delay_ms(500);
Delay_us(50);
TM1650_Set(0x48,0x31);//为5级亮度,开显示八段显示方式,后一个字节中高位用于亮度,低位用于七段或八段显示方式和开关显示
Delay_us(150);
                                  //如:0x71为七级亮度,八段显示方式,开显示;0x79为为七级亮度,七段显示方式,开显示
TM1650_Set(0x68,CODE[0]);
Delay_us(50);
TM1650_Set(0x6A,CODE[0]);
Delay_us(50);
TM1650_Set(0x6C,CODE[0]);
Delay_us(50);
TM1650_Set(0x6E,CODE[0]);

while(1)
{

Tube_DisNum(22);//随便显示个数

}

}
void Delay_us(uint i) //us延时
{
for(;i>0;i--)
{
nop();
nop();
nop();
nop();
nop();
}
}
void I2CStart(void)//开始信号
{
SCL_H;
Delay_us(5);
SDA_H;
Delay_us(5);
SDA_L;
Delay_us(5);

}

void I2Cask(void) //ACK信号
{
uchar timeout = 1;

SCL_H;
Delay_us(5);
SCL_L;
while((SDA)&&(timeout<=100))
{
  timeout++;
}
Delay_us(5);
SCL_L;
}

void I2CStop(void) //停止信号
{
SCL_H;
Delay_us(5);
SDA_L;
Delay_us(5);
SDA_H;
Delay_us(5);

}
/******************
void I2CWrByte(uchar oneByte) //写一个字节高位在前,低位在后
{
        uchar i;
                SCL_L;
                Delay_us(1);
        for(i=0;i<8;i++)
{
oneByte<<=1;
SDA = CARRY;
SCL_L;
Delay_us(5);
SDA_H;
Delay_us(5);
SCL_L;
}
}
*************/
/*********************/
void I2CWrByte(uchar oneByte) //写一个字节高位在前,低位在后
{
        uchar i;
                SCL_H;
                Delay_us(5);
        //        SDA_H;
        //        Delay_us(1);
        //        SDA_L;
        //        Delay_us(1);
        for(i=0;i<8;i++)
        {
               
                if( oneByte & 0x80 )
                        {
                        SDA_H;
                        SCL_L;
                                Delay_us(10);
                                SCL_H;       
                                Delay_us(10);
                                SCL_L;
       
                Delay_us(5);
                        }
                                else {
                                        SDA_L;
                                SCL_L;
                                Delay_us(10);
                                SCL_H;       
                                Delay_us(10);
                                SCL_L;
                                oneByte <<=1;
                                }
       
        }
               
       
}

/**************************不要了***
uchar Scan_Key(void)  // 按键扫描
{
uchar i;
uchar rekey=0;
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();
}


发表于 2019-8-6 23:02:05 来自手机浏览器 | 显示全部楼层
由于pic单片机没有双向io在读取sda脚信号前必须把sda脚设置成输入
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-7 05:42:41 来自手机浏览器 | 显示全部楼层
mckk520 发表于 2019-8-6 23:02
由于pic单片机没有双向io在读取sda脚信号前必须把sda脚设置成输入

我不需要读取按键,看手册上只是需要设置高低电平啊!
回复 支持 反对

使用道具 举报

发表于 2019-8-7 21:48:39 来自手机浏览器 | 显示全部楼层
qwer1415926 发表于 2019-8-7 05:42
我不需要读取按键,看手册上只是需要设置高低电平啊!

你确定?你在ack信号里面while((SDA)&&(timeout<=100))这句解释一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-8 16:41:02 | 显示全部楼层
mckk520 发表于 2019-8-7 21:48
你确定?你在ack信号里面while((SDA)&&(timeout

读之前改成输入了还是不行
void I2Cask(void) //ACK信号
{
uchar timeout = 1;

SCL_H;
Delay_us(5);
SCL_L;
TRISC2=1;
        Delay_us(25);
while((SDA)&&(timeout<=100))
{
  timeout++;
}
Delay_us(5);
SCL_L;
TRISC2=0;
}
回复 支持 反对

使用道具 举报

发表于 2019-8-9 17:48:43 来自手机浏览器 | 显示全部楼层
你按数据文档来写程序,这个复制的肯定有问题,us延时那里都不对,延时慢了n多倍
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-10 08:32:50 来自手机浏览器 | 显示全部楼层
mckk520 发表于 2019-8-9 17:48
你按数据文档来写程序,这个复制的肯定有问题,us延时那里都不对,延时慢了n多倍 ...

好的谢谢!我去试试
回复 支持 反对

使用道具 举报

发表于 2019-11-28 16:24:41 | 显示全部楼层
想问楼主,您点亮了吗?我最近还是遇到了一样的问题。
回复 支持 反对

使用道具 举报

发表于 2021-4-13 22:41:22 | 显示全部楼层
你好楼主,你这个驱动TM1650问题解决了吗?我现在也出现这个问题
回复 支持 反对

使用道具 举报

发表于 2021-4-14 00:06:50 来自手机浏览器 | 显示全部楼层
600zhang123 发表于 2021-4-13 22:41
你好楼主,你这个驱动TM1650问题解决了吗?我现在也出现这个问题

TM1650我写过,但是芯片是FD650的,没有TM1650的芯片,不知通不通用,反正是看TM1650的手册写的,TM1651倒是保证能用。
回复 支持 反对

使用道具 举报

发表于 2021-4-14 11:08:00 | 显示全部楼层
本帖最后由 inthsunshine 于 2021-4-14 19:45 编辑

这个我点亮过,1650的串口协议和I2C略有不同,可以视为简化版,要注意修改一下, 显示和按键都正常

1.jpg

2.jpg



回复 支持 反对

使用道具 举报

发表于 2021-4-14 18:37:47 | 显示全部楼层
inthsunshine 发表于 2021-4-14 11:08
这个我点亮过,1650的串口协议和I2C不同,要注意修改一下, 显示和按键都正常

大佬请教下,TM1650不是最多只能驱动8段x4位么?
PCB右下的三颗LED你是如何驱动的?
回复 支持 反对

使用道具 举报

发表于 2021-4-14 19:38:29 | 显示全部楼层
本帖最后由 inthsunshine 于 2021-4-14 19:46 编辑
mousebat04 发表于 2021-4-14 18:37
大佬请教下,TM1650不是最多只能驱动8段x4位么?
PCB右下的三颗LED你是如何驱动的? ...

对,最多4位, 如果你需要更多位,可以看看TM1627,最多10位*7段,键盘还带中断输出
这个板子是立创买元件免费领的,原设计是AiP650, 硬件电路一样,我是按TM1650手册写的

右下脚那3个灯,1个电源指示,1个是lock, 1个standby, AiP650手册里有(没找到解释,应该是指示的作用,不是程序驱动的), 但TM1650没这部分电路



回复 支持 反对

使用道具 举报

发表于 2021-4-14 21:04:56 | 显示全部楼层
inthsunshine 发表于 2021-4-14 19:38
对,最多4位, 如果你需要更多位,可以看看TM1627,最多10位*7段,键盘还带中断输出
这个板子是立创买元件 ...

原来如此,谢谢大佬指点。我还以为有新玩法。
回复 支持 反对

使用道具 举报

发表于 2021-4-15 10:31:19 | 显示全部楼层
inthsunshine 发表于 2021-4-14 11:08
这个我点亮过,1650的串口协议和I2C略有不同,可以视为简化版,要注意修改一下, 显示和按键都正常

你好,请问可以参考下代码吗?
回复 支持 反对

使用道具 举报

发表于 2021-4-15 14:33:48 | 显示全部楼层
本帖最后由 inthsunshine 于 2021-4-15 14:36 编辑

void I2CWrByte(uchar oneByte)
这个函数的时序有问题,建议检查一下

在SDA = CARRY;已经输出后(CARRY是pic的进位吗?)
正常应该先延时,再置SCL=1, 这时SDA的电平被TM1650读取,然后延时,恢复SCL=0. 准备下一位发送

但你这里,又出现SDA_H(又把SDA置1)是什么意思?(SCL_H的笔误?)

PS: 回复后才发现是老贴,估计作者早就搞定了:lol:
回复 支持 反对

使用道具 举报

发表于 2021-4-15 17:54:44 | 显示全部楼层
inthsunshine 发表于 2021-4-15 14:33
void I2CWrByte(uchar oneByte)
这个函数的时序有问题,建议检查一下

能留个联系加你请教下吗?
回复 支持 反对

使用道具 举报

发表于 2021-4-15 19:02:53 | 显示全部楼层
600zhang123 发表于 2021-4-15 17:54
能留个联系加你请教下吗?

在这里说吧,我不大习惯私聊,见谅
回复 支持 反对

使用道具 举报

发表于 2021-4-15 21:25:37 | 显示全部楼层
inthsunshine 发表于 2021-4-15 19:02
在这里说吧,我不大习惯私聊,见谅

你好,我想请教下,在给1650发指令时,发出的脉冲不对,是什么原因呢?
回复 支持 反对

使用道具 举报

发表于 2021-4-17 17:29:19 | 显示全部楼层
mousebat04 发表于 2021-4-14 18:37
大佬请教下,TM1650不是最多只能驱动8段x4位么?
PCB右下的三颗LED你是如何驱动的? ...

最多32个点,  自己看吧, 前面第一上,或者哪里不要的点移到别的批示灯上.
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-5-6 20:12 , Processed in 0.187201 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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