STM32下模拟I2C的C语言实现
2011-12-05 11:13
387 查看
近来主要在写一些STM32上的开发程序,由于STM32的固件库中,I2C模块实在是不好用,所以在采用了软件模拟的方法来实现。
具体的代码如下(在Keil下调试通过):
具体的代码如下(在Keil下调试通过):
#include "stm32f10x_lib.h" //条件编译 1:使用软件模拟I2C //#define PIN_SCL GPIO_Pin_6 //#define PIN_SDA GPIO_Pin_7 static __inline void TWI_SCL_0(void) { GPIOB->BRR=PIN_SCL; } static __inline void TWI_SCL_1(void) { GPIOB->BSRR=PIN_SCL;} static __inline void TWI_SDA_0(void) { GPIOB->BRR=PIN_SDA; } static __inline void TWI_SDA_1(void) { GPIOB->BSRR=PIN_SDA;} static __inline u8 TWI_SDA_STATE(void) { return (GPIOB->IDR & PIN_SDA) != 0; } //static __inline void TWI_NOP(void) { TWI_Delay(); } static const u8 TWI_ACK =0; static const u8 TWI_READY =0; static const u8 TWI_NACK =1; static const u8 TWI_BUS_BUSY =2; static const u8 TWI_BUS_ERROR =3; static const u8 TWI_RETRY_COUNT = 3; //重试次数 extern void Delay_mS(u32 n); static void TWI_Initialize(void); static u8 TWI_START(void); static u8 TWI_START_SHT(void); static void TWI_STOP(void); static u8 TWI_SendByte(u8 Data); static u8 TWI_ReceiveByte(void); static void TWI_SendACK(void); static void TWI_SendNACK(void); /******************************************************************************* * 函数名称:TWI_Delay * 描 述:延时函数 * * 输 入:无 * 输 出:无 * 返 回:无 * 作 者: * 修改日期:2010年6月8日 *******************************************************************************/ static void TWI_NOP(void) { vu32 i, j; vu32 sum = 0; i = 20; while(i--) { for (j = 0; j < 10; j++) sum += i; } sum = i; } /******************************************************************************* * 函数名称:TWI_Initialize * 描 述:I2C初始化函数 * * 输 入:无 * 输 出:无 * 返 回:无 * 作 者: * 修改日期:2010年6月8日 *******************************************************************************/ static void TWI_Initialize(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Pin = PIN_SDA; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = PIN_SCL; GPIO_Init(GPIOB, &GPIO_InitStructure); TWI_SDA_1(); TWI_SCL_0(); //////DebugPrint("Software TWI Initializing...\n"); } /******************************************************************************* * 函数名称:TWI_START * 描 述:发送启动 * * 输 入:无 * 输 出:无 * 返 回:无 * 作 者: * 修改日期:2010年6月8日 *******************************************************************************/ static u8 TWI_START(void) { TWI_SDA_1(); TWI_NOP(); TWI_SCL_1(); TWI_NOP(); if(!TWI_SDA_STATE()) { ////DebugPrint("TWI_START:BUSY\n"); return TWI_BUS_BUSY; } TWI_SDA_0(); TWI_NOP(); TWI_SCL_0(); TWI_NOP(); if(TWI_SDA_STATE()) { ////DebugPrint("TWI_START:BUS ERROR\n"); return TWI_BUS_ERROR; } return TWI_READY; } /* --------------------------------------------------------------------------*/ /** * @Brief: TWI_START_SHT * * @Returns: */ /* --------------------------------------------------------------------------*/ static u8 TWI_START_SHT(void) { TWI_SDA_1(); TWI_SCL_0(); TWI_NOP(); TWI_SDA_1(); TWI_SCL_1(); TWI_NOP(); if(!TWI_SDA_STATE()) { return TWI_BUS_BUSY; } TWI_SDA_0(); TWI_NOP(); TWI_SCL_0(); TWI_NOP(); TWI_SCL_1(); TWI_NOP(); TWI_SDA_1(); TWI_NOP(); TWI_SCL_0(); TWI_NOP(); return TWI_READY; } /* --------------------------------------------------------------------------*/ /** * @Brief: TWI_STOP */ /* --------------------------------------------------------------------------*/ static void TWI_STOP(void) { TWI_SDA_0(); TWI_NOP(); TWI_SCL_1(); TWI_NOP(); TWI_SDA_1(); TWI_NOP(); //////DebugPrint("TWI_STOP\n"); } /* --------------------------------------------------------------------------*/ /** * @Brief: TWI_SendACK */ /* --------------------------------------------------------------------------*/ static void TWI_SendACK(void) { TWI_SDA_0(); TWI_NOP(); TWI_SCL_1(); TWI_NOP(); TWI_SCL_0(); TWI_NOP(); TWI_SDA_1(); //////DebugPrint("TWI_SendACK\n"); } /* --------------------------------------------------------------------------*/ /** * @Brief: TWI_SendNACK */ /* --------------------------------------------------------------------------*/ static void TWI_SendNACK(void) { TWI_SDA_1(); TWI_NOP(); TWI_SCL_1(); TWI_NOP(); TWI_SCL_0(); TWI_NOP(); //////DebugPrint("TWI_SendNACK\n"); } /* --------------------------------------------------------------------------*/ /** * @Brief: TWI_SendByte * * @Param: Data * * @Returns: */ /* --------------------------------------------------------------------------*/ static u8 TWI_SendByte(u8 Data) { u8 i; TWI_SCL_0(); for(i=0;i<8;i++) { //---------数据建立---------- if(Data&0x80) { TWI_SDA_1(); } else { TWI_SDA_0(); } Data<<=1; TWI_NOP(); //---数据建立保持一定延时---- //----产生一个上升沿[正脉冲] TWI_SCL_1(); TWI_NOP(); TWI_SCL_0(); TWI_NOP();//延时,防止SCL还没变成低时改变SDA,从而产生START/STOP信号 //--------------------------- } //接收从机的应答 TWI_SDA_1(); TWI_NOP(); TWI_SCL_1(); TWI_NOP(); if(TWI_SDA_STATE()) { TWI_SCL_0(); TWI_SDA_1(); //////DebugPrint("TWI_NACK!\n"); return TWI_NACK; } else { TWI_SCL_0(); TWI_SDA_1(); //////DebugPrint("TWI_ACK!\n"); return TWI_ACK; } } /* --------------------------------------------------------------------------*/ /** * @Brief: TWI_ReceiveByte * * @Returns: */ /* --------------------------------------------------------------------------*/ static u8 TWI_ReceiveByte(void) { u8 i,Dat; TWI_SDA_1(); TWI_SCL_0(); Dat=0; for(i=0;i<8;i++) { TWI_SCL_1();//产生时钟上升沿[正脉冲],让从机准备好数据 TWI_NOP(); Dat<<=1; if(TWI_SDA_STATE()) //读引脚状态 { Dat|=0x01; } TWI_SCL_0();//准备好再次接收数据 TWI_NOP();//等待数据准备好 } //////DebugPrint("TWI_Dat:%x\n",Dat); return Dat; }
相关文章推荐
- STM32下模拟I2C的C语言实现
- C语言模拟通讯录系统的简单实现
- stm32软件模拟I2C
- 用C语言实现对N个进程的简单时间片轮转法Round Robin的调度模拟
- STM32--模拟I2C_2402--SDA_H,SDA_L
- c语言实现数据结构中的栈(数组模拟)
- C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现
- 位带操作在stm32中的C语言实现
- c语言:模拟实现printf,要求功能:print(&quot;ccc\ts!&quot;,&#39;b&#39;,&#39;i&#39;,&#39;t&#39;,&quot;welcome to you&quot;);
- STM32 SPI 模拟实现 W25X16读写代码
- c语言数组模拟实现排列组合
- C语言:模拟实现strstr函数,若是子串,输出子串后面的字符串,否则输出null
- 模拟实现C语言中的内存管理
- C语言模拟实现memcpy,memmove函数
- 【C语言】【面试题】【笔试题】模拟实现数据库中memmove函数
- 【C语言】【面试题】【笔试题】模拟实现数据库中strcmp函数
- C语言模拟实现atoi函数
- C语言~模拟实现通用冒泡排序
- 三子棋游戏C语言模拟实现
- 【C语言】【面试题】【笔试题】模拟实现strncmp