链接:https://pan.baidu.com/s/1wxbQTMlnX2pavrbW2RYg4g 提取码:dxex 注意:延时函数使用了FreeRTOS的vTaskDelay任务延时函数 需包含头文件 board_i2c.h IIC_Init IIC_Start IIC_Stop IIC_SendByte IIC_ReadByte IIC_WaitAck IIC_Ack IIC_NAck IIC_CheckDevice 1)添加头文件 2)添加初始化代码 • 由 Leung 写于 2020 年 6 月 15 日
一、硬件连接
功能口
引脚
SCL
PB.6
SDA
PB.5
二、移植文件
将 board_i2c.c 和 board_i2c.h 两个文件加入工程的User文件夹下2.1 board_i2c.c
/********************************************************************* * INCLUDES */ #include "FreeRTOS.h" #include "task.h" #include "board_i2c.h" #include "board_systick.h" static void SDA_OUT_MODE(void); static void SDA_IN_MODE(void); /********************************************************************* * PUBLIC FUNCTIONS */ /** @brief I2C驱动初始化,采用模拟IO的方式实现 @param 无 @return 无 */ void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(IIC_SCL_CLK | IIC_SDA_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = IIC_SCL_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(IIC_SCL_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN; GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure); IIC_Stop(); // 给一个停止信号, 复位I2C总线上的所有设备到待机模式 } /** @brief CPU发起I2C总线启动信号 @param 无 @return 无 */ void IIC_Start(void) { SDA_OUT_MODE(); // SDA线输出模式 IIC_SDA_1(); IIC_SCL_1(); vTaskDelay(1); IIC_SDA_0(); // 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 vTaskDelay(1); IIC_SCL_0(); // 钳住I2C总线,准备发送或接收数据 } /** @brief CPU发起I2C总线停止信号 @param 无 @return 无 */ void IIC_Stop(void) { SDA_OUT_MODE(); // SDA线输出模式 IIC_SCL_0(); IIC_SDA_0(); IIC_SCL_1(); vTaskDelay(1); IIC_SDA_1(); // 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 vTaskDelay(1); } /** @brief CPU向I2C总线设备发送8bit数据 @param ucByte -[in] 等待发送的字节 @return 无 */ void IIC_SendByte(uint8_t ucByte) { uint8_t i; SDA_OUT_MODE(); // SDA线输出模式 IIC_SCL_0(); // 拉低时钟开始数据传输 for(i = 0; i < 8; i++) { if(ucByte & 0x80) { IIC_SDA_1(); } else { IIC_SDA_0(); } ucByte <<= 1; vTaskDelay(1); IIC_SCL_1(); vTaskDelay(1); IIC_SCL_0(); vTaskDelay(1); } } /** @brief CPU从I2C总线设备读取8bit数据 @param 无 @return 读到的数据 */ uint8_t IIC_ReadByte(void) { uint8_t i = 0; uint8_t value = 0; SDA_IN_MODE(); // SDA线输入模式 for(i = 0; i < 8; i++) { value <<= 1; IIC_SCL_1(); vTaskDelay(1); if(IIC_SDA_READ()) { value++; } IIC_SCL_0(); vTaskDelay(1); } IIC_Ack(); return value; } /** @brief CPU产生一个时钟,并读取器件的ACK应答信号 @param 无 @return 返回0表示正确应答,1表示无器件响应 */ uint8_t IIC_WaitAck(void) { uint8_t result = 0; SDA_IN_MODE(); // SDA线输入模式 IIC_SDA_1(); // CPU释放SDA总线 vTaskDelay(1); IIC_SCL_1(); // CPU驱动SCL = 1, 此时器件会返回ACK应答 vTaskDelay(1); if(IIC_SDA_READ()) { result = 1; } else { result = 0; } IIC_SCL_0(); vTaskDelay(1); return result; } /** @brief CPU产生一个ACK信号 @param 无 @return 无 */ void IIC_Ack(void) { SDA_OUT_MODE(); // SDA线输出模式 IIC_SDA_0(); // CPU驱动SDA = 0 vTaskDelay(1); IIC_SCL_1(); // CPU产生1个时钟 vTaskDelay(1); IIC_SCL_0(); vTaskDelay(1); IIC_SDA_1(); // CPU释放SDA总线 } /** @brief CPU产生1个NACK信号 @param 无 @return 无 */ void IIC_NAck(void) { SDA_OUT_MODE(); // SDA线输出模式 IIC_SDA_1(); // CPU驱动SDA = 1 vTaskDelay(1); IIC_SCL_1(); // CPU产生1个时钟 vTaskDelay(1); IIC_SCL_0(); vTaskDelay(1); } /** @brief 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在 @param address -[in] 设备的I2C总线地址+读写控制bit(0 = w, 1 = r) @return 0 - 表示正确, 1 - 表示未探测到 */ uint8_t IIC_CheckDevice(uint8_t address) { uint8_t ucAck; IIC_Init(); // 初始化I2C IIC_Start(); // 发送启动信号 IIC_SendByte(address); // 设备的I2C总线地址+读写控制bit(0 = w, 1 = r) ucAck = IIC_WaitAck(); // 检测设备的ACK应答 IIC_Stop(); // 发送停止信号 return ucAck; } /********************************************************************* * LOCAL FUNCTIONS */ /** @brief SDA输出配置 @param 无 @return 无 */ static void SDA_OUT_MODE(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure); } /** @brief SDA输入配置 @param 无 @return 无 */ static void SDA_IN_MODE(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure); } /****************************************************END OF FILE****************************************************/
2.2 board_i2c.h
#ifndef _BOARD_I2C_H_ #define _BOARD_I2C_H_ /********************************************************************* * INCLUDES */ #include "stm32f10x.h" /********************************************************************* * DEFINITIONS */ // I2C_SCL时钟 #define IIC_SCL_CLK RCC_APB2Periph_GPIOB // GPIO端口时钟 #define IIC_SCL_PORT GPIOB // GPIO端口 #define IIC_SCL_PIN GPIO_Pin_6 // GPIO引脚 // I2C_SDA时钟 #define IIC_SDA_CLK RCC_APB2Periph_GPIOB // GPIO端口时钟 #define IIC_SDA_PORT GPIOB // GPIO端口 #define IIC_SDA_PIN GPIO_Pin_5 // GPIO引脚 /********************************************************************* * MACROS */ #define IIC_SCL_0() GPIO_ResetBits(IIC_SCL_PORT, IIC_SCL_PIN) #define IIC_SCL_1() GPIO_SetBits(IIC_SCL_PORT, IIC_SCL_PIN) #define IIC_SDA_0() GPIO_ResetBits(IIC_SDA_PORT, IIC_SDA_PIN) #define IIC_SDA_1() GPIO_SetBits(IIC_SDA_PORT, IIC_SDA_PIN) #define IIC_SDA_READ() GPIO_ReadInputDataBit(IIC_SDA_PORT, IIC_SDA_PIN) /********************************************************************* * API FUNCTIONS */ void IIC_Init(void); void IIC_Start(void); void IIC_Stop(void); void IIC_SendByte(uint8_t ucByte); uint8_t IIC_ReadByte(void); uint8_t IIC_WaitAck(void); void IIC_Ack(void); void IIC_NAck(void); uint8_t IIC_CheckDevice(uint8_t address); #endif /* _BOARD_I2C_H_ */
三、API调用
功能
I2C驱动初始化,采用模拟IO的方式实现
函数定义
void IIC_Init(void)
参数
无
返回
无
功能
CPU发起I2C总线启动信号
函数定义
void IIC_Start(void)
参数
无
返回
无
功能
CPU发起I2C总线停止信号
函数定义
void IIC_Stop(void)
参数
无
返回
无
功能
CPU向I2C总线设备发送8bit数据
函数定义
void IIC_SendByte(uint8_t ucByte)
参数
ucByte:等待发送的字节
返回
无
功能
CPU从I2C总线设备读取8bit数据
函数定义
uint8_t IIC_ReadByte(void)
参数
无
返回
读到的数据
功能
CPU产生一个时钟,并读取器件的ACK应答信号
函数定义
uint8_t IIC_WaitAck(void)
参数
无
返回
0表示正确应答,1表示无器件响应
功能
CPU产生一个ACK信号
函数定义
void IIC_Ack(void)
参数
无
返回
无
功能
CPU产生1个NACK信号
函数定义
void IIC_NAck(void)
参数
无
返回
无
功能
检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
函数定义
uint8_t IIC_CheckDevice(uint8_t address)
参数
address:设备的I2C总线地址+读写控制bit(0 = w, 1 = r)
返回
0 – 表示正确, 1 – 表示未探测到
四、使用例子
#include "board_i2c.h"
int main(void) { BaseType_t xReturn = pdPASS; // 定义一个创建信息返回值,默认为pdPASS /*-------------------------- 外设驱初始化 ---------------------------*/ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,都统一用这个优先级分组,千万不要再分组,切忌 Board_LedInit(); // LED灯驱动初始化 Board_KeyInit(); // 按键驱动初始化 USART_Config(); // 串口驱动初始化 printf("-------------- I2C Init--------------rn"); // 这里写入设备的I2C总线地址 uint8_t i2cDevice = IIC_CheckDevice(TEA5767_ADDR_W); // 初始化I2C,并检测是否有设备 if(!i2cDevice) { printf("---- I2C OK ----rn"); } else { printf("---- I2C ERROR ----rn"); } /*-------------------------- 任务创建 ---------------------------*/ xReturn = xTaskCreate((TaskFunction_t)appTaskCreate, // 任务入口函数 (const char* )"appTaskCreate", // 任务名字 (uint16_t )512, // 任务栈大小 (void* )NULL, // 任务入口函数参数 (UBaseType_t )1, // 任务的优先级 (TaskHandle_t* )&s_appTaskCreateHandle); // 任务控制块指针 /*-------------------------- 开启调度 ---------------------------*/ if(pdPASS == xReturn) { vTaskStartScheduler(); } else { return -1; } while(1) { /* 正常不会执行到这里 */ }; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算