📄 c51对i2c数据的读写.c
字号:
#include <reg51.h>
#include <intrins.h>
#include <i2c.c>
#include <stdio.h>
unsigned char key_s, key_v, tmp;
char code wGood[] = " write i2c good.\r\n";
char code wBad[]= " write i2c bad .\r\n";
char code rGood[]= " read i2c good .\r\n";
char code rBad[]= " read i2c bad .\r\n";
char code temp[]= " \n";
void send_int(void);
void send_str(unsigned char * temp);
bit scan_key();
void proc_key();
void delayms(unsigned char ms);
void send_char(unsigned char txd);
sbit K1 = P1^4;
//24C04的读写添加语句
#define WRITE 0xa0
#define READ 0xa1
#define BLOCK_SIZE 32
typedef char array[BLOCK_SIZE];
//#define uchar unsigned char
//xdata uchar EAROMImage[BLOCK_SIZE];
array EAROMImage;
array readData;
bit flag=FALSE,writeMark=TRUE;
bit E_address(uchar address)//功能:向24C04写入器件地址和一个指定的字节地址
{
I_start();
if(I_send(WRITE))
return (I_send(address));
else
return (FALSE) ;
}
bit E_read_block(void)//从24C04中讲读取BLOCK_SIZE个字节的数据并转存于外部RAM存储映像单元,采用序列读操作
{ //方式从片内0地址开始连续读取数据。如果24C04不接受指定的地址则返回0(false)
uchar I;
if(E_address(0))//从地址0开始读取数据
{
I_start();
if(I_send(READ))
{
for(I=0;I<=BLOCK_SIZE;I++)
{
readData[I] = (I_receive());
if(I != BLOCK_SIZE)
I_Ack();
else{
I_clock();
I_stop();
}
}
return (TRUE);
}
else {
I_stop();
return(FALSE);
}
}
else
I_stop();
return (FALSE);
}
void wait_5ms(void)//提供5ms秒延时(时钟频率为12MHZ)
{
int I;
for(I=0;I<1000;I++)
{
;
}
}
//下一个函数功能:将外部RAM存储映像单元中的数据写入到24C04的头BLOCK_SIZE个字节,采用字节写操作方式
//每次写入时都需要指定内地址。如果24C04不接受指定的地址或某个传达的字节未收到应答信号ACK,则返回0否则返回1.
bit E_write_block(void){
uchar I;
for(I=0;I<=BLOCK_SIZE;I++)
{
if(E_address(I)&&I_send(EAROMImage[I]))
{
I_stop();
wait_5ms();
}
else
return(FALSE);
}
return(TRUE);
}
//结束24C04的读写添加语句
main()
{ uchar i;
SCON = 0x5a;
TMOD = 0x20;
TCON = 0x69;
TH1 = 0xf4;
PCON&= 0xef;
// TH1 = 0xfd;
I_init();
if(E_read_block())
{
uchar n;
send_str(rGood);
for(n=0;n<BLOCK_SIZE; n++)
{
send_char(readData[n]);// 回传接收到的数据
// delayms(2);
i=0;
}
writeMark = TRUE;
}
else
{
send_str(rBad);
}
send_int();
TR1 = 1; // 启动定时器1
// int i=0;
while(1)
{
if(scan_key()) // 扫描按键
{
delayms(10); // 延时去抖动
if(scan_key()) // 再次扫描
{
key_v = key_s; // 保存键值
proc_key(); // 键处理
}
}
if(RI) // 是否有数据到来
{
RI = 0;
tmp = SBUF; // 暂存接收到的数据
P0 = tmp; // 数据传送到P0口
if(tmp=='2')
{
flag=TRUE;
send_char(tmp);
}
if(flag)
{
if(flag&&i<BLOCK_SIZE)
{
EAROMImage[i]=tmp;
i++;
}
else
{
if(writeMark)
{
if(E_write_block())
{
send_str(wGood);
writeMark = FALSE;
}
else
{
send_str(wBad);
}
}
else
{
if(E_read_block())
{
uchar n;
send_str(rGood);
for(n=0;n<BLOCK_SIZE; n++)
{
send_char(readData[n]);// 回传接收到的数据
delayms(2);
i=0;
}
writeMark = TRUE;
}
else
{
send_str(rBad);
}
}
}
}
}
}
}
void send_int(void)
{ TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xF4; // 波特率2400
TL1 = 0xF4;
SCON = 0x50; // 设定串行口工作方式
PCON&= 0xef; // 波特率不倍增
IE = 0x0; // 禁止任何中断
}
bit scan_key()
// 扫描按键
{
key_s = 0x00;
key_s |= K1;
return(key_s ^ key_v);
}
void proc_key()
// 键处理
{
if((key_v & 0x01) == 0)
{ // K1按下
send_str(NULL); // 传送字串
}
}
void send_char(unsigned char txd)
// 传送一个字符
{
SBUF = txd;
while(!TI); // 等特数据传送
TI = 0; // 清除数据传送标志
}
void send_str(unsigned char * temp)
// 传送字串
{
unsigned char i = 0;
while(temp[i] != '\0')
{
SBUF = temp[i];
while(!TI); // 等特数据传送
TI = 0; // 清除数据传送标志
i++; // 下一个字符
}
}
void delayms(unsigned char ms)
// 延时子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -