完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
使用硬件I2C的说明
STM32F0使用硬件I2C作为master,与外设通信,code步骤如下: 配置GPIO引脚功能 初始化I2C外设 调用I2C的外设库函数进行读写I2C 下面是详细代码: 1. 配置GPIO引脚功能 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; 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_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_1); 这里外设控制时钟使用了AHB总线时钟,PB8、9脚复用了I2C功能GPIO_AF_1,注意使用了开漏的脚位设置,实际电路上8、9两脚上要上拉10K电阻 2. 初始化I2C外设 I2C_InitTypeDef I2C_InitStructure; RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; I2C_InitStructure.I2C_DigitalFilter = 0x00; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_Timing = 0x30E32E44; I2C_Init(I2C1, &I2C_InitStructure); I2C_Cmd(I2C1, ENABLE); 这里工作时钟使用了系统时钟RCC_I2C1CLK_SYSCLK,注意I2C_Timing时钟寄存器的值需要使用ST官方工具来计算 3. 调用I2C的外设库函数进行读写I2C 可以使用查询状态寄存器方式 主要库函数有: (1).void I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode) (2)uint8_t I2C_ReceiveData ( I2C_TypeDef * I2Cx ) (3)void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) 详细说明可看标准外设库帮助文档 I2C读设备数据 /** * @brief 从I2C1总线上的某一器件的某一起始地址中读取一定字节的数据到数组中 * @param driver_Addr:I2C器件地址 * @param start_Addr:起始字节地址 * @param number_Bytes:要读取的字节数量(小于一页) * @param read_Buffer:存放读取数据的数组指针 * @retval 是否读取成功 */ I2C_Status I2C1_Read_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *read_Buffer) { uint8_t read_Num; I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_TransferHandling(I2C1, driver_Addr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_SendData(I2C1, start_Addr); I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_TransferHandling(I2C1, driver_Addr, number_Bytes, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); for(read_Num = 0; read_Num 《 number_Bytes; read_Num++) { I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } read_Buffer[read_Num] = I2C_ReceiveData(I2C1); } I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } return I2C_OK; } I2C写设备数据 /** * @brief 从I2C1的总线上的某一器件的某一起始地址中读取一定字节的数据到数组中 * @param driver_Addr:I2C器件地址 * @param start_Addr:起始字节地址 * @param number_Bytes:要读取的字节数量(小于一页) * @param write_Buffer:存放读取数据的数组指针 * @retval 是否读取成功 */ I2C_Status I2C1_Write_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *write_Buffer) { uint8_t write_Num; I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_TransferHandling(I2C1, driver_Addr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_SendData(I2C1, start_Addr); I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TCR) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_TransferHandling(I2C1, driver_Addr, number_Bytes, I2C_AutoEnd_Mode, I2C_No_StartStop); for(write_Num = 0; write_Num 《 number_Bytes; write_Num++) { I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_SendData(I2C1, write_Buffer[write_Num]); } I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } return I2C_OK; } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
645浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
516浏览 3评论
532浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
505浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 11:26 , Processed in 0.784208 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号