[转]基于stm32的I2C总线通讯简介及使用操作2
3、参考代码子函数文件 iic.c#include "myi2c.h"void I2C_GPIO_Config(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin =SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void I2C_delay(void)
{
u8 i=10; //这里可以优化速度 ,经测试最低到5还能写入
while(i)
{
i--;
}
}void delay5ms(void)
{
int i=5000;
while(i)
{
i--;
}
}
uint16_t I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
SDA_L;
I2C_delay();
if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出
SDA_L;
I2C_delay();
return TRUE;
}
void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
}
void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
void I2C_NoAck(void)
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
uint16_t I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
SCL_L;
I2C_delay();
return FALSE;
}
SCL_L;
I2C_delay();
return TRUE;
}
void I2C_SendByte(unsigned char SendByte) //数据从高位到低位//
{
u8 i=8;
while(i--)
{
SCL_L;
I2C_delay();
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte<<=1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}
unsigned char I2C_RadeByte(void)//数据从高位到低位//
{
u8 i=8;
u8 ReceiveByte=0; SDA_H;
while(i--)
{
ReceiveByte<<=1;
SCL_L;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL_L;
return ReceiveByte;
}
//ZRX
//单字节写入*****************************uint16_t Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data) //void
{
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
I2C_SendByte(REG_Address ); //设置低起始地址
I2C_WaitAck();
I2C_SendByte(REG_data);
I2C_WaitAck();
I2C_Stop();
delay5ms();
return TRUE;
}//单字节读取****************************
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{ unsigned char REG_data;
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop();return FALSE;}
I2C_SendByte((u8) REG_Address); //设置低起始地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck(); REG_data= I2C_RadeByte();
I2C_NoAck();
I2C_Stop();
//return TRUE;
return REG_data;}
头文件 iic.h#ifndef __MYI2C_H__#define __MYI2C_H__#include "stm32f10x.h"#define FALSE 0#define TRUE1 #define SCL_PIN GPIO_Pin_6#define SDA_PIN GPIO_Pin_7 #define SCL_H GPIOB->BSRR = SCL_PIN #define SCL_L GPIOB->BRR= SCL_PIN #define SDA_H GPIOB->BSRR = SDA_PIN #define SDA_L GPIOB->BRR= SDA_PIN #define SCL_read GPIOB->IDR& SCL_PIN #define SDA_read GPIOB->IDR& SDA_PIN void I2C_GPIO_Config(void);void I2C_delay(void);void delay5ms(void);uint16_t I2C_Start(void);void I2C_Stop(void);void I2C_Ack(void); void I2C_NoAck(void);uint16_t I2C_WaitAck(void);void I2C_SendByte(unsigned char SendByte);unsigned char I2C_RadeByte(void);uint16_t Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data);unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address); #endif // __MYI2C_H__
页:
[1]