单片机IIC通信(2)

2020-04-17 04:43

// 读取数据 unsigned char d = 0,i = 0; for (;i < 8;i++) { // 在eeprom修改sda之前,sda需要是高电平 // 即单片机的引脚需要读入数据是,必须置高 SCL = 0; Delay(); SDA = 1; Delay(); // scl置高,表示将要读取数据 SCL = 1; Delay(); d <<= 1; if (SDA == 1) { // 该位为高电平 d |= 0x01; } // scl此时已经是高,不必置高 Delay(); } // 读完一个字节,发送一个非应答位 SCL = 0; Delay(); SDA = 1; Delay(); SCL = 1; Delay(); SCL = 0; return d; }

前面用到的延时函数引用了一个头文件:#include 该头文件包含了_nop_();函数,延时一个机器周期。 void Delay() { // 大概延时四个机器周期 _nop_(); _nop_(); _nop_(); _nop_(); }

以下为完整的代码: #include #include #include \

// 实现单片机的IIC通信

void main() { unsigned char i = 0; unsigned char d = 0; InitAll(); // 向eeprom写1~10的数字,起始地址为0x00 for (i = 1;i <= 10;i++) { if (Write_IIC(i - 1,i) == 0) { P0 = 0x00; } Delay_2(20000); } // 从EEPROM读取前十个数字,通过uart通信发送到电脑 while (1) { for (i = 0;i < 10;i++) { d = Read_IIC(i); Send_UART(d); // 延时 Delay_2(20000); } } }

void InitAll() { // IIC通信 SDA = 1,SCL = 1; // uart通信,scon SM0 = 0,SM1 = 1,REN = 1; // 定时器1 TR1 = 1; // 时间 TH1 = 0xfd,TL1 = 0xfd; // 使用模式2 TMOD = 0x20; // 设置led灯 ENLED = 0,ADDR3 = 1; ADDR0 = 0,ADDR1 = 0,ADDR2 = 0; P0 = 0xff; }

unsigned char WriteData(unsigned char c) { // 向EEPROM写数据

unsigned char temp = 0x80,i; for (i = 0;i < 8;i ++) { SCL = 0; Delay(); if ((c & temp) != 0) { // 真表示测试位是1 SDA = 1; } else { // 假表示测试位是0 SDA = 0; } temp >>= 1; // 将scl置高,让EEPROM有机会读取SDA上的信息 Delay(); SCL = 1; Delay(); } // 最后再接收一个应答位 SCL = 0; Delay(); SDA = 1; Delay(); SCL = 1; Delay(); // 此时SDA已经接收到一个应答位,暂不处理 if (SDA != 0) { // 没有接收到应答位,返回错误 return 0; } SCL = 0; return 1; }

unsigned char Write_IIC(unsigned char address,unsigned char d) { // 开始信号 StartIIC(); // 发送设备地址和操作方式,设备地址为000,操作方式写:0 if (WriteData(0xa0) == 0) { return 0; } // 发送操作数据的地址 if (WriteData(address) == 0) {

return 0; } // 发送数据 if (WriteData(d) == 0) { return 0; } // 停止信号 StopIIC(); }

unsigned char Read_IIC(unsigned char address) { unsigned char d = 0; // 开始信号 StartIIC(); // 写设备地址和操作方式,设备地址为000,操作方式写:0 WriteData(0xa0); // 写操作数据的地址 WriteData(address); // 重新发送开始信号 StartIIC(); // 写设备地址和操作方式,设备地址为000,操作方式读:1 WriteData(0xa1); // 由于前面已经写入希望操作的数据的地址,所以现在不用重新发送 // 读取信号 d = ReadData(); // 停止信号 StopIIC(); return d; }

unsigned char ReadData() { // 读取数据 unsigned char d = 0,i = 0; for (;i < 8;i++) { // 在eeprom修改sda之前,sda需要是高电平 // 即单片机的引脚需要读入数据是,必须置高 SCL = 0; Delay(); SDA = 1; Delay(); // scl置高,表示将要读取数据 SCL = 1; Delay(); d <<= 1; if (SDA == 1) {

// 该位为高电平 d |= 0x01; } // scl此时已经是高,不必置高 Delay(); } // 读完一个字节,发送一个非应答位 SCL = 0; Delay(); SDA = 1; Delay(); SCL = 1; Delay(); SCL = 0; return d; }

void StartIIC() { // 先将scl置底,以便将sda置高 SCL = 0; Delay(); SDA = 1; Delay(); SCL = 1; Delay(); // 在此基础上将sda置低,表示开始 SDA = 0; Delay(); SCL = 0; }

void StopIIC() { // SCL = 0; Delay(); SDA = 0; Delay(); // 现在SDA,SCL都是低电平 SCL = 1; Delay(); SDA = 1; Delay(); }

void Delay() { // 大概延时四个机器周期 _nop_(); _nop_(); _nop_();

_nop_(); }

void Delay_2(unsigned int t) { while (t--) {} }

void Send_UART(unsigned char d) { SBUF = d; while (!TI) ; TI = 0; }


单片机IIC通信(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:动设备监造管理规定

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: