您的当前位置:首页STM32F10X--模拟IIC程序

STM32F10X--模拟IIC程序

来源:小侦探旅游网
STM32F10X--模拟IIC程序

听说STM32的IIC硬件做的很鸡肋,所以在这⾥通过模拟的⽅式实现IIC协议。此程序能成功对AT24C02操作。程序中的带参数宏 IIC_DELAY(time)的功能是延时time us,在实际中具体场合具体分析。宏定义⽂件--IIC.h

#ifndef _IIC_#define _IIC_

#include \"SysTick.h\"#include \"stm32f10x.h\"#include \"SystemConfig.h\"/* 配置IIC的SDA、SCL两个端⼝ */#define IIC_SCL_IO GPIO_Pin_6#define IIC_SDA_IO GPIO_Pin_7

/* SDA端⼝动态改变输⼊输出状态定义 */

#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X80000000;} //配置上拉输⼊#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X30000000;} //配置推挽输出/* IIC 操作定义 */

#define IIC_SDA PBOUT(7)  //定义的STM32位操作#define READ_SDA PBIN(7)#define IIC_SCL PBOUT(6)

#define IIC_DELAY(time) delay(time)

/* 定义的函数原型 */void IIC_IOInit(void);void IIC_Start(void);void IIC_Stop(void);

unsigned char IIC_Wait_Ack(void);void IIC_NoAck(void);void IIC_Ack(void);

void IIC_Send_Byte(unsigned char txd);

unsigned char IIC_Read_Byte(unsigned char ack);#endif

程序源⽂件IIC.c⽂件

#include \"IIC.h\"

/*********************************************************************** STM32模拟IIC通信** ⽂件编码: GBK2312

**********************************************************************/

/******************************* 初始化IIC的IO⼝**

******************************/void IIC_IOInit(void){

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE ); //使能IO⼝时钟

GPIO_InitStructure.GPIO_Pin = IIC_SCL_IO | IIC_SDA_IO;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_SetBits(GPIOB,IIC_SCL_IO | IIC_SDA_IO); //置位SDA,SCL }

/******************************* 起始信号**

******************************/void IIC_Start(void){

SDA_OUT(); //sda 线输出 IIC_SDA=1; IIC_SCL=1; IIC_DELAY(4);

IIC_SDA=0;//当时钟线为⾼时,SDA拉低则起始信号才有效

IIC_DELAY(4);

IIC_SCL=0;//钳住 I2C 总线,准备发送或接收数据}

/******************************* 停⽌信号**

******************************/void IIC_Stop(void){

SDA_OUT();//sda 线输出 IIC_SCL=0;

IIC_SDA=0;//STOP:when CLK is high DATA change form low to high IIC_DELAY(4);

IIC_SCL=1; IIC_DELAY(1);

IIC_SDA=1;//发送 I2C 总线结束信号 IIC_DELAY(4);}

/******************************* 等待应答信号

** 返回值: 1-接收应答失败, 0-为接收成功******************************/

unsigned char IIC_Wait_Ack(void){

unsigned char ucErrTime=0; SDA_IN(); //SDA 设置为输⼊ IIC_SDA=1;IIC_DELAY(1); IIC_SCL=1;IIC_DELAY(1);

while(READ_SDA) //判断SDA上是否有低电平发⽣ {

ucErrTime++;

if(ucErrTime>250) //如果在⼀段时间内没有接收到应答信号,则发送停⽌信号 {

IIC_Stop(); return 1; } }

IIC_SCL=0;//时钟输出 0 return 0;}

/******************************* 产⽣应答信号**

******************************/void IIC_Ack(void){

IIC_SCL=0; SDA_OUT(); IIC_SDA=0;

IIC_DELAY(2); //数据改变有效

IIC_SCL=1; IIC_DELAY(2); IIC_SCL=0;}

/******************************* 不产⽣应答信号**

******************************/void IIC_NoAck(void){

IIC_SCL=0; SDA_OUT(); IIC_SDA=1; IIC_DELAY(2);

IIC_SCL=1; IIC_DELAY(2); IIC_SCL=0;}

/******************************* 发送⼀个字节的数据**

******************************/

void IIC_Send_Byte(unsigned char txd)

{

unsigned char t; SDA_OUT();

IIC_SCL=0;//拉低时钟开始数据传输,时SDA上的数据改变有效 for(t=0;t<8;t++) {

IIC_SDA=(txd&0x80)>>7; txd<<=1;

IIC_DELAY(2); //对 TEA5767 这三个延时都是必须的

IIC_SCL=1;

IIC_DELAY(2); //保持数据⼀段时间

IIC_SCL=0; IIC_DELAY(2); }}

/******************************* 读⼀个字节的数据

** 形式参数:ack=1,发送ACK, ack=0,发送NACK******************************/

unsigned char IIC_Read_Byte(unsigned char ack){

unsigned char i,receive=0; SDA_IN();//SDA 设置为输⼊

for(i=0;i<8;i++ ) {

IIC_SCL=0; IIC_DELAY(2); IIC_SCL=1; receive<<=1;

if(READ_SDA)receive++; IIC_DELAY(1); }

if (!ack)

IIC_NoAck();//发送 nACK else

IIC_Ack(); //发送 ACK

return receive;}

因篇幅问题不能全部显示,请点此查看更多更全内容