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

2020-01-12 17:17发布

网上找的1640程序,多是  驱动共阴数码管的,客户要共阳!
找到个转换程序套上,可以正常显示0~9~abcd,但是,更新第二次显示,就是乱码,单独显示一次就正常???
折腾一天了,非常抓狂了???
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
21条回答
wkman
2020-01-12 18:23
源码如下


#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);
    }
}

一周热门 更多>