写入数据24c256然后再读出来,液晶显示的是乱码,(液晶显示部分没问题)程序已付在上面。希望大虾解决下。本人怀疑是不是24c256的程序部分出了问题?如果是的话,改怎么修改?谢谢!
程序如下:
#include <reg52.h>
#include <intrins.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCL = P1^5; //I2C时钟
sbit SDA = P1^6; //I2C数据/地址
void I2C_start()
{
SCL = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
SDA = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SDA = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
void I2C_writebyte(unsigned char dat)
{
unsigned char i,temp;
temp=dat;
for(i = 0;i<8;i++)
{
SCL = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
SDA = temp&0x80;
temp=temp<<1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
SCL = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
unsigned char I2C_readbyte()
{
unsigned char dat,i;
SCL = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
SDA = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
for(i = 0;i<8;i++)
{
SCL = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
dat=dat<<1;
if(SDA)dat++;
SCL = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
SCL = 0;
return(dat);
}
void I2C_response()
{
unsigned char i = 0;
SCL = 1;
while((SDA == 1)&&(i<150))i++;
SCL = 0;
}
void I2C_stop()
{
SCL = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
SDA = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SDA = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL = 0;
}
void delay_I2C()
{
int i;
for(i=0;i<1100;i++)_nop_();
}
void I2C_write_byte(int addr1,int addr2,unsigned char dat) //在指定地址写一位数据
{
I2C_start();
I2C_writebyte(0xa0);
I2C_response();
I2C_writebyte(addr1);
I2C_response();
I2C_writebyte(addr2);
I2C_response();
I2C_writebyte(dat);
I2C_response();
I2C_stop();
}
unsigned char I2C_read_byte(int addr1,int addr2)//从指定地址读一位数据
{
I2C_start();
I2C_writebyte(0xa0);
I2C_response();
I2C_writebyte(addr1);
I2C_response();
I2C_writebyte(addr2);
I2C_response();
I2C_start();
I2C_writebyte(0xa1);
I2C_response();
return(I2C_readbyte());
I2C_stop();
}
sbit LCM_E=P3^5;//定义接口
sbit LCM_RW=P3^6;
sbit LCM_RS=P3^7;
#define LCM_Data P2//数据接口
void LCM_WriteData(uchar WDLCM);
void LCM_WriteCommand(uchar WCLCM,BuysC);
uchar LCM_ReadData(void);
uchar LCM_ReadStatus(void);
void LCM_Init(void);
void DisplayOneChar(uchar X, uchar Y, uchar DData);
void DisplayListChar(uchar X, uchar Y, uchar code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
uchar code uctech[] = {"1602A"};
uchar code net[] = {"www.52c51.com"};
/****************************1602A写数据函数**************************/
/*函数原型:void LCM_WriteData(uchar WDLCM)
/*函数功能:1602A写数据
/*输入参数:要写入的数据
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void LCM_WriteData(uchar WDLCM)
{
LCM_ReadStatus();//检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0;//若晶振速度太高可以在这后加小的延时
LCM_E = 0;//延时
LCM_E = 1;
}
/****************************1602A写指令函数**************************/
/*函数原型:void LCM_WriteCommand(uchar WCLCM,BuysC)
/*函数功能:1602A写指令
/*输入参数:要写入的指令
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void LCM_WriteCommand(uchar WCLCM,BuysC)//BuysC为0时忽略忙检测
{
if (BuysC) LCM_ReadStatus();//根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}
/****************************1602A读数据函数**************************/
/*函数原型:uchar LCM_ReadData(void)
/*函数功能:1602A读数据
/*输入参数:无
/*输出参数:1602A返回的数据
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
uchar LCM_ReadData(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}
/****************************1602A读状态函数**************************/
/*函数原型:uchar LCM_ReadData(void)
/*函数功能:1602A读状态
/*输入参数:无
/*输出参数:1602A返回的状态
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
uchar LCM_ReadStatus(void)
{
LCM_Data = 0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & 0x80);//检测忙信号
return(LCM_Data);}
/****************************1602A初始化函数**************************/
/*函数原型:void LCM_Init(void)
/*函数功能:1602A初始化
/*输入参数:无
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void LCM_Init(void)
{
LCM_Data = 0;
LCM_WriteCommand(0x38,0);//三次显示模式设置,不检测忙信号
Delay5Ms();
LCM_WriteCommand(0x38,0);
Delay5Ms();
LCM_WriteCommand(0x38,0);
Delay5Ms();
LCM_WriteCommand(0x38,1);//显示模式设置,开始要求每次检测忙信号
LCM_WriteCommand(0x08,1);//关闭显示
LCM_WriteCommand(0x01,1);//显示清屏
LCM_WriteCommand(0x06,1);// 显示光标移动设置
LCM_WriteCommand(0x0C,1);// 显示开及光标设置
}
/******************1602A按指定位置显示一个字符函数**********************/
/*函数原型:void DisplayOneChar(uchar X, uchar Y, uchar DData)
/*函数功能:1602A按指定位置显示一个字符
/*输入参数:X坐标 Y坐标 要显示的字符
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void DisplayOneChar(uchar X, uchar Y, uchar DData)
{
Y &= 0x1;
X &= 0xF;//限制X不能大于15,Y不能大于1
if (Y) X |= 0x40;//当要显示第二行时地址码+0x40;
X |= 0x80;// 算出指令码
LCM_WriteCommand(X, 0);//这里不检测忙信号,发送地址码
LCM_WriteData(DData);
}
/*******************1602A按指定位置显示一串字符函数*********************/
/*函数原型:void DisplayListChar(uchar X, uchar Y, uchar code *DData)
/*函数功能:1602A按指定位置显示一个字符
/*输入参数:X坐标 Y坐标 要显示字符串的首地址
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void DisplayListChar(uchar X, uchar Y, uchar code *DData)
{
uchar ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF;//限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x20)//若到达字串尾则退出
{
if (X <= 0xF)//X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]);//显示单个字符
ListLength++;
X++;
}
}
}
/********************5ms延时函数************************/
/*函数原型:void Delay5Ms(void)
/*函数功能:5ms延时
/*输入参数:无
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
/********************400ms延时延时函数************************/
/*函数原型:void Delay400Ms(void)
/*函数功能:400ms延时延时
/*输入参数:无
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14/*作者:站长
/**********************************************************************/
void Delay400Ms(void)
{
uchar TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
/********************5ms延时函数************************/
void main()
{
unsigned char a ;
delay_I2C(); //延时很重要,上电必须要延时一段时间才能对eeprom操作
I2C_write_byte(0,6,0x38);//在地址4处写数据0x16
delay_I2C(); //可要。
a = I2C_read_byte(0,6); //从地址4处读回数据
Delay400Ms();//启动等待,等LCM讲入工作状态
LCM_Init();//LCM初始化
Delay5Ms();//延时片刻(可不要)
LCM_ReadData();//测试用句无意义
LCM_Data=255;
DisplayOneChar(1,0,a);
} |