STM32F407 模拟IIC读写EEPROM -- AT24C02

一.I2C 简介
I2C(内部集成电路)总线接口用作微控制器和 I2C 串行总线之间的接口。它提供多主模式功
能,可以控制所有 I2C 总线特定的序列、协议、仲裁和时序。它支持标准和快速模式。它还
与 SMBus 2.0 兼容。
它可以用于多种用途,包括 CRC 生成和验证、 SMBus(系统管理总线)以及 PMBus(电源
管理总线)。
根据器件的不同,可利用 DMA 功能来减轻 CPU 的工作量

二.IIC物理层
它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总
线中,可连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。
(2) 一个 I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线
(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。
(3) 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之
间的访问。
(4) 总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空
闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
5) 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用
总线。
(6) 具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式
下可达 3.4Mbit/s,但目前大多 I2C 设备尚不支持高速模式。
(7) 连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制

三.在IIC通信前,先把串口的代码贴出来,因为需要用到串口调试
1.bsp_debug_usart.h

#ifndef __DEBUG_USART_H
#define __DEBUG_USART_H
#include "stm32f4xx.h"
#include <stdio.h>

//引脚定义
/*******************************************************/
#define DEBUG_USART                             USART1
#define DEBUG_USART_CLK                         RCC_APB2Periph_USART1
#define DEBUG_USART_RX_GPIO_PORT                GPIOA
#define DEBUG_USART_RX_GPIO_CLK                 RCC_AHB1Periph_GPIOA
#define DEBUG_USART_RX_PIN                      GPIO_Pin_10
#define DEBUG_USART_RX_AF                       GPIO_AF_USART1
#define DEBUG_USART_RX_SOURCE                   GPIO_PinSource10
#define DEBUG_USART_TX_GPIO_PORT                GPIOA
#define DEBUG_USART_TX_GPIO_CLK                 RCC_AHB1Periph_GPIOA

#define DEBUG_USART_TX_PIN                      GPIO_Pin_9
#define DEBUG_USART_TX_AF                       GPIO_AF_USART1
#define DEBUG_USART_TX_SOURCE                   GPIO_PinSource9
/************************************************************/

//串口波特率
#define DEBUG_USART_BAUDRATE                    115200
void Debug_USART_Config(void);

#endif /* __USART1_H */

2.bsp_debug_usart.c

#include "bsp_debug_usart.h"

/*DEBUG_USART GPIO 配置,工作模式配置。115200 8-N-1*/
void Debug_USART_Config(void)
{
   
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;  
  RCC_AHB1PeriphClockCmd( DEBUG_USART_RX_GPIO_CLK|DEBUG_USART_TX_GPIO_CLK, ENABLE);
  
  /* 使能 UART 时钟 */
  RCC_APB2PeriphClockCmd(DEBUG_USART_CLK, ENABLE); 
  /* 连接 PXx 到 USARTx_Tx*/
  GPIO_PinAFConfig(DEBUG_USART_RX_GPIO_PORT,DEBUG_USART_RX_SOURCE, DEBUG_USART_RX_AF);
  /*  连接 PXx 到 USARTx__Rx*/
  GPIO_PinAFConfig(DEBUG_USART_TX_GPIO_PORT,DEBUG_USART_TX_SOURCE,DEBUG_USART_TX_AF);

  /* 配置Tx引脚为复用功能  */
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_PIN  ;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
 
  /* 配置Rx引脚为复用功能 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_PIN;
  GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);   
 
  /* 配置串DEBUG_USART 模式 */
  USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No ;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(DEBUG_USART, &USART_InitStructure); 
  USART_Cmd(DEBUG_USART, ENABLE);
}

///重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
   
  /* 发送一个字节数据到串口DEBUG_USART */
  USART_SendData(DEBUG_USART, (uint8_t) ch);  
  /* 等待发送完毕 */
  while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);   
  return (ch);
}

///重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
   
  /* 等待串口输入数据 */
  while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_RXNE) == RESET);
  return (int)USART_ReceiveData(DEBUG_USART);
}

四.IIC读写EEPROM过程
1.跟硬件相关的GPIO先用宏封装起来,方便移植,如图所示,我的原理图是用PB8和PB9作为IIC的两个引脚,下图是在STM32数据手册截图而来,我们设计原理图就要看这个

数据手册
STM32引脚
EEPROM引脚
AT24C02手册中的设备读写位
代码如下,包含AT24C02的设备地址读写位,IIC引脚的封装和一下函数的声明
IIC_GPIO.h

#ifndef _I2C_GPIO_H
#define _I2C_GPIO_H

#include "stm32f4xx.h"
#include "inttypes.h"

/*EEPROM写方向*/
#define EEPROM_I2C_WR  0
/*EEPROM读方向*/
#define EEPROM_I2C_RD  1

#define EEPROM_I2C_GPIO_PORT  GPIOB
#define EEPROM_I2C_GPIO_CLK   RCC_AHB1Periph_GPIOB 
#define EEPROM_I2C_SCL_PIN    GPIO_Pin_8 
#define EEPROM_I2C_SDA_PIN    GPIO_Pin_9

#define EEPROM_I2C_SCL_1() GPIO_SetBits(EEPROM_I2C_GPIO_PORT,EEPROM_I2C_SCL_PIN)
#define EEPROM_I2C_SCL_0() GPIO_ResetBits(EEPROM_I2C_GPIO_PORT,EEPROM_I2C_SCL_PIN)

#define
  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是STM32IIC模拟读写AT24c02的代码: ``` #include "stm32f10x.h" #include "delay.h" #define IIC_SCL_H GPIOB->BSRR = GPIO_Pin_10 #define IIC_SCL_L GPIOB->BRR = GPIO_Pin_10 #define IIC_SDA_H GPIOB->BSRR = GPIO_Pin_11 #define IIC_SDA_L GPIOB->BRR = GPIO_Pin_11 #define IIC_SDA GPIOB->IDR & GPIO_Pin_11 void IIC_Start() { IIC_SDA_H; IIC_SCL_H; delay_us(5); IIC_SDA_L; delay_us(5); IIC_SCL_L; } void IIC_Stop() { IIC_SDA_L; IIC_SCL_H; delay_us(5); IIC_SDA_H; delay_us(5); } void IIC_Ack() { IIC_SDA_L; delay_us(5); IIC_SCL_H; delay_us(5); IIC_SCL_L; IIC_SDA_H; } void IIC_NoAck() { IIC_SDA_H; delay_us(5); IIC_SCL_H; delay_us(5); IIC_SCL_L; } uint8_t IIC_WaitAck() { uint8_t ucErrTime = 0; IIC_SDA_H; delay_us(1); IIC_SCL_H; delay_us(1); while (IIC_SDA) { ucErrTime++; if (ucErrTime > 250) { IIC_Stop(); return 1; } } IIC_SCL_L; return 0; } void IIC_SendByte(uint8_t ucByte) { uint8_t i; for (i = 0; i < 8; i++) { if ((ucByte << i) & 0x80) { IIC_SDA_H; } else { IIC_SDA_L; } delay_us(1); IIC_SCL_H; delay_us(1); IIC_SCL_L; } } uint8_t IIC_ReadByte() { uint8_t i, ucByte = 0; IIC_SDA_H; for (i = 0; i < 8; i++) { ucByte <<= 1; IIC_SCL_H; delay_us(1); if (IIC_SDA) { ucByte |= 0x01; } IIC_SCL_L; delay_us(1); } return ucByte; } void IIC_Init() { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); IIC_SDA_H; IIC_SCL_H; } void AT24C02_WriteByte(uint8_t ucAddr, uint8_t ucData) { IIC_Start(); IIC_SendByte(0xa0); IIC_WaitAck(); IIC_SendByte(ucAddr); IIC_WaitAck(); IIC_SendByte(ucData); IIC_WaitAck(); IIC_Stop(); delay_ms(10); } uint8_t AT24C02_ReadByte(uint8_t ucAddr) { uint8_t ucData; IIC_Start(); IIC_SendByte(0xa0); IIC_WaitAck(); IIC_SendByte(ucAddr); IIC_WaitAck(); IIC_Start(); IIC_SendByte(0xa1); IIC_WaitAck(); ucData = IIC_ReadByte(); IIC_NoAck(); IIC_Stop(); return ucData; } int main(void) { uint8_t ucData; IIC_Init(); AT24C02_WriteByte(0x00, 0x55); ucData = AT24C02_ReadByte(0x00); while (1); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值