📄 at24c08.c
字号:
#include "main.h"
#include "port.h"
/*------------------------------------main.h-------------------------------------*-
#ifndef _MAIN_H
#define _MAIN_H
#include "REG51F.H"
#include <intrins.h>
typedef unsigned char tByte;
typedef unsigned int tWord;
typedef unsigned long tLong;
#endif
-*-------------------------------end of main.h-----------------------------------*/
/*-----------------------------------port.h--------------------------------------*-
sbit SDA = P3^7;
sbit SCL = P3^6;
-*-------------------------------end of port.h-----------------------------------*/
/*-------------------------------------------------------------------------------*-
*说 明:本程序适用与24CXX,EEPROM的读写
----------
*调试情况:调试器件使用了AT24C08,调试成功
----------
*测试功能:将数据写入EEPROM在从EEPROM读出送LCD1602显示
----------
*作 者:冯耿超
*完成日期:2007-08-11
-*-------------------------------------------------------------------------------*/
tByte xdata Getrom[] = {0};
//LCD1602阿拉伯数字 0 1 2 3 4 5 6 7 8 9 :
tByte code DispCode[] ={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a};
//15915281761
tByte code ROM[] = {0x01,0x05,0x09,0x01,0x05,0x02,0x08,0x01,0x07,0x06,0x01,0x01,0x05,0x09,0x01,0x05,0x02,0x08,0x01,0x07,0x06,0x01};
/*---------------------------------------LCD1602---------------------------------*/
//写控制字操作
void write_cmd_oper()
{
lcd_rs = 0;
lcd_rw = 0;
}
//写数据操作
void write_dat_oper()
{
lcd_rs = 1;
lcd_rw = 0;
}
//读控制字寄存器操作
void read_cmd_oper()
{
lcd_rs = 0;
lcd_rw = 1;
}
//检查BF忙标志位
bit check_busy()
{
bit flag;
read_cmd_oper();
//忙标志位为0,返回flag
while(lcd_data&0x80==1);
flag = 0;
return (flag);
}
//向LCD写控制字
void lcd_write_cmd(tByte cmd,check)
{
//check为1,则检测忙信号
if(check)
{
//检查BF忙标志位,0为空闲
while(check_busy());
}
//将控制字写入到LCD
write_cmd_oper();
lcd_en = 1;
EA = 0;
lcd_data = cmd;
EA = 1;
lcd_en = 0;
}
//向LCD写数据
void lcd_write_dat(tByte dat)
{
//检查BF忙标志位,0为空闲,可以写入
while(check_busy());
//将数据写入到LCD
write_dat_oper();
lcd_en = 1;
EA = 0;
lcd_data = dat;
EA = 1;
lcd_en = 0;
}
/*--------------------在指定的位置上显示字符,X行,Y为列,--------------------*-
-*--------------------Z为显示的字符个数dat为显示的字符地址------------------*/
void lcd_display_str(tByte x,tByte y,tByte z,tByte *dat)
{
tByte t;
t=z+1;
//输入第一行,第Y列(Y从1到16)
if(x==1)
{
{
//第一行,第Y列的起始地址
lcd_write_cmd(lcd_first_line-1+y,1);
}
}
//输入第二行,第Y列
if(x==2)
{
//第二行,第Y列的起始地址
lcd_write_cmd(lcd_second_line-1+y,1);
}
while(--t&&*dat!='\0')
{
//开始从第二行的第Y列写上显示数据
lcd_write_dat(*dat++);
}
}
/*-----------------------向X行Y列写入N个DAT数据---------------------------*/
void write_dat_toxy(tByte X,tByte Y,tByte N,tByte DAT)
{
tByte i;
i=0;
if(X==1)
{
//发送命令让LCD指向第一行
lcd_write_cmd(lcd_first_line+Y-1,1);
i=N;
}
else if(X==2)
{
//发送命令让LCD指向第二行
lcd_write_cmd(lcd_second_line+Y-1,1);
i=N;
}
if(i!=0)
{
do
{
//让LCD的相应位置显示空格
lcd_write_dat(DAT);
}while(--i!=0);
}
}
//LCD初始化
void lcd_init()
{
lcd_data = 0x00;
//三次显示模式设置,不检测忙信号
lcd_write_cmd(lcd_8bit_2_line, 0);
lcd_write_cmd(lcd_8bit_2_line, 0);
lcd_write_cmd(lcd_8bit_2_line, 0);
//设置显示模式,检测忙信号
lcd_write_cmd(lcd_8bit_2_line, 1);
//屏幕显示关,无光标闪烁
lcd_write_cmd(lcd_cur_r_shift, 1);
//设置光标移动
lcd_write_cmd(lcd_cur_r_shift, 1);
//屏幕显示开,无光标无闪烁
lcd_write_cmd(lcd_on_non_cur_flash,1);
//光标或显示移位,光标和文字右移
//lcd_write_cmd(lcd_test_r_shift, 1);
//清除屏幕显示
lcd_write_cmd(clear_display, 1);
}
//LCD1602显示程序
void LCDDisp_Task()
{
tByte i,j;
for(j=0;j<11;j++)
{
write_dat_toxy(1,j+1,1,DispCode[Getrom[j]]);
}
for(i=0;i<11;i++)
{
write_dat_toxy(2,i+1,1,DispCode[Getrom[i+11]]);
}
}
/*------------------------------------END OF LCD----------------------------------*/
/*--------------------------------- 24CXX读写程序 --------------------------------*/
//使用11.0592晶振,延时大约kms
void delay(tByte k)
{
while(k--)
{
tByte i;
for(i=125;i>0;i--);
}
}
/*--------------------------------------------------------------------------------*-
*启动I2C总线,
*SCL为高时,SDA从高变为低
-*--------------------------------------------------------------------------------*/
void I2C_Star(void)
{
SDA = 1;
SCL = 1;
_nop_();
SDA = 0;
_nop_();
}
//停止
void I2C_Stop(void)
{
SDA = 0;
SCL = 1;
_nop_();
SDA = 1;
_nop_();
}
//正向回应
void I2C_Ack(void)
{
SDA = 0;
_nop_();
SCL = 1;
_nop_();
SCL = 0;
}
//反向回应
void I2C_No_Ack(void)
{
SDA = 1;
_nop_();
SCL = 1;
_nop_();
SCL = 0;
}
//内部函数,发送数到i2c
void Write_I2C(tByte dat)
{
tByte BitCnt=8;
tByte Temp;
do
{
Temp = dat;
SCL = 0;
_nop_();
if((Temp&0x80)==0x80)
SDA=1;
else
SDA=0;
SCL=1;
Temp=dat<<1;
dat=Temp;
BitCnt--;
} while(BitCnt);
SCL=0;
}
//内部函数,从i2c接收数
tByte Read_I2C(void)
{
tByte Temp=0,Temp1=0,BitCnt=8;
SDA=1;
do
{
SCL=0;
_nop_();
SCL=1;
_nop_();
if(SDA)
Temp=Temp|0x01;
else
Temp=Temp&0xfe;
if(BitCnt-1)
{
Temp1=Temp<<1;
Temp=Temp1;
}
BitCnt--;
} while(BitCnt);
return(Temp);
}
/*--------------------------------------------------------------------------*-
*外部调用API函数
*功 能:向I2C器件写入数据
*入口参数:器件号(页号)I2CAdd_W,写入数据dat,写入的内部地址Address
*出口参数:无
*作 者:冯耿超
*完成日期:2007-08-11
-*--------------------------------------------------------------------------*/
void Write_Byte_To_I2C(tByte I2CAdd_W,tByte dat,tByte Address)
{
EA=0;
I2C_Star();
Write_I2C(I2CAdd_W);
I2C_Ack();
Write_I2C(Address);
I2C_Ack();
Write_I2C(dat);
I2C_Ack();
I2C_Stop();
delay(1);
EA=1;
}
/*--------------------------------------------------------------------------*-
*外部调用API函数
*功 能:从I2C器件读入数据
*入口参数:器件号(页号)I2CAdd_W,I2CAdd_R,所读数据的内部地址Address
*出口参数:dat
*作 者:冯耿超
*完成日期:2007-08-11
-*--------------------------------------------------------------------------*/
tByte Read_Byte_I2C(tByte I2CAdd_W,I2CAdd_R,Address)
{
tByte dat;
I2C_Star();
Write_I2C(I2CAdd_W);
I2C_Ack();
Write_I2C(Address);
I2C_Ack();
I2C_Star();
Write_I2C(I2CAdd_R);
I2C_Ack();
dat=Read_I2C();
SCL=0;
I2C_No_Ack();
I2C_Stop();
return(dat);
}
void main()
{
tByte i;
lcd_init();
//向I2CEEPROM写如22个字节
for(i=0;i<22;i++)
{
Write_Byte_To_I2C(0xa0,ROM[i],i);
}
while(1)
{
for(i=0;i<22;i++)
{
Getrom[i] = Read_Byte_I2C(0xa0,0xa1,i);
}
LCDDisp_Task();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -