51单片机,读写IIC总线,1602LCD显示.结果乱码

//片头申明#include<AT89X52.h>//调用51单片机的头文件#defineucharunsignedchar#defineuintunsignedint/... //片头申明
#include <AT89X52.h> //调用51单片机的头文件
#define uchar unsigned char
#define uint unsigned int

/******IIC模块************/

//申明总线
sbit SCL=P1^5;
sbit SDA=P1^4;

//定义全局变量
uchar read_buf; //定义一个寄存器用来暂存读出的数据

//微秒延时函数
void delayus(uint xus)
{
int s;
for(s=0;s<xus;s++);
}

//定义延时函数
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}

//开始信号子程序
void Start()
{
SDA=1;
delayus(1);
SCL=1;
delayus(1);
SDA=0;
delayus(1);
}

//终止信号子程序
void Stop()
{
SDA=0;
delayus(1);
SCL=1;
delayus(1);
SDA=1;
}

//发送应答子程序
void Ack() //读数据时用,主机发从机
{
SDA=0;
delayus(1);
SCL=1;
delayus(1);
SCL=0;
delayus(1);
SDA=1;
delayus(1);
}

//发送非应答子程序
void NoAck() //读数据时用
{
SDA=1;
delayus(1);
SCL=1;
delayus(1);
SCL=0;
delayus(1);
}

//应答检测子程序
bit TestAck() /*主器件将SDA置1,完了看从器件有没有讲SDA拉低,SDA=0说明从器件应答了 发数据时用 主机发从机*/
{
bit Error_Bit;
SDA=1;
delayus(1);
SCL=1;
delayus(1);
Error_Bit=SDA;
delayus(1);
SCL=0;
delayus(1);
return(Error_Bit); //若响应 返回0
}

//写一个字节数据子程序,可以不带返回值,一位一位写给SDA
void write_bit(uchar input) //主机写入数据input
{
uchar t;
for(t=8;t!=0;t--)
{
input=input<<1; //将首位移入寄存器CY
SCL=0;
delayus(1);
SDA=CY;
SCL=1;
delayus(1);
SCL=0;
delayus(1);
}
}

//读出一个字节,不带参数 有返回值
uchar read_bit()
{
uchar t,rbyte = 0;
for(t=8;t>0;t--)
{
SCL=1;
delayus(1);
rbyte=rbyte<<1; //将rbyte移位
delayus(1);
rbyte=rbyte|((uchar)(SDA)); //每次将SDA(一位)给rbyte
SCL=0;
delayus(1);
}
return(rbyte); //在主函数中返回值rbyte
}

void write_AT24C02(uchar Address,uchar Databuf) //写入一个字节的数据到AT24C02
{
Start(); //IIC启动信号
write_bit(0xA0); //发送AT24C02的器件地址和写信号 0x1010
TestAck();
write_bit(Address); //发送地址
TestAck();
write_bit(Databuf); //发送数据
TestAck();
Stop(); //产生IIC停止信号
}

uint ReadAT24C02(unsigned char Address) //从AT24C02读出一个字节(选择AT24C02的任何一个地址来读)
{

Start(); //IIC启动信号
write_bit(0xA0); //发送AT24C02的器件地址和写信号
TestAck();
write_bit(Address); //发送地址
TestAck();
Start(); //IIC启动信号
write_bit(0xA1); //发送AT24C02的器件地址和读信号
TestAck();
read_buf=read_bit();//读一个字节数据
NoAck();
Stop(); //产生IIC停止信号
return(read_buf); //将读出数据返回
}
//主函数
void main()
{
uchar shi,ge;
write_AT24C02(0x00,0x07);
ReadAT24C02(0x00);
shi=read_buf/16;
ge=read_buf%16;
init();
write_com(0x80);
busy();
write_date(shi);
write_com(0x81);
busy();
write_date(ge);
while(1);
}
展开
 我来答
jmhyys
2015-01-13 · TA获得超过524个赞
知道小有建树答主
回答量:1052
采纳率:62%
帮助的人:284万
展开全部
write_date(shi); write_date(ge);

是不是这两个地方不对啊,shi,ge这两个数转换成ASII值之后再传给屏才能正常显示吧 ?
追问

感谢你的回答~ 

按你所说我做了修改

write_date(read_buf/10+'0');

busy();

write_com(0x81);

busy();

write_date(read_buf%10+'0');

busy();

write_com(0x82);

busy();

write_date('2');


第三位显示2是为了验证LCD函数的正确性。

但是并没有得到想要的结果(072)。o_O

追答
你按10进制数表示?还是按16进制数表示?
10进制:read_buf/100,read_buf/10,read_buf%10
16进制:read_buf/0x10,read_buf%0x10
你那个出现了I大写字符就是这个原因
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式