amobbs.com 阿莫电子技术论坛
标题:
HT1621 写数据可以,再读出来就不可以?已附上程序
[打印本页]
作者:
simon09
时间:
2010-6-12 11:59
标题:
HT1621 写数据可以,再读出来就不可以?已附上程序
为什么在写数据到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中,低位在高
}
}
作者:
lgw65
时间:
2010-6-12 14:22
给你我的程序,经过使用的。
//这里是符号对应的显示顺序,也就对应了在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;
}
作者:
simon09
时间:
2010-6-12 14:57
回复【1楼】lgw65
-----------------------------------------------------------------------
以上程序我做过参考, 效果还是一样,我不知道你用的是哪种单片机?
我用的是STC12C5A60S2 的 速度比较快,所以我在延时上是传统51的12倍延时
结果还是一样
比较奇怪的是,其中某一SEG的数据 可以读正确,但是读其他段的数据就不正确了,全是0
作者:
tothen5
时间:
2010-9-9 10:39
我也碰到你同样的问题,就是SEG0的时间能读出来,但其他的都是0
作者:
yukaigogogo
时间:
2013-12-19 10:43
本帖最后由 yukaigogogo 于 2013-12-19 11:09 编辑
rd_dat=rd_dat+(temp_data<<(cnt-1-i));//读数据从低至高,在rd_dat中,低位在高 这一句好难懂
不如用rd_dat |= temp_data << i; //这样出来的数就高位在前了。方便其它程序处理
欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/)
Powered by Discuz! X3.4