链接: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网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算
 官方软件产品操作指南 (170)
官方软件产品操作指南 (170)