STM32模拟IIC
2017-07-23 17:21
288 查看
IIC.h
#ifndef _MD_IIC_h_ #define _MD_IIC_h_ #include "stm32f10x.h" /* Pin Definiton ---------- */ #define IIC_GPIO (GPIOC) #define IIC_GOIO_SDA (GPIOC) #define IIC_GPIO_SCL (GPIOC) #define IIC_SDA (GPIO_Pin_2) #define IIC_SCL (GPIO_Pin_1) //初始化调用IIC_GPIO_Configuration( IIC_GOIO_SDA , IIC_SDA , IIC_GPIO_SCL , IIC_SCL ); extern void IIC_GPIO_Configuration( GPIO_TypeDef * GPIOx_SDA , uint16_t SDA_Pin , GPIO_TypeDef * GPIOx_SCL , uint16_t SCL_Pin ); //使用软件模拟I2C #define SET_SDA { GPIO_SetBits ( IIC_GPIO , IIC_SDA ); } #define RESET_SDA { GPIO_ResetBits( IIC_GPIO , IIC_SDA ); } #define SET_SCL { GPIO_SetBits ( IIC_GPIO , IIC_SCL ); } #define RESET_SCL { GPIO_ResetBits( IIC_GPIO , IIC_SCL) ; } #define IIC_SDA_STATE (IIC_GPIO->IDR&IIC_SDA) #define IIC_SCL_STATE (IIC_GPIO->IDR&IIC_SDA) #define IIC_DELAY { IIC_Delay(); } enum IIC_REPLAY_ENUM { IIC_NACK = 0, IIC_ACK = 1 }; enum IIC_BUS_STATE_ENUM { IIC_BUS_READY = 0, IIC_BUS_BUSY=1, IIC_BUS_ERROR=2 }; //IIC 延时 extern void IIC_Delay(void); //IIC 启动函数 extern u8 IIC_Start(void); //IIC 停止函数 extern void IIC_Stop(void); //IIC 发送动作 extern void IIC_SendACK(void); //IIC 停止动作 extern void IIC_SendNACK(void); //IIC 发送单字节 extern u8 IIC_SendByte(u8 Data); //IIC 接收单字节 extern u8 IIC_RecvByte(void); //IIC 写入单字节 extern void Single_Write_IIC(u8 SlaveAddress,u8 REG_Address,u8 REG_data); //IIC 读取单字节 extern u8 Single_Read_IIC(u8 SlaveAddress, u8 REG_Address); //GPIO 过滤器 extern uint16_t GPIO_Filter( GPIO_TypeDef * GPIOx ); #endif /* _MD_IIC_H_ */ /* End of file ------------------------------------------------------------- */
IIC.c
#include "stm32f10x.h" #include "MD_IIC.h" void IIC_GPIO_Configuration( GPIO_TypeDef * GPIOx_SDA , uint16_t SDA_Pin , GPIO_TypeDef * GPIOx_SCL , uint16_t SCL_Pin ) { GPIO_InitTypeDef GPIO_InitStructure; uint32_t RCC_GPIOx_SDA = 0; uint32_t RCC_GPIOx_SCL = 0; //得到滤波后的引脚端口 RCC_GPIOx_SDA = GPIO_Filter( GPIOx_SDA ); RCC_GPIOx_SCL = GPIO_Filter( GPIOx_SCL ); //使能时钟 RCC_APB2PeriphClockCmd(RCC_GPIOx_SDA,ENABLE); RCC_APB2PeriphClockCmd(RCC_GPIOx_SCL,ENABLE); //配置引脚 GPIO_InitStructure.GPIO_Pin = SDA_Pin; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD; GPIO_Init(GPIOx_SDA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = SCL_Pin; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD; GPIO_Init(GPIOx_SCL, &GPIO_InitStructure); //初始化ICC的模式 SET_SDA; SET_SCL; } void IIC_Delay(void) { u32 i = 5; while( i-- ); } u8 IIC_Start(void) { SET_SDA; IIC_DELAY; SET_SCL; IIC_DELAY; if( IIC_SDA_STATE == RESET ) { return IIC_BUS_BUSY; } RESET_SDA; IIC_DELAY; RESET_SCL; IIC_DELAY; if( IIC_SDA_STATE == SET ) { return IIC_BUS_ERROR; } return IIC_BUS_READY; } void IIC_Stop(void) { RESET_SDA; IIC_DELAY; SET_SCL; IIC_DELAY; SET_SDA; IIC_DELAY; } /* 收到数据,发送NACK - */ void IIC_SendNACK(void) { RESET_SDA; IIC_DELAY; SET_SCL; IIC_DELAY; RESET_SCL; IIC_DELAY; } /* 收到数据,发送ACK -- */ void IIC_SendACK(void) { SET_SDA; IIC_DELAY; SET_SCL; IIC_DELAY; RESET_SCL; IIC_DELAY; } /* 发送一个字节 ----------------------------------------------------------- */ u8 IIC_SendByte(u8 Data) { u8 i; RESET_SCL; for(i=0;i<8;i++) { //数据建立 if(Data&0x80) { SET_SDA; } else { RESET_SDA; } Data<<=1; IIC_DELAY; //数据建立保持一定延时 SET_SCL; //产生一个上升沿[正脉冲] IIC_DELAY; RESET_SCL; IIC_DELAY; //延时,防止SCL还没变成低时改变SDA,从而产生START/STOP信号 } //接收从机的应答 SET_SDA; IIC_DELAY; SET_SCL; IIC_DELAY; if(IIC_SDA_STATE) { RESET_SCL; return IIC_NACK; } else { RESET_SCL; return IIC_ACK; } } /* 接收一个字节 ----------------------------------------- */ u8 IIC_RecvByte(void) { u8 i,Dat = 0; SET_SDA; RESET_SCL; Dat=0; for(i=0;i<8;i++) { SET_SCL; //产生时钟上升沿[正脉冲],让从机准备好数据 IIC_DELAY; Dat<<=1; if(IIC_SDA_STATE) //读引脚状态 { Dat|=0x01; } RESET_SCL; //准备好再次接收数据 IIC_DELAY; //等待数据准备好 } return Dat; } /* 单字节写入 -------------------------------------------------------- */ void Single_Write_IIC(u8 SlaveAddress,u8 REG_Address,u8 REG_data) { IIC_Start(); //起始信号 IIC_SendByte(SlaveAddress); //发送设备地址+写信号 IIC_SendByte(REG_Address); //内部寄存器地址, //请参考中文pdf22页 IIC_SendByte(REG_data); //内部寄存器数据, //请参考中文pdf22页 IIC_Stop(); //发送停止信号 } /* 单字节读取 --------------------------------------------------------- */ u8 Single_Read_IIC(u8 SlaveAddress, u8 REG_Address) { u8 REG_data; IIC_Start(); //起始信号 IIC_SendByte(SlaveAddress); //发送设备地址+写信号 IIC_SendByte(REG_Address); //发送存储单元地址,//从0开始 IIC_Start(); //起始信号 IIC_SendByte(SlaveAddress+1); //发送设备地址+读信号 REG_data = IIC_RecvByte(); //读出寄存器数据 IIC_SendACK(); IIC_Stop(); //停止信号 return REG_data; } //引脚端口过滤器 返回值为 引脚端口的时钟编号 uint16_t GPIO_Filter( GPIO_TypeDef * GPIOx ) { uint32_t RCC_GPIOx = 0; if( GPIOx == GPIOA ) { RCC_GPIOx = RCC_APB2Periph_GPIOA; } else if( GPIOx == GPIOA ) { RCC_GPIOx = RCC_APB2Periph_GPIOA; } else if( GPIOx == GPIOB ) { RCC_GPIOx = RCC_APB2Periph_GPIOB; } else if( GPIOx == GPIOC ) { RCC_GPIOx = RCC_APB2Periph_GPIOC; } else if( GPIOx == GPIOD ) { RCC_GPIOx = RCC_APB2Periph_GPIOD; } else if( GPIOx == GPIOE ) { RCC_GPIOx = RCC_APB2Periph_GPIOE; } else if( GPIOx == GPIOF ) { RCC_GPIOx = RCC_APB2Periph_GPIOF; } else if( GPIOx == GPIOG ) { RCC_GPIOx = RCC_APB2Periph_GPIOG; } return RCC_GPIOx; }
相关文章推荐
- 基于STM32平台的BMP180测试(模拟IIC)
- IIC 时序分析,stm32软件模拟驱动编写
- STM32 IO 模拟IIC I2C
- 基于stm32单片机的模拟IIC时序(附源码)
- stm32模拟iic——引脚配置、代码
- STM32模拟IIC读写24CXX
- STM32 模拟IIC主设备 非IIC静默模式
- stm32模拟iic——引脚配置、代码
- STM32-IIC模拟从模式
- STM32模拟IIC读写AT24CXX
- STM32 IIC 通信 模拟方式
- 【Hardware】STM32软件模拟IIC
- STM32模拟 IIC
- 关于STM32 的 硬件IIC和 模拟IIC理解学习
- STM32模拟IIC
- stm32模拟iic——引脚配置、代码
- 关于STM32模拟IIC的理解
- STM32软件模拟IIC
- STM32硬件IIC操作 (转)
- C语言模拟IIC