单片机通过串口向iic写入数据并读出,功能未实现,求高...
时间:10-02
整理:3721RD
点击:
/*
函数功能 通过串口向EEPROM中写入数据然后读出数据显示到串口调试工具上,串口的收发功能已经调试验证过,但是向eeprom中写和读不知道错误在哪里。
*/
#include <reg52.h> //包含51单片机寄存器定义的头文件
#include <intrins.h> //包含_nop_()函数定义的头文件
#define uchar unsigned char
#define con_read 0xa1 //器件地址以及读取操作,0xa1即为1010 0001B
#define con_write 0xa0 //器件地址以及写入操作,0xa1即为1010 0000B
#define len 8 //数据长度
sbit SDA=P2^0; //将串行数据总线SDA位定义在为P2.0引脚
sbit SCL=P2^1; //将串行时钟总线SDA位定义在为P2.1引脚
uchar inbuf[len]; //存储数据
uchar outbuf[len];
int count = 0;
uchar flag = 0;//数据校验
void delay(void) //延时
{
_nop_();
_nop_();
_nop_();
_nop_();
}
void iic_init(void) //IIC初始化
{
SCL = 1;
SDA = 1;
}
void uart_init(void)
{
SCON = 0x50; //串口通信模式1
TMOD = 0x20; //定时器1,模式2
TH1 = 0xfd; //波特率9600
TL1 = 0xfd;
TR1 = 1;
ES = 1;
EA = 1;
}
void iic_start(void) //开始
{
SCL = 1;
SDA = 1;
delay();
SDA = 0;
delay();
SCL = 0;
}
void iic_stop(void) //结束
{
SCL = 1;
SDA = 0;
delay();
SDA = 1;
delay();
}
void iic_writebyte(uchar ch) //写一字节数据
{
uchar i;
for (i=0;i<8;i++)
{
SCL = 0;
delay();
SDA = (bit)(ch&0x80);
delay();
SCL = 1;
delay();
ch <<= 1;
}
SCL = 0;
SDA = 1; //发送完一字节数据后,将数据线电平拉高,等待应答位
delay();
}
bit iic_ask(void) //应答
{
int i=0;
uchar ask;
SCL = 1;
delay();
ask = (bit)SDA;
while ((ask==1)&&(i<100))i++;
SCL = 0;
delay();
return ask;
}
void iic_write(uchar add,uchar dat) //向EEPROM中写数据
{
iic_start();
iic_writebyte(con_write);//con_write 写控制
iic_ask();
iic_writebyte(add);//地址
iic_ask();
iic_writebyte(dat);//数据
iic_ask();
iic_stop();
delay();
}
uchar iic_readbyte(void) //读一个字节数据并发送非应答
{
uchar x;
int i;
SCL = 0;
delay();
SDA = 1;
delay();
for (i=0;i<8;i++)
{
SCL = 1;
delay();
x <<= 1;
x |= (uchar)SDA;
SCL = 0;
delay();
}
SCL = 0;
SDA = 1;
delay();
SCL = 1;
delay();
SCL = 0;
return x;
}
uchar iic_read(uchar add) //从EEPROM中读数据
{
uchar x;
iic_start();
iic_writebyte(con_write);
iic_ask();
iic_writebyte(add);
iic_ask();
iic_start();
iic_writebyte(con_read);
iic_ask();
x = iic_readbyte();
iic_stop();
return x;
}
void delaynms(uchar n) //延时
{
uchar i,j;
for(i=0;i<n;i++)
for(j=0;j<100;j++);
}
void serial() interrupt 4 //串口中断 读串口发来的数据
{
if (RI)
{
RI = 0;
inbuf[count] = SBUF;
count++;
if (count == len)
{
flag = 1;
count = 0;
}
}
}
void send_char(uchar ch) //向串口发送一个字节数据
{
SBUF = ch;
while (!TI);
TI = 0;
}
void send_string(uchar *str) //向串口发送一串数据
{
int i;
for (i=0;i<len;i++)
{
send_char(*(str+i));
}
}
void main(void)
{
uchar i; //EEPROM中地址
uart_init(); //串口初始化
iic_init(); //iic总线初始化
while (1)
{
if (flag == 1) //从串口中读取数据完毕则flag置1
{
for (i=0;i<len;i++)
{
iic_write(i,inbuf[i]); //将从串口接收到的数据写到EEPROM中
}
delaynms(200);
for (i=0;i<len;i++)
{
outbuf[i] = iic_read(i); //将EEPROM中的数据读出
}
send_string(outbuf); //将EEPROM中读出的数据发送到串口
delaynms(200);
flag = 0; //标志位清零
}
}
}
函数功能 通过串口向EEPROM中写入数据然后读出数据显示到串口调试工具上,串口的收发功能已经调试验证过,但是向eeprom中写和读不知道错误在哪里。
*/
#include <reg52.h> //包含51单片机寄存器定义的头文件
#include <intrins.h> //包含_nop_()函数定义的头文件
#define uchar unsigned char
#define con_read 0xa1 //器件地址以及读取操作,0xa1即为1010 0001B
#define con_write 0xa0 //器件地址以及写入操作,0xa1即为1010 0000B
#define len 8 //数据长度
sbit SDA=P2^0; //将串行数据总线SDA位定义在为P2.0引脚
sbit SCL=P2^1; //将串行时钟总线SDA位定义在为P2.1引脚
uchar inbuf[len]; //存储数据
uchar outbuf[len];
int count = 0;
uchar flag = 0;//数据校验
void delay(void) //延时
{
_nop_();
_nop_();
_nop_();
_nop_();
}
void iic_init(void) //IIC初始化
{
SCL = 1;
SDA = 1;
}
void uart_init(void)
{
SCON = 0x50; //串口通信模式1
TMOD = 0x20; //定时器1,模式2
TH1 = 0xfd; //波特率9600
TL1 = 0xfd;
TR1 = 1;
ES = 1;
EA = 1;
}
void iic_start(void) //开始
{
SCL = 1;
SDA = 1;
delay();
SDA = 0;
delay();
SCL = 0;
}
void iic_stop(void) //结束
{
SCL = 1;
SDA = 0;
delay();
SDA = 1;
delay();
}
void iic_writebyte(uchar ch) //写一字节数据
{
uchar i;
for (i=0;i<8;i++)
{
SCL = 0;
delay();
SDA = (bit)(ch&0x80);
delay();
SCL = 1;
delay();
ch <<= 1;
}
SCL = 0;
SDA = 1; //发送完一字节数据后,将数据线电平拉高,等待应答位
delay();
}
bit iic_ask(void) //应答
{
int i=0;
uchar ask;
SCL = 1;
delay();
ask = (bit)SDA;
while ((ask==1)&&(i<100))i++;
SCL = 0;
delay();
return ask;
}
void iic_write(uchar add,uchar dat) //向EEPROM中写数据
{
iic_start();
iic_writebyte(con_write);//con_write 写控制
iic_ask();
iic_writebyte(add);//地址
iic_ask();
iic_writebyte(dat);//数据
iic_ask();
iic_stop();
delay();
}
uchar iic_readbyte(void) //读一个字节数据并发送非应答
{
uchar x;
int i;
SCL = 0;
delay();
SDA = 1;
delay();
for (i=0;i<8;i++)
{
SCL = 1;
delay();
x <<= 1;
x |= (uchar)SDA;
SCL = 0;
delay();
}
SCL = 0;
SDA = 1;
delay();
SCL = 1;
delay();
SCL = 0;
return x;
}
uchar iic_read(uchar add) //从EEPROM中读数据
{
uchar x;
iic_start();
iic_writebyte(con_write);
iic_ask();
iic_writebyte(add);
iic_ask();
iic_start();
iic_writebyte(con_read);
iic_ask();
x = iic_readbyte();
iic_stop();
return x;
}
void delaynms(uchar n) //延时
{
uchar i,j;
for(i=0;i<n;i++)
for(j=0;j<100;j++);
}
void serial() interrupt 4 //串口中断 读串口发来的数据
{
if (RI)
{
RI = 0;
inbuf[count] = SBUF;
count++;
if (count == len)
{
flag = 1;
count = 0;
}
}
}
void send_char(uchar ch) //向串口发送一个字节数据
{
SBUF = ch;
while (!TI);
TI = 0;
}
void send_string(uchar *str) //向串口发送一串数据
{
int i;
for (i=0;i<len;i++)
{
send_char(*(str+i));
}
}
void main(void)
{
uchar i; //EEPROM中地址
uart_init(); //串口初始化
iic_init(); //iic总线初始化
while (1)
{
if (flag == 1) //从串口中读取数据完毕则flag置1
{
for (i=0;i<len;i++)
{
iic_write(i,inbuf[i]); //将从串口接收到的数据写到EEPROM中
}
delaynms(200);
for (i=0;i<len;i++)
{
outbuf[i] = iic_read(i); //将EEPROM中的数据读出
}
send_string(outbuf); //将EEPROM中读出的数据发送到串口
delaynms(200);
flag = 0; //标志位清零
}
}
}