STM8S_010_I2C读写EEPROM(硬件方式)

来源:互联网 发布:淘宝店铺过户给别人 编辑:程序博客网 时间:2024/05/16 05:03

相关标题:STM8 I2C EEPROM 硬件I2C


Ⅰ、写在前面

相信看过前面那篇文章更加深入理解I2C总线、协议及应用”的人对I2C都有一定的了解了。那篇文章是针对I2C,使用单片机IO模拟I2C方式实现读写操作。

本文将讲述硬件I2C读写操作,也就是由处理器自身硬件的I2C实现时钟、数据的传输过程。

 

为方便大家阅读,本文内容已经整理成PDF文件:

http://pan.baidu.com/s/1i5uWhJR

 

作者:strongerHuang

版权所有,未经允许,禁止用于其它商业用途!!!

 

Ⅱ、STM8硬件I2C知识

STM8SI2C模块不仅可以接收和发送数据,还可以在接收时将数据从串行转换成并行数据,在发送时将数据从并行转换成串行数据。可以开启或禁止中断。接口通过数据引脚(SDA)和时钟引脚(SCL)连接到I2C总线。允许连接到标准(最高100kHz)或快速(最高400kHz)I2C总线。

1.I2C4种模式

● 从设备发送模式

● 从设备接收模式

● 主设备发送模式

● 主设备接收模式

 

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_SPEEDI2C速度,一般是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

 

提示:如果网盘链接失效,可以微信公众号“底部菜单”查看更新链接

Ⅴ、最后

微信搜索EmbeddDeveloper” 或者扫描下面二维码、关注,在我的底部菜单查看更多精彩内容!

 


原创粉丝点击