搜索
bottom↓
回复: 20

折腾xx1640驱动共阳数码管,显示只一次正常,刷新就乱码!

[复制链接]

出0入0汤圆

发表于 2019-10-30 20:33:37 | 显示全部楼层 |阅读模式
网上找的1640程序,多是  驱动共阴数码管的,客户要共阳!
找到个转换程序套上,可以正常显示0~9~abcd,但是,更新第二次显示,就是乱码,单独显示一次就正常???
折腾一天了,非常抓狂了???

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2019-10-30 20:34:37 | 显示全部楼层
源码如下


#include<reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit SPK = P2^5;//BELL

sbit CLK = P1^6;//1640时钟线      1640接16个共阳8字管
sbit DIO = P1^5;//1640数据线

//命令说明                    
#define write_mode_z  0x40  //采用自动地址加一方式写显示缓存
#define write_mode_g  0x44  //地址固定模式
//#define read_mode   0x42  //键盘扫描模式(1640无Key)
#define start_addr    0xc0  //起始地址
#define disp_mode     0x8a  //显示控制命令:开启+亮度(低3位)
#define close_disp    0x80  //关显示bit-3

uchar code num[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,    0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,};
//数码管码           0,1,2,3,4,5,6,7,8,9,  A,b,C,d,E,F
uchar SEG[16]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,    0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,};
//显示缓存:对应[0]~[15]共16个8字管
//******************************************************************
//  延时1ms程序:    IAP15W413AS_TSSOP28_IRC11.0592Mhz_1ms:(10,181)
//------------------------------------------------------------------
void Delay(uint count)  //while(1){IO=~IO;Delay(1);}//Test!
{
    uchar a,b;
    while(count--!=0)
    {   for(a=0;a<10;a++)
        {
            //WDT_CONTR=0x3c;   //喂狗
            for(b=0;b<155;b++);
}   }   }
//void delay_us(uint us){while(us--);}
void delay_us(uchar delay_time) //如果信号引脚接上电容 需增加延时
{
    uchar i=delay_time;
   
    while(i--)
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    }
}
//********************************************************************
void init_1640(void)
{
    CLK=0;delay_us(1);
    DIO=1;delay_us(1);
    CLK=1;delay_us(1);
    DIO=0;delay_us(1);
}
//********************************************************************
void start_1640(void)
{
    CLK=0;delay_us(1);
    DIO=1;delay_us(1);
    CLK=1;delay_us(1);
    DIO=0;delay_us(1);
}
//********************************************************************
void stop_1640(void)
{
    CLK=0;delay_us(1);
    DIO=0;delay_us(1);
    CLK=1;delay_us(1);
    DIO=1;delay_us(1);
}
//********************************************************************
void send_1640(unsigned char in_data)
{
    unsigned char i=0;
   
    CLK = 0;
    delay_us(1);
   
    for( i=0;i<8;i++)
    {
        if(in_data&0x01)
        {
            DIO = 1;
            delay_us(1);
        }
        else
        {
            DIO = 0;
            delay_us(1);
        }
        CLK = 1;
        delay_us(1);
        in_data>>=1;
        CLK = 0;
        delay_us(1);
    }
}
//********************************************************************
void disp_1640(void)
{
    unsigned char i,j,k,ex_[16];
   
    //---------------------------------
    //共阴AH->BS共阳码(段/位)转换
    //---------------------------------
    for(i=0;i<16;i++)
    {
        k = i/8;
        for(j=0;j<8;j++)
        {
            if(SEG[i] & (0x80>>j) )
               ex_[j+k*8] |= 1<<(i%8);
        }
    }
    //---------------------------------
    start_1640();
    send_1640(write_mode_z);//地址自动增加1模式写显存
    stop_1640();

    start_1640();
    send_1640(start_addr);  //起始地址:从0xC0起
        
    for(i=0;i<16;i++)
    {
        send_1640(ex_[i]);  //写数据
    }
    stop_1640();

    start_1640();
    send_1640(disp_mode);   //控制命令:开显示+亮度
    stop_1640();
}
//********************************************************************
//  Main
//--------------------------------------------------------------------
void main(void)
{
    unsigned char i=0,j=0;
   
    SPK=1;Delay(200);//Test!
    SPK=0;Delay(200);
    SPK=1;Delay(200);
    SPK=0;Delay(200);
   
    init_1640();//初始化
    //---------------------------------
    while(1)
    {
        //---------------------------------
        //以下代码独立可显示   FEdcbA~9~0
        //---------------------------------
        start_1640();
        send_1640(close_disp);//关显示
        stop_1640();
        Delay(100);
        for(i=0;i<16;i++)
            SEG[i] = num[i];//在16个8字管上显示:0~9~AbcdEF
        disp_1640();
        Delay(3000);

        //---------------------------------
        //以下代码独立可显示   FEdcbA~9~0                      单独使用都显示正常,轮流显示,就是乱码了!!!
        //---------------------------------
        start_1640();
        send_1640(close_disp);//关显示
        stop_1640();
        Delay(100);
        
        for(i=0;i<16;i++)
            SEG[i] = num[15-i];//逆序显示:
        disp_1640();
        Delay(3000);
        
        //---------------------------------
        SPK=1;Delay(10);//Test!
        SPK=0;Delay(10);
    }
}

出0入0汤圆

 楼主| 发表于 2019-10-30 20:46:04 | 显示全部楼层
  

屏蔽 while里面的一段,就正常,,,但是数码管显示值,不可能固定,是要不断刷新的啊,,,一刷新要显示其它数据,就成下面状态了:而且,再刷回上次正确数据也不动,固定显示乱码界面:

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2019-10-30 20:56:48 | 显示全部楼层
本帖最后由 wkman 于 2019-10-30 20:59 编辑

屏蔽 while里面的一段,就正常,,,但是数码管显示值,不可能固定,是要不断刷新的啊,,,一刷新要显 ...[/quote]



只要两个轮流显示打开,就固定成这个界面了,,,有使用经验的所说啥问题啊???

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2019-10-30 21:12:10 | 显示全部楼层
客户还关心你用共阴还是共阳的数码管?这个是专门驱动共阴的,程序送数据符合习惯,驱动共阳转换起来本身就麻烦很多

出0入0汤圆

发表于 2019-10-30 21:13:37 | 显示全部楼层
void Start(void)
{
        SCLK_high;
        _delay_us(5);
        DIN_high;
        _delay_us(5);
        DIN_low;
        _delay_us(5);
//        SCLK_low;
//        _delay_us(5);
}
void Stop(void)
{
        SCLK_high;
        _delay_us(5);
        DIN_low;
        _delay_us(5);
        DIN_high;
        _delay_us(5);
}
void TM1640_Write(unsigned char        DATA)                        //写数据函数
{
        unsigned char i;
        for(i=0;i<8;i++)
        {
                SCLK_low;
                if(DATA&0X01)
                        DIN_high;
                else
                        DIN_low;
                _delay_us(5);
                DATA>>=1;
                _delay_us(5);
                SCLK_high;
                _delay_us(5);
        }
}
void Write_COM(unsigned char cmd)                //发送命令字
{
        Start();
        TM1640_Write(cmd);
        Stop();
}
void Write_DATA(unsigned char add,unsigned char DATA)                //指定地址写入数据
{
        Write_COM(0x44);
        Start();
        TM1640_Write(0xc0|add);
        TM1640_Write(DATA);
        Stop();
}
这是我在用的TM1640的底层驱动

出0入0汤圆

 楼主| 发表于 2019-10-30 21:49:55 | 显示全部楼层
JY-MCU 发表于 2019-10-30 21:12
客户还关心你用共阴还是共阳的数码管?这个是专门驱动共阴的,程序送数据符合习惯,驱动共阳转换起来本身就 ...

是客户那边多用共阳,就指定用共阳8字管

出0入0汤圆

 楼主| 发表于 2019-10-30 21:53:58 | 显示全部楼层
JY-MCU 发表于 2019-10-30 21:13
void Start(void)
{
        SCLK_high;

转换为共阳,这这个函数里面实现了,且显示也正常,,,,我遇到的问题是,,,第二次修改更新全部16个数码管的显示值,,实现不了?成乱码了,,,这个我第一次遇到,以前用过很多tm的芯片,都没这次奇怪

    //---------------------------------
    //共阴AH->BS共阳码(段/位)转换
    //---------------------------------
    for(i=0;i<16;i++)
    {
        k = i/8;
        for(j=0;j<8;j++)
        {
            if(buff_ & (0x80>>j) )
               ex_[j+k*8] |= 1<<(i%8);
        }
    }

出0入0汤圆

 楼主| 发表于 2019-10-30 22:09:14 | 显示全部楼层
void Write_DATA(unsigned char add,unsigned char DATA)                //指定地址写入数据
{
        Write_COM(0x44);
        Start();
        TM1640_Write(0xc0|add);
        TM1640_Write(DATA);
        Stop();
}

谢谢,,,试了下,这个  固定地址方式,,,在我的板是没有任何显示???

出0入0汤圆

 楼主| 发表于 2019-10-30 22:24:50 | 显示全部楼层
  更新显示数据,就出现乱码,且再不可变了 ???

本帖子中包含更多资源

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

x

出0入8汤圆

发表于 2019-10-31 08:31:21 来自手机 | 显示全部楼层
1640/1680都用过,你好像没有应答信号!

出0入0汤圆

 楼主| 发表于 2019-10-31 11:41:34 | 显示全部楼层
skype 发表于 2019-10-31 08:31
1640/1680都用过,你好像没有应答信号!

应答什么?

出0入8汤圆

发表于 2019-10-31 22:11:10 | 显示全部楼层
void TM_I2C_Delay(void)
{       
    uint32_t i=5; /* 10us */
    while(i)
    {
        i--;
    }
}



/********************Start函数*************************/
void TM_I2CStart(void)
{
        DIN_H;
    CLK_H;
    TM_I2C_Delay();
        DIN_L;
        TM_I2C_Delay();
        CLK_L;
        //TM_I2C_Delay();
}
/********************Stop函数*************************/
void TM_I2CStop(void)
{
        CLK_L;
        TM_I2C_Delay();
        DIN_L;
        TM_I2C_Delay();
        CLK_H;
        TM_I2C_Delay();
        DIN_H;
        TM_I2C_Delay();
}

/***************发送8bit数据,从低位开始**************/
void TM_Writebyte(uint8_t oneByte)
{
        uint8_t i;
        for(i=0;i<8;i++)
        {
                CLK_L;
                TM_I2C_Delay();
        
                if(oneByte&0x01)
                        DIN_H;
                else
                        DIN_L;
               
                oneByte=oneByte>>1;
                CLK_H;
                TM_I2C_Delay();
        }
        CLK_L;
        //TM_I2C_Delay();
}

///
    TM1640_GPIO_Configuration();
    TM_I2CStart();
    TM_Writebyte(0x40);        //数据命令设置:普通模式,地址自动加一
    TM_I2CStop();

    TM_I2CStart();
    TM_Writebyte(0xc0);        //地址命令设置:初始地址00H
    for(i=0;i<16;i++)        //发送16位显示数据
    {
        TM_Writebyte(Led_data_buf[i]);
    }
    TM_I2CStop();


//
void TM_FAN(uint8_t *p, uint8_t s)
{
        const uint8_t fan_list[]={0x3,0x05,0x06};

    TM_I2CStart();
    TM_Writebyte(0xc0+5);        //地址命令设置:初始地址00H

    TM_Writebyte(*p &0xf8 + fan_list[s & 0x07]);
   
    TM_I2CStop();
}

简单的驱动,没有出现过有乱码

出200入2554汤圆

发表于 2019-11-1 01:36:10 | 显示全部楼层
wkman 发表于 2019-10-30 21:53
转换为共阳,这这个函数里面实现了,且显示也正常,,,,我遇到的问题是,,,第二次修改更新全部16个数 ...

位段操作,你只有 |= 置一,不见 &= 置零,要闹哪样?
之前统一清零了?
用 static 数组了?(只有初始化时清零)

出0入0汤圆

 楼主| 发表于 2019-11-1 09:55:43 | 显示全部楼层
t3486784401 发表于 2019-11-1 01:36
位段操作,你只有 |= 置一,不见 &= 置零,要闹哪样?
之前统一清零了?
用 static 数组了?(只有初始化 ...

多谢回复

在位段切换函数内,ex_数组在定义后,就是全0
unsigned char i,j,k,ex_[16];

然后只做    或操作,是1就赋值,是0还是保持0啊
ex_[j+k*8] |= 1<<(i%8);

,,,再刷新数据,就是一直乱码中

出200入2554汤圆

发表于 2019-11-1 10:04:00 | 显示全部楼层
wkman 发表于 2019-11-1 09:55
多谢回复

在位段切换函数内,ex_数组在定义后,就是全0

没有初始化的局部数组!拿来的自信说全是零。
乱码后大多数笔段点亮就是这个毛病。

至少加上 ={0} 每次强制初始化啊。

出0入0汤圆

 楼主| 发表于 2019-11-1 10:16:20 | 显示全部楼层
t3486784401 发表于 2019-11-1 10:04
没有初始化的局部数组!拿来的自信说全是零。
乱码后大多数笔段点亮就是这个毛病。

  你是对的!!!!   

这句改成这样就好了:  T_T
    unsigned char i,j,k,ex_[16]={0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, };

出0入0汤圆

 楼主| 发表于 2019-11-1 10:22:36 | 显示全部楼层
本帖最后由 wkman 于 2019-11-1 10:29 编辑
skype 发表于 2019-10-31 22:11
void TM_I2C_Delay(void)
{       
    uint32_t i=5; /* 10us */


多谢帮忙回复!
TM_Writebyte(*p &0xf8 + fan_list[s & 0x07]);     这段代码也是  “共阴管切换到共阳管”  功能?



出0入8汤圆

发表于 2019-11-1 11:28:29 | 显示全部楼层
wkman 发表于 2019-11-1 10:22
多谢帮忙回复!
TM_Writebyte(*p &0xf8 + fan_list[s & 0x07]);     这段代码也是  “共 ...

不是,是低三位要修改,而其他位不变。

出0入0汤圆

发表于 2019-11-1 15:34:59 | 显示全部楼层
能正常显示一次,说明共阴转共阳的部分没有问题。问题出现在刷新后,说明在刷新操作中有地方的数据混乱了

出0入0汤圆

 楼主| 发表于 2019-11-1 19:46:08 | 显示全部楼层
rifjft 发表于 2019-11-1 15:34
能正常显示一次,说明共阴转共阳的部分没有问题。问题出现在刷新后,说明在刷新操作中有地方的数据混乱了{: ...

是啊非常低级的错误,,,,幸亏网友指出了,否则又要折腾去打共阴数码管的板了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 06:34

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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