yujietian 发表于 2017-4-14 19:52:30

[转]基于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]
查看完整版本: [转]基于stm32的I2C总线通讯简介及使用操作2