历史上的今天
今天是:2024年08月29日(星期四)
2019年08月29日 | STM32F429 >> 12. I²C 通讯(Code)
2019-08-29 来源:eefocus
硬件I²C
在此我们使用硬件I²C 通讯,即使用I²C 外设帮助我们控制数据的发送和时钟的规律跳变。
若是使用模拟I²C 即是51 风格的编程,用程序手动控制两根总线的数据和时钟变化。
编程指南
初始化I²C GPIO引脚;
初始化I²C;
根据事件相应顺序编写相应的读/写操作程序;
编写页写入程序;(非必要)
编写缓冲区buffer 写入程序。(非必要)
bsp_i2c.h
/**
******************************************************************************
* @file bsp_i2c.h
* @author Waao
* @version V1.0.0
* @date 15-Jan-2019
* @brief This file contains some board support package's functions for the configuration of the I2C.
*
******************************************************************************
* @attention
*
* None
*
******************************************************************************
*/
#ifndef _BSP_I2C_H_
#define _BSP_I2C_H_
#include #include #include #include //=========================== I2C ================================== #define I2C_SCL_GPIO_PORT GPIOB #define I2C_SCL_GPIO_PIN GPIO_Pin_6 #define I2C_SCL_GPIO_PINSOURCE GPIO_PinSource6 #define I2C_SCL_GPIO_AF GPIO_AF_I2C1 #define I2C_SCL_GPIO_CLK RCC_AHB1Periph_GPIOB //AHB1 #define I2C_SDA_GPIO_PORT GPIOB #define I2C_SDA_GPIO_PIN GPIO_Pin_7 #define I2C_SDA_GPIO_PINSOURCE GPIO_PinSource7 #define I2C_SDA_GPIO_AF GPIO_AF_I2C1 #define I2C_SDA_GPIO_CLK RCC_AHB1Periph_GPIOB //AHB1 #define I2C_ I2C1 #define I2C_CLK RCC_APB1Periph_I2C1 //APB1 #define I2C_SPEED 400000 #define I2C_OWN_ADDRESS 0X01 /*This address just need to be differenent with the address of the device which communicated with the master.*/ //========================== EEPROM ================================== #define EEPROM_SCL_GPIO_PORT GPIOB #define EEPROM_SCL_GPIO_PIN GPIO_Pin_6 #define EEPROM_SDA_GPIO_PORT GPIOB #define EEPROM_SDA_GPIO_PIN GPIO_Pin_7 #define EEPROM_W_ADDRESS 0XA0 #define EEPROM_R_ADDRESS 0XA1 #define TIMEOUT (uint32_t)(0X1000) #define LONG_TIMEOUT (uint32_t)(10*TIMEOUT) #define I2C_PageSize 8 void I2C_FINAL_Config(void); void I2C_EE_WaitEepromStandByState(void); uint32_t I2C_TRANSMIT_Byte(u8 WriteAddr, u8* data); uint8_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite); void I2C_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite); uint32_t I2C_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead); #endif bsp_i2c.c /** ****************************************************************************** * @file bsp_i2c.c * @author Waao * @version V1.0.0 * @date 15-Jan-2019 * @brief This file contains some board support package's functions for the configuration of the I2C. * ****************************************************************************** * @attention * * None * ****************************************************************************** */ #include uint32_t timeout; /** * @brief Configure the I2C_GPIO * @param None * @retval None */ void I2C_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(I2C_SCL_GPIO_CLK, ENABLE); RCC_AHB1PeriphClockCmd(I2C_SDA_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN; GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN; GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStructure); GPIO_PinAFConfig(I2C_SCL_GPIO_PORT, I2C_SCL_GPIO_PINSOURCE, I2C_SCL_GPIO_AF); GPIO_InitStructure.GPIO_Pin = I2C_SDA_GPIO_PIN; GPIO_Init(I2C_SDA_GPIO_PORT, &GPIO_InitStructure); GPIO_PinAFConfig(I2C_SDA_GPIO_PORT, I2C_SDA_GPIO_PINSOURCE, I2C_SDA_GPIO_AF); } /** * @brief Configure the I2C * @param None * @retval None */ void I2C_Config(void) { I2C_InitTypeDef I2C_InitStructure; RCC_APB1PeriphClockCmd(I2C_CLK, ENABLE); I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C_OWN_ADDRESS; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Init(I2C_, &I2C_InitStructure); I2C_Cmd(I2C_, ENABLE); } /** * @brief Configure the I2C and I2C_GPIO * @param None * @retval None */ void I2C_FINAL_Config(void) { I2C_GPIO_Config(); I2C_Config(); } /** * @brief Error prompt function: When the program meet a error, this function will tell you the error code. * @param None * @retval None */ uint32_t TIME_OUT_CallBack(u8 STATE) { printf("The program has error, the error code is %dn", STATE); return 0; } /** * @brief Waiting the EEPROM to be ready. * @param None * @retval None */ void I2C_EE_WaitEepromStandByState(void) { uint16_t SR1_tmp = 0; do { I2C_GenerateSTART(I2C_, ENABLE); SR1_tmp = I2C_ReadRegister(I2C_, I2C_Register_SR1); I2C_Send7bitAddress(I2C_, EEPROM_W_ADDRESS, I2C_Direction_Transmitter); } while(!(I2C_ReadRegister(I2C_, I2C_Register_SR1) & 0x0002)); I2C_ClearFlag(I2C_, I2C_FLAG_AF); I2C_GenerateSTOP(I2C_, ENABLE); } /** * @brief Transmit a Byte to EEPROM through the I2C peripherals. * @param data: The data you want to transmit. * @retval None */ uint32_t I2C_TRANSMIT_Byte(u8 WriteAddr, u8* data) { I2C_GenerateSTART(I2C_, ENABLE); timeout = TIMEOUT; while(!I2C_CheckEvent(I2C_, I2C_EVENT_MASTER_MODE_SELECT)) //EV5 { timeout--; if(timeout == 0) return TIME_OUT_CallBack(0); } //Transmit the address which the EEPROM has. I2C_Send7bitAddress(I2C_, EEPROM_W_ADDRESS, I2C_Direction_Transmitter); timeout = TIMEOUT; while(!I2C_CheckEvent(I2C_, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EV6_TRANSMITTER { timeout--; if(timeout == 0) return TIME_OUT_CallBack(1); } //Transmit the internal address with the ROM of the EEPROM I2C_SendData(I2C_, WriteAddr); timeout = TIMEOUT; while(!I2C_CheckEvent(I2C_, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) //EV8_TRANSMITTING { timeout--; if(timeout == 0) return TIME_OUT_CallBack(2); } //Transmit the real data I2C_SendData(I2C_, *data); timeout = TIMEOUT; while(!I2C_CheckEvent(I2C_, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) //EV8_TRANSMITTING { timeout--; if(timeout == 0) return TIME_OUT_CallBack(3); } I2C_GenerateSTOP(I2C_, ENABLE); printf("Transmit successfully!"); return 1; } /** * @brief Transmit a page of data to EEPROM through the I2C * @param pBuffer: The pointer of the buffer. * WriteAddr: Write address. * NumByteToWrite: The number of bytes what we write. * @retval None */ uint8_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite) { timeout = LONG_TIMEOUT; //Check whether the I2C bus is busy or not while(I2C_GetFlagStatus(I2C_, I2C_FLAG_BUSY)) { timeout--; if(timeout-- == 0) return TIME_OUT_CallBack(8); } I2C_GenerateSTART(I2C_, ENABLE); timeout = TIMEOUT; while(!I2C_CheckEvent(I2C_, I2C_EVENT_MASTER_MODE_SELECT)) //EV5 { timeout--; if(timeout == 0) return TIME_OUT_CallBack(9); } I2C_Send7bitAddress(I2C_, EEPROM_W_ADDRESS, I2C_Direction_Transmitter); timeout = TIMEOUT; while(!(I2C_CheckEvent(I2C_, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))) //EV6_TRANSMISTTING { timeout--; if(timeout == 0) return TIME_OUT_CallBack(10); } I2C_SendData(I2C_, WriteAddr); timeout = TIMEOUT; while(!(I2C_CheckEvent(I2C_, I2C_EVENT_MASTER_BYTE_TRANSMITTED))) //EV8_2 { timeout--; if(timeout == 0) return TIME_OUT_CallBack(11); } for(;NumByteToWrite>0;NumByteToWrite--) { I2C_SendData(I2C_, *pBuffer); pBuffer++; timeout = TIMEOUT; while(!(I2C_CheckEvent(I2C_, I2C_EVENT_MASTER_BYTE_TRANSMITTED))) //EV8_2 { timeout--; if(timeout == 0) return TIME_OUT_CallBack(12); } } I2C_GenerateSTOP(I2C_, ENABLE); return 1; } /** * @brief Transmit the data to EEPROM from the buffer * @param pBuffer: The pointer of the buffer. * WriteAddr: Write address. * NumByteToWrite: The number of bytes what we write. * @retval None */ void I2C_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite) { u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0; //One page can full with 8 bytes data utmostly Addr = WriteAddr % I2C_PageSize; count = I2C_PageSize - Addr; NumOfPage = NumByteToWrite / I2C_PageSize; NumOfSingle = NumByteToWrite % I2C_PageSize; //We can write the data directly to a new page if(Addr == 0) { //The data can't make full of a page if(NumOfPage == 0) { I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); I2C_EE_WaitEepromStandByState(); } else { //We should make full of the whole page one by one while(NumOfPage--) { I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize); I2C_EE_WaitEepromStandByState();
史海拾趣
|
我在2440上移植了DM9000A的网卡,系统运行后能够被PING通。可是一运行IE就报如下错误: Data Abort: Thread=97d9aab4 Proc=81d96340 \'device.exe\' AKY=ffffffff PC=02b52178(dm9isa.dll+0x00002178) RA=02b52174(dm9isa.dll+0x00002174) BVA=06 ...… 查看全部问答> |
|
我现在需要用到2051接收来自PC的数据(长度不定,但长度信息是在接收的第一个字节里),打算用方式1,定时器2,串口超时了就表示接收已经完成,现在问题是:如何实现串口的超时处理? 是用另外一个定时器?还是在等待RI的过程中DJNZ某数以实现计时 ...… 查看全部问答> |
|
arm-linux平台上摄像头 quick capture interface的中断问题 我需要在pxa271平台上通过quick capture interface来获取摄像头图像,程序是从别的操作系统移植过来的,所以CIF寄存器初始化设置的逻辑应该没有问题,现在的问题是只要我设置了Start of Frame的中断,即 CICR0置位 ~(CICR0_SOFM), 再enable CIF接 ...… 查看全部问答> |
|
源例程,寻求帮助!!!谢谢 GPIO管脚能否配置采样速率? [ 本帖最后由 bjmonsoon 于 2011-1-13 19:35 编辑 ]… 查看全部问答> |
|
我在PB5.0下要修改代码,但是有的函数在其他文件里(例如在根目录下),我想看一下某个函数的实现体,我在函数上点击右键选择Go To Definition of \"函数名\", 但是出现对话框说要去project中的setting中设置, 我 ...… 查看全部问答> |




