搜索
bottom↓
回复: 5

HT1621 写数据可以,再读出来就不可以?已附上程序

[复制链接]

出0入0汤圆

发表于 2010-6-12 11:59:02 | 显示全部楼层 |阅读模式
为什么在写数据到HT1621就可以,再读出来就全是零,请问这个情况该怎么样解决
   通过看英文数据手册,在先读后写的模式下,在5V的驱动下,RD脚周期大概是8us  ,为什么就读不出来数据呢?
        ht1621_cs=0;
          ht1621wr_data(0xa0,3);         //写入命令标志101,读后写数据方式
          ht1621wr_data(i,6);         //发读数据地址,
        ht1621rd_data(4);                  //读4bit数据

  void ht1621rd_data(unsigned char cnt)
{
          unsigned char i;
        rd_dat=0;
        ht1621_wr=1;
          for (i=0;i<cnt;i++)
          {   
                ht1621_rd=0;
                _Nop();
                _Nop();
                _Nop();
                _Nop();
        //        _Nop();       
        //        _Nop();
        //        _Nop();       
        //                        _Nop();
        //        _Nop();
        //                        _Nop();
        //        _Nop();
                ht1621_rd=1;
                _Nop();
        //        _Nop();
        //        _Nop();
        //        _Nop();
        //        _Nop();       
        //        _Nop();
        //        _Nop();       
        //                        _Nop();
        //        _Nop()
                rd_dat<<=1;
                if(ht1621_dat)
                {rd_dat=rd_dat+1;
                  }         
                                 _Nop();
                _Nop();
        //        rd_dat=rd_dat+(temp_data<<(cnt-1-i));//读数据从低至高,在rd_dat中,低位在高

          }
}

出0入0汤圆

发表于 2010-6-12 14:22:51 | 显示全部楼层
给你我的程序,经过使用的。

//这里是符号对应的显示顺序,也就对应了在ht1621B数据寄存器内的位置
#define                        _lcd_BUSY                 0      
#define                        _lcd_AC                        1             
#define                        _lcd_PLUS                2      
#define                        _lcd_F1                        3
#define                        _lcd_ERROR           4
#define                        _lcd_DC                        5
#define                        _lcd_MINUS                6
#define                        _lcd_F2                        7
#define                        _lcd_DOT0                12
#define                        _lcd_AUTO                20
#define                        _lcd_RUN                        24
#define                        _lcd_PAUSE                25
#define                        _lcd_DOT1                26
#define                        _lcd_COLON0           27
#define                        _lcd_DOT2                32
#define                        _lcd_STOP                40
#define                        _lcd_KPA                        44
#define                        _lcd_SETUP                45
#define                        _lcd_DOT3                46
#define                        _lcd_COLON1                47
#define                        _lcd_DOT4                52
#define                        _lcd_KG                        60
#define                        _lcd_MM                        64
#define                        _lcd_KM                        65
#define                        _lcd_L                        66
#define                        _lcd_M3                        67
#define                        _lcd_DB                        68
#define                        _lcd_PERCENT        69
#define                        _lcd_OHOM                70
#define                        _lcd_DEGREE                71
#define                        _lcd_A                        72
#define                        _lcd_V                        73
#define                        _lcd_MHZ                         74
#define                        _lcd_KW                        75
#define                        _lcd_MA                        76
#define                        _lcd_MV                        77
#define                        _lcd_KHZ                        78
#define                        _lcd_W                        79
#define                        _lcd_NG                        80
#define                        _lcd_OK                        81
#define                        _lcd_RX                        82
#define                        _lcd_TX                        83
#define                        _lcd_FM                        84
#define                        _lcd_PM                        85
#define                        _lcd_AM                        86
#define                        _lcd_CARD                87
#define                        _lcd_AT3                        88
#define                        _lcd_AT2                        89
#define                        _lcd_AT1                        90
#define                        _lcd_AT0                        91
#define                        _lcd_LOCK                95
#define                        _lcd_BELL                103
#define                        _lcd_COLON2                111
#define                        _lcd_BAT                        119
#define                        _lcd_MAX                        124
#define                        _lcd_MIN                        125
#define                        _lcd_CH                        126
#define                        _lcd_FAULT                127
       

//ht1621控制位(液晶模块接口定义,根据自已的需要更改)
sbit ht1621_dat=P1^0; //ht1621数据引脚
sbit ht1621_wr=P1^1;    //ht1621写引脚
sbit ht1621_rd=P1^2;    //ht1621读引脚
sbit ht1621_cs=P1^3;    //ht1621使能引脚  
   
//unsigned char i,j;
unsigned char rd_dat;//存储读取的数据,高位在高。
                                                        //可存储4位或8位ht1621的数据

#define _Nop() _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
#define BIAS   0x52 //0b1000 0101 0010  1/3duty 4com

#define SYSDIS 0X00    //0b1000 0000 0000  关振系统荡器和LCD偏压发生器
#define SYSEN  0X02    //0b1000 0000 0010 打开系统振荡器

#define LCDOFF 0X04    //0b1000 0000 0100  关LCD偏压
#define LCDON  0X06    //0b1000 0000 0110  打开LCD偏压

#define XTAL   0x28    //0b1000 0010 1000 外部接时钟
#define RC256  0X30    //0b1000 0011 0000  内部时钟

#define TONEON  0X12    //0b1000 0001 0010  打开声音输出
#define TONEOFF 0X10    //0b1000 0001 0000 关闭声音输出

#define WDTDIS  0X0A //0b1000 0000 1010  禁止看门狗

//定义两个数组 ,用于显示阿拉伯数字
const unsigned char BUFFER0[10]={0xD7,0x06,0xE3,0xA7,0x36,0xB5,0xF5,
                                0x07,0xF7,0xB7};
const unsigned char BUFFER1[10]={0xEB,0x60,0xC7,0xE5,0x6C,0xAD,0xAF,
                                0xE0,0xEF,0xED};

/******************************************************
1毫秒延时子程序,最大65530MS
*******************************************************/
delayms(unsigned int ms)
{                                                       
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i< 85; i++)
                {
                        _nop_();_nop_();_nop_();_nop_();
                }
        }
}

/******************************************************
写数据函数,Data 为待传送数据,数据传送为高位在前,cnt为传送数据位数,
也可用于发送命令
*******************************************************/
void ht1621wr_data(unsigned char Data,unsigned char cnt)
{
          unsigned char i;
          for (i=0;i<cnt;i++)
          {   
                ht1621_wr=0;
                ht1621_dat=Data&0x80;        
                ht1621_wr=1;
                Data<<=1;  
          }
}

/******************************************************
读数据函数,cnt为接收数据位数, 读出数据存储于rd_dat
*******************************************************/
void ht1621rd_data(unsigned char cnt)
{
          unsigned char i,temp_data;
        rd_dat=0;
          for (i=0;i<cnt;i++)
          {   
                ht1621_rd=0;
                ht1621_rd=1;
                temp_data=ht1621_dat;      
                rd_dat=rd_dat+(temp_data<<(cnt-1-i));//读数据从低至高,在rd_dat中,低位在高
          }
}

/********************************************************
函数名称:void ht1621wr_cmd(uchar Cmd)
功能描述: ht1621命令写入函数
参数说明:Cmd为写入命令数据
说    明:写入命令标识位100
********************************************************/
void ht1621wr_cmd(unsigned char Cmd)
{
          ht1621_cs=0;
          ht1621wr_data(0x80,4); //写入命令标志100
          ht1621wr_data(Cmd,8); //写入命令数据
          ht1621_cs=1;
}

/********************************************************
h1621初始化
********************************************************/
void ht1621_Init(void)
{
          ht1621_cs=1;
          ht1621_wr=1;
          ht1621_dat=1;
          delayms(200);      //延时使LCD工作电压稳定
          ht1621wr_cmd(BIAS);
          ht1621wr_cmd(RC256);     //使用内部振荡器
          ht1621wr_cmd(SYSDIS);
          ht1621wr_cmd(WDTDIS);
          ht1621wr_cmd(SYSEN);
          ht1621wr_cmd(LCDON);
}


/********************************************************
//向液晶写一个符号
//name:可直接写0~127的整数,也可以写程序开始定义的标号,如:_lcd_BUSY
//display:符号是否显示,1:显示,0:不显示.
********************************************************/
void lcd_char(unsigned char name,unsigned char display)
{
        unsigned char i,j;
        i= (name/4)<<2; //存储器地址,从高位发6位地址,所以要左移2位
        j= 0x01<<(3-name%4);  //存储器bit位0123变为1248,便于下面运算

        ht1621_cs=0;
          ht1621wr_data(0xa0,3); //写入命令标志101,读后写数据方式
          ht1621wr_data(i,6); //发读数据地址,
        ht1621rd_data(4);  //读4bit数据
        //编辑数据

        if (display==0)//关闭该段显示
        {
                if((rd_dat & j)==j)        //该段处于显示状态
                {rd_dat =rd_dat-j;}
        }
        else  //打开该段显示
        {
                if((rd_dat & j)==0)        //该段处于未显示状态
                {rd_dat =rd_dat+j;}
        }

          ht1621wr_data(rd_dat<<4,4); //将数据写回存储器,发rd_dat高位,所以要左移4位
        ht1621_cs=1;
}


/********************************************************
清除全部液晶的显示
/********************************************************/
void lcd_clr()
{       
        unsigned char i;
        ht1621_cs=0;
          ht1621wr_data(0xa0,3); //写入命令标志101,写数据方式
          ht1621wr_data(0,6); //发写数据地址,
        for ( i=0; i<16;i++)
        {
                  ht1621wr_data(0,8); //将所有128bit位写0
        }
        ht1621_cs=1;
}

/********************************************************
向液晶的数字处写一个0~9的数  
数字位置为大数码的左至右为0~5,小数码的右至左为6~9;
number:欲显示的数 0~9
position:欲显示的数字位置
display:显示开关,1: 显示该数字, 0: 关闭该数字显示,
********************************************************/
void lcd_number(unsigned char number,unsigned char position,unsigned char display)
{
        unsigned char num_addr;
        unsigned char i;

        switch (position)  //取存储器地址
        {
                case 0:
                {        num_addr=8;            }break;
                case 1:
                {        num_addr=16;        }break;
                case 2:
                {        num_addr=28;        }break;
                case 3:
                {        num_addr=36;        }break;
                case 4:
                {        num_addr=48;        }break;
                case 5:
                {        num_addr=56;        }break;
                case 6:
                {        num_addr=92;        }break;
                case 7:
                {        num_addr=100;        }break;
                case 8:
                {        num_addr=108;        }break;
                case 9:
                {        num_addr=116;        }break;
        }

        i= (num_addr/4)<<2; //存储器地址,从高位发6位地址,所以要左移2位

        //读8bit数据
        ht1621_cs=0;
          ht1621wr_data(0xc0,3); //写入命令标志110,读数据方式
          ht1621wr_data(i,6); //发读数据地址,
        ht1621rd_data(8);  //读8bit数据
        ht1621_cs=1;
       
        //编辑数据
        if (position<6)//大数码
        {
        rd_dat=rd_dat&0x08; //清除该段显示,保留小数点
//rd_dat=0;
                if (display!=0)//打开该段显示
                {
                        rd_dat=rd_dat|BUFFER0[number];
                }
        }
        else//小数码
        {
                rd_dat=rd_dat&0x10; //清除该段显示,保留小数点
//rd_dat=0;
                if (display!=0)//打开该段显示
                {
                        rd_dat=rd_dat|BUFFER1[number];
                }
        }

        //写8bit数据
        ht1621_cs=0;
          ht1621wr_data(0xa0,3); //写入命令标志101,写数据方式
          ht1621wr_data(i,6); //发写数据地址,
          ht1621wr_data(rd_dat,8); //将数据写回存储器
        ht1621_cs=1;       
}

出0入0汤圆

 楼主| 发表于 2010-6-12 14:57:16 | 显示全部楼层
回复【1楼】lgw65
-----------------------------------------------------------------------

以上程序我做过参考,  效果还是一样,我不知道你用的是哪种单片机?
   我用的是STC12C5A60S2 的 速度比较快,所以我在延时上是传统51的12倍延时
    结果还是一样
比较奇怪的是,其中某一SEG的数据 可以读正确,但是读其他段的数据就不正确了,全是0

出0入0汤圆

发表于 2010-9-9 10:39:25 | 显示全部楼层
我也碰到你同样的问题,就是SEG0的时间能读出来,但其他的都是0

出0入0汤圆

发表于 2013-12-19 10:43:49 | 显示全部楼层
本帖最后由 yukaigogogo 于 2013-12-19 11:09 编辑

rd_dat=rd_dat+(temp_data<<(cnt-1-i));//读数据从低至高,在rd_dat中,低位在高   这一句好难懂
不如用rd_dat |= temp_data << i; //这样出来的数就高位在前了。方便其它程序处理
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 ( 公安交互式论坛备案:44190002001997 粤ICP备09047143号 )

GMT+8, 2022-7-1 06:47

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

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