历史上的今天
今天是:2024年11月09日(星期六)
2019年11月09日 | STM8S_010_I2C读写EEPROM(硬件方式)
2019-11-09 来源:eefocus
Ⅰ、写在前面
相信看过前面那篇文章“更加深入理解I2C总线、协议及应用”的人对I2C都有一定的了解了。那篇文章是针对I2C,使用单片机IO模拟I2C方式实现读写操作。
本文将讲述硬件I2C读写操作,也就是由处理器自身硬件的I2C实现时钟、数据的传输过程。
Ⅱ、STM8硬件I2C知识
STM8S的I2C模块不仅可以接收和发送数据,还可以在接收时将数据从串行转换成并行数据,在发送时将数据从并行转换成串行数据。可以开启或禁止中断。接口通过数据引脚(SDA)和时钟引脚(SCL)连接到I2C总线。允许连接到标准(最高100kHz)或快速(最高400kHz)的I2C总线。
1.I2C的4种模式
● 从设备发送模式
● 从设备接收模式
● 主设备发送模式
● 主设备接收模式
2.I2C的主要特点
● 并行总线/I2C总线协议转换器
● 多主机功能:该模块既可做主设备也可做从设备
● I2C主设备功能
─ 产生起始和停止信号
● I2C从设备功能
─ 可编程的 I2C 地址检测
─ 停止位检测
● 产生和检测7位/10位地址和广播呼叫
● 支持不同的通讯速度
─ 标准速度(最高 100 kHz)
─ 快速(最高 400 kHz)
● 状态标志:
─ 发送器/接收器模式标志
─ I2C 总线忙标志
─ 主模式时的仲裁失败
─ 地址/数据传输后的应答(ACK)错误
─ 检测到错误的起始或停止条件
─ 禁止时钟展宽功能时数据过载或欠载
● 3种中断
─ 1 个通讯中断
─ 1 个出错中断
─ 1 个唤醒中断
● 唤醒功能
─ 从模式下如果检测到地址匹配可以将 MCU 从低功耗模式中唤醒
● 可选的时钟展宽功能
3.主模式所要求的操作顺序
● 在I2C_FREQR寄存器中设定该模块的输入时钟以产生正确的时序
● 配置时钟控制寄存器
● 配置上升时间寄存器
● 编程I2C_CR1寄存器启动外设
● 置I2C_CR1寄存器中的START位为1,产生起始条件
● I2C模块的输入时钟频率必须至少是:
● 标准模式下为:1MHz
● 快速模式下为:4MHz
Ⅲ、软件工程源代码
1.关于工程
本文提供的工程代码是基于前面软件工程“STM8S-A04_UART基本收发数据”增加I2C接口修改而来。读写EEPROM的方式和之前“模拟I2C读写”的方式不一样。
2.硬件I2C初始化
void I2C_Initializes(void)
{
CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
I2C_Cmd(ENABLE);
I2C_Init(I2C_SPEED, I2C_SLAVE_ADDRESS7, I2C_DUTYCYCLE_2, I2C_ACK_CURR,
I2C_ADDMODE_7BIT, 16);
}
I2C_SPEED:I2C速度,一般是100K - 400K
I2C_SLAVE_ADDRESS7:从设备地址,作为主设备时,这个地址不起作用。
I2C_DUTYCYCLE_2:快速模式
I2C_ACK_CURR:应答
I2C_ADDMODE_7BIT:设备地址位数
16:输入时钟(单位M)
3.EEPROM_WriteByte写一字节
写一字节分为5个步骤:
void EEPROM_WriteByte(uint16_t Addr, uint8_t Data)
{
while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
/* 1.开始 */
I2C_GenerateSTART(ENABLE);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 2.设备地址/写 */
I2C_Send7bitAddress(EEPROM_DEV_ADDR, I2C_DIRECTION_TX);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* 3.数据地址 */
#if (8 == EEPROM_WORD_ADDR_SIZE)
I2C_SendData((Addr&0x00FF));
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
#else
I2C_SendData((uint8_t)(Addr>>8));
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData((uint8_t)(Addr&0x00FF));
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
#endif
/* 4.写一字节数据 */
I2C_SendData(Data);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* 5.停止 */
I2C_GenerateSTOP(ENABLE);
}
4.EEPROM_ReadByte读一字节
读一字节比写一字节多了2个步骤,原因是读的时候多写地址到读数据这个切换过程。
void EEPROM_ReadByte(uint16_t Addr, uint8_t *Data)
{
while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
/* 1.开始 */
I2C_GenerateSTART(ENABLE);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 2.设备地址/写 */
I2C_Send7bitAddress(EEPROM_DEV_ADDR, I2C_DIRECTION_TX);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* 3.数据地址 */
#if (8 == EEPROM_WORD_ADDR_SIZE)
I2C_SendData((Addr&0x00FF));
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
#else
I2C_SendData((uint8_t)(Addr>>8));
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData((uint8_t)(Addr&0x00FF));
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
#endif
/* 4.重新开始 */
I2C_GenerateSTART(ENABLE);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 5.设备地址/读 */
I2C_Send7bitAddress(EEPROM_DEV_ADDR, I2C_DIRECTION_RX);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* 6.读一字节数据 */
I2C_AcknowledgeConfig(I2C_ACK_NONE);
while(I2C_GetFlagStatus(I2C_FLAG_RXNOTEMPTY) == RESET);
*Data = I2C_ReceiveData();
/* 7.停止 */
I2C_GenerateSTOP(ENABLE);
}
Ⅳ、下载
STM8S资料:
http://pan.baidu.com/s/1o7Tb9Yq
软件源代码工程两版本(STM8S-A10_I2C读写EEPROM(硬件)):
http://pan.baidu.com/s/1c2EcRo0
提示:如果网盘链接失效,可以微信公众号“底部菜单”查看更新链接。
史海拾趣
|
涉及产品造型问题。无庸置疑,做FFT,DSP是首选,但ARM也有其很诱人的优势,想请教一下用ARM做过FFT的朋友,其速度如何?请告知一下所用的芯片型号、振荡器频率、FFT点数及运行时间。谢谢各位。… 查看全部问答> |
|
warning: function declared implicitly错误原因 error:function declared implicitly 解决方法:需在在头文件中用extern关键字声明函数 … 查看全部问答> |
|
CPU:E2200 主板:技嘉GA-G31M(板载X3100显卡,intel G31芯片组)(因为技嘉,华硕价格较贵,可以微星,昂达等G31芯片组的二组主板代替) 内存:金士顿2G,DDR2/800(或金邦,建议不要用威刚,威刚兼容性较差) 显卡:(如有需要可另配,但学习 ...… 查看全部问答> |
|
STM32F107中,用TIM3的PWM模式,预分频数为0,重装载值为3600,按道理说TIM3的最大频率为36MHz,那么PWM的频率应该 ...… 查看全部问答> |
|
毕业已一年又一个月,4年的大学时光,可以说我花在学习上的时间不少,基本上每门课都去学,搞到最后整体成绩还好,但每一门又不是很精通。所以现在工作中得恶补了,呵呵~记得在大三时开设了单片机课程,51的,还是汇编语言。当时就对单片机很好奇, ...… 查看全部问答> |
|
前两天我发了个帖子,说明LPC810如何用SWD方式(J-LINK)下载 于是我写了下程序,就是点亮那个LED的程序 #include \"lpc8xx.h\" int main(){ LPC_SYSCON->SYSAHBCLKCTRL |= (1DIR0|=1… 查看全部问答> |
|
现出让一套CY8CKIT-001 PSoC 开发套件,该套件是集PSoC 1、PSoC 3、PSoC 5三个系列的学习开发的,共包括一块主板、三块MCU模块、还有一个MINI PROR 程序下载下载器。下面上个图: … 查看全部问答> |




