通过串口输入 R 、W 进行控制程序读写IIC设备。波特率9600bps,晶振115200HZ。
main.c
/*----------------------------------------------- IIC编程 1 编写:Louis 邮箱:kaly.liu@163.com 日期:2015.06.01 修改:通过串口命令R/W,控制EEPROM的读R写W。并从串口提示。 改进:增加对页读写功能 晶振:11.0592MHZ NOTE:*通过实测发现,AT24C02可以连续写入16BYTE字节,而且地址要连续的两个页。就是0~15,16~31,。。。 ------------------------------------------------*/ #include <REG52.H> #include<string.h> #include"uart.h" #include "iic.h" sbit WP=P1^0; sbit LED7=P1^7; unsigned char idata temp[8]; unsigned char rxnum; unsigned char flag2; unsigned char EEPROM_WR_FLAG=0; code const char str1[] = "The string is 来自单片机!\r\n"; code const char str2[] = "Author: louis \r\n"; //const 限定一个变量不允许被改变。在一定程度上提高程序安全性和可靠性 //code 存储区间为 程序存储区 /***************函数声明*******************/ void InitUART(void); void SendOneByte(uint8); void SendrStr(uint8 *ptr); void main(void) { unsigned char Control,*p1,*p2; unsigned char buf1[]="The first page!!The second page!The third page!!"; /* 发送缓冲区 */ unsigned char idata buf2[49]; /* 接收缓冲区 */ unsigned char Length; unsigned int addr ,i=0; /* 24Cxx片内地址 */ WP=0; // P4SW|= 0x10; LED7=1; InitUART(); while(str2[i]!='\0') { SendOneByte(str2[i++]); } SendrStr(str1); ES =1; EA =1; p1=buf1; p2=buf2; addr=0; ////片内地址 AT24C02为0~255 , 32page*8byte = 256个字节///// Length=48; ////// 读写长度 ////// enumer=AT2402; /// 读写AT24C02//// while(1){ if(EEPROM_WR_FLAG=='W'){ Control=0xae; /// 1010 1110 写操作/// RW24xx(p1,Length,addr,Control,enumer); // 写操作 // for(i=0;i<10000;i++); //要加入延时···才可正确的读取数据! //在STOP和START之间有个 write cycle,一般有个最大值Twr.这是设备内部进行写入数据需要的时间,所以此处的延迟需要 大于这个 最大值Twr。 // Delay(1000);//1:6.18us; 2:8.36us 3:10.55us △=2.18us EEPROM_WR_FLAG=0; } if(EEPROM_WR_FLAG=='R'){ Control=0xaf; ///读操作/// RW24xx(p2,Length,addr,Control,enumer);// 读 EEPROM_WR_FLAG=0; SendrStr(p2); SendrStr("\r\n"); } }//while } /****************中断服务函数***************/ void UART_ISR(void) interrupt 4 { uint8 RX_Data; //只响应"接收"中断,"发送"中断来了就直接抹掉 if(RI) { RI = 0; //串口中断标志不能自己清除,需要手动清除 RX_Data=SBUF; EEPROM_WR_FLAG = RX_Data; SendOneByte(EEPROM_WR_FLAG); SendrStr(":\r\n"); } else TI = 0; //串口发中断是发送完缓冲区数据之后产生 }
uart.h头文件
/*----------------------------------------------- 编写:刘宗铭 邮箱:kaly.liu@163.com 日期:2015.05 修改:无 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 /******************************************************************* 请提前计算一下所选晶振能达到的最高速度,波特率不能超过最高速度 (1) 波特率加倍(SMOD=1): Max_Baud = FOSC/12/16 (2) 波特率不加倍(SMOD=0):Max_Baud = FOSC/12/32 例如:22.1184MHz晶振,波特率加倍时,最大波特率=22118400/12/16=115200 *******************************************************************/ #define FOSC 11059200 //振荡频率 #define BAUD 9600 //波特率 #define SMOD 1 //是否波特率加倍 #if SMOD #define TC_VAL (256-FOSC/16/12/BAUD) #else #define TC_VAL (256-FOSC/32/12/BAUD) #endif typedef unsigned char uint8; typedef unsigned int uint16; /****************串口初始化函数*************/ void InitUART(void) { TMOD = 0x20; //定时器1,模式2工作模式 SCON = 0x50; //串口工作模式1,允许REN /* SCON: 模式 1, 8-bit UART, 使能接收 */ TH1 = TC_VAL; TL1 = TH1; PCON = 0x80; //发送速率加倍 ES = 1; EA = 1; TR1 = 1; } /**************串口发送字符函数*************/ void SendOneByte(uint8 c) { ES = 0; //禁止中断,让串口安心工作啊 SBUF = c; while(!TI); //等待发送完毕 TI = 0; //清TI中断 ES = 1; //打开中断 } /**************串口发送字符串函数*************/ /**************串口发送字符串函数*************/ void SendrStr(const uint8 *ptr) { for(;*ptr!='\0';ptr++) { SendOneByte(*ptr); } }
IIC.h头文件
/*----------------------------------------------- 编写:<span style="font-family: Arial, Helvetica, sans-serif;">Louis </span> 邮箱:kaly.liu@163.com 日期:2015.05 修改:添加多页读写功能 器件的型号 我用的是AT24C02 32PAGE*8BYTE = 2Kbit ------------------------------------------------*/ #include <intrins.h> #include<reg52.h> #define ERROR 10 //允许ERROR的最大次数 sbit SDA=P1^2; sbit SCL=P1^1; enum eepromtype {AT2401,AT2402,AT2404,AT2408,AT2416,AT2432,AT2464,AT24128,AT24256};/*器件的型号 我用的是AT24C02*/ enum eepromtype enumer; //定义一个枚举变量 /* * * * * * * * 一个简单延时程序 * * * * * * * * * * * * */ void Delay(unsigned char DelayCount) { while(DelayCount--); //判断 + 执行 2个机器周期 } /* * * * * 以下是对IIC总线的操作子程序 * * * * */ /* * * * * * 启动总线 * * * * */ void Start(void) { SCL=0; /* SCL处于高电平时,SDA从高电平转向低电平表示 */ SDA=1; /* 一个"开始"状态,该状态必须在其他命令之前执行 */ Delay(2); SCL=1; Delay(2); SDA=0; Delay(2); SCL=0; SDA=1; Delay(2); } /* * * * * 停止IIC总线 * * * * */ void Stop(void) { SCL=0; /*SCL处于高电平时,SDA从低电平转向高电平 */ SDA=0; /*表示一个"停止"状态,该状态终止所有通讯 */ Delay(2); SCL=1; Delay(2); /* 空操作 */ SDA=1; Delay(2); SCL=0; Delay(1000); } /* * * * * 检查应答位 * * * * */ bit RecAck(void) { SCL=0; SDA=1; Delay(20); SCL=1; Delay(2); Delay(2); CY=SDA; /* 因为返回值总是放在CY中的 */ SCL=0; Delay(20); return(CY); } /* * * * *对IIC总线产生应答 * * * * */ void Ack(void) { SDA=0; /* EEPROM通过在收到每个地址或数据之后, */ SCL=1; /* 置SDA低电平的方式确认表示收到读SDA口状态 */ Delay(2); SCL=0; Delay(2); SDA=1; } /* * * * * * * * * 不对IIC总线产生应答 * * * * */ void NoAck(void) { SDA=1; SCL=1; Delay(2); SCL=0; } /* * * * * * * * * 向IIC总线写数据 * * * * */ void Send(unsigned char sendbyte) { unsigned char data j=8; for(;j>0;j--) { SCL=0; sendbyte <<= 1; /* 使CY=sendbyte^7; */ SDA=CY; /* CY 进位标志位 */ Delay(2); SCL=1; Delay(20); } SCL=0; Delay(2); } /* * * * * * * * * 从IIC总线上读数据子程序 * * * * */ unsigned char Receive(void) { register receivebyte,i=8; SCL=0; while(i--) { SCL=1; receivebyte = (receivebyte <<1 ) | SDA; Delay(2); SCL=0; // receivebyte = (receivebyte <<1 ) | SDA; //不能放在这里啊,放这里接受数据出错··!! Delay(2); } return(receivebyte); } /* ----- AT24C01~AT24C256 的读写程序 ------ */ bit RW24xx(unsigned char *DataBuff,unsigned char Length,unsigned int Addr, unsigned char Control,enum eepromtype enumer) { unsigned char data j,i=ERROR; unsigned int k; bit errorflag=1; /* 出错标志 */ while(i--) { Start(); /* 启动总线 */ Send(Control & 0xfe); /* 向IIC总线写数据,器件地址 */ if(RecAck()) continue; /* 如写不正确结束本次循环 */ if(enumer > AT2416) { Send((unsigned char)(Addr >> 8));//把整型数据转换为字符型数据:弃高取低,只取低8位.如果容量大于32K位,使用16位地址寻址,写入高八位地址 if(RecAck()) continue; } Send((unsigned char)Addr); /* 向IIC总线写数据 */ if(RecAck()) continue; /* 如写不正确结束本次循环 */ if(!(Control & 0x01)) //判断是读器件还是写器件 如果是写 0 就进去执行 { j=Length; errorflag=0; /* 清错误特征位 */ while(j--) { //******************此段判断页***多页读写功能***********************// if(Addr%16==0) { Stop(); for(k=0;k<10000;k++); Start(); /*启动总线*/ Send(Control & 0xfe); /*发送器件地址*/ if(RecAck()) continue; /* 如写不正确结束本次循环 */ if(enumer > AT2416) { Send((unsigned char)(Addr >> 8));//把整型数据转换为字符型数据:弃高取低,只取低8位. //如果容量大于32K位,使用16位地址寻址,写入高八位地址 if(RecAck()) continue; /* 如写不正确结束本次循环 */ } Send((unsigned char)Addr); /*发送器件子地址*/ if(RecAck()) continue; /* 如写不正确结束本次循环 */ } Addr++; //********************此段判断页***多页读写功能**************************// /*发送数据*/ Send(*DataBuff++); /* 向IIC总线写数据 */ if(!RecAck()) continue; /* 如写正确结束本次循环 */ errorflag=1; break; } if(errorflag==1) continue; // SendOneByte('O'); break; } else { Start(); /* 启动总线 */ Send(Control); /* 向IIC总线写数据 */ if(RecAck()) continue;//器件没应答结束本次本层循环 while(--Length) /* 字节长为0结束 */ { *DataBuff ++= Receive(); Ack(); /* 对IIC总线产生应答 */ } *DataBuff=Receive(); /* 读最后一个字节 */ NoAck(); /* 不对IIC总线产生应答 */ errorflag=0; break; } } Stop(); /* 停止IIC总线 */ if(!(Control & 0x01)) { Delay(255); Delay(255); Delay(255); Delay(255); } return(errorflag); }
相关推荐
清晰明确的操作思路 详细的注释 通过IIC总线读写AT24C02B(EEPROM),同时用LED反映读出数据状态
1、基于IIC协议,采用verilog编写AT24C16驱动程序。 2、实现功能:在AT24C16的地址0~99之间顺序写入数据0~99,然后在读取出来,读取的数据通过串口调试助手显示出来。 3、测试平台Quartus 17.1
STM32f103VE通过IIC读写24C02存储器,完成对于存储器的数据读写和写入。使用Cortex-M3 IIC通讯方法;Cortex-M3数据从24C02存储器进行读写;使用STM32CubMX软件,正确配置STM32 IIC;操控STM32 实现对24C02存储器的...
串行接口:通过串行接口(如I2C)进行读写操作,与微控制器或其他外部设备连接方便。 可编程性:支持电擦除和可编程的存储单元,可以反复写入新的数据。 低功耗:在待机状态下功耗很低,适合移动设备或电池供电的...
TQ2440的IIC应用——读写AT24C02A 这是赵春江老师博客摘录下来TQ2440开发板裸机程序,我基本上验证过,转发给大家,希望对大家有些帮助,多多交流,一起进步。
将ascii_table[i]内的144字节数据存储到EEPROM 24C02内,并通过串口通信(9600pbs)发送,同时通过P1口8位显示。
使用IIC协议读写24c02并在LCD上显示结果
2、【一码全包】针对AT24CXX系列芯片编写了通用代码,只需在头文件中更改相关宏定义即可改变芯片型号(支持AT24C01、AT24C02、AT24C04、AT24C08、AT24C16) 3、【单字节读写模式】针对AT24CXX芯片的(RandomRead&BYTE...
STM32 GPIO模拟IIC串口,实现AT24C16页读写
LPC210X的I2C控制单元 I2C 串行I/O 控制器 LPC2101/2102/2103 各含有两个I2C 总线控制器。 I2C 是一个双向总线,它使用两条线:串行时钟线(SCL) 和串行数据线(SDA) 实现互连 芯片的...
3、【一码全包】针对AT24CXX系列芯片编写了通用代码,只需在头文件中更改相关宏定义即可改变芯片型号(支持AT24C01、AT24C02、AT24C04、AT24C08、AT24C16) 4、【单字节读写模式】针对AT24CXX芯片的(RandomRead&BYTE...
该程序采用德州仪器的cc2530单片机,在模拟IIC时序下进行读写,断电复位后串口0打印写入的数据
AT24c16 通信 i2c 读写 i2c IO模拟 PB6 pb7 测试写入 地址100 读出值 串口打印
STC8A8K64S4A12单片机模拟I2C接口读写AT24C EEPROM存储串口监测输出 KEIL工程文件源码: void main() { u8 pd; UartInit(); //串口初始化 delay1ms(500); UartSendStr("uart I2C test"); while(1) { ...
stm32f103单片机 读写IIC总线EEPROM 24c02 的 程序
这是我写的STM32F103的硬件IIC程序,亲测可用。可用通过串口查看读写结果。可以在正点原子战舰板上运行。
基于XN-51-V1.1开发板IIC总线AT24C02芯片读写 基于XN-51-V1.1开发板LCD12864液晶显示 基于XN-51-V1.1开发板LCD1602液晶显示 基于XN-51-V1.1开发板串口通信试验 基于XN-51-V1.1开发板定时器控制LED亮灭试验 基于XN-51...
本程序是通过C8051F020单片机控制,向24C16里面写数据,再把写进去的数据读出来,通过串口打印出来,实现IIC的读写操作
本程序在实验板ATMEGA16上测试通过,在示波器把SCL,SDA信号线有数据,移值到自己电路上可以放心使用,在ATMEGA32上一样使用,本人24C02的A2,A1,A0都是接地,若地址不一样,在程序相应位置改一下就可以,串口上...
为多种EEPROM芯片提供IIC读写控制器,对外接口方便,可直接使用。包括AT24C04的vivado工程,M24C64的读写源码,24LC64的读写源码。架构清晰,也可以把该控制器轻松的移植到其他的IIC接口器件上。