微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > 嵌入式系统设计讨论 > 基于stm32f1的开发板,模拟的I2C通信程序 哪里错了啊 返回...

基于stm32f1的开发板,模拟的I2C通信程序 哪里错了啊 返回...

时间:10-02 整理:3721RD 点击:

#include "stm32f10x.h"

#include "I2C.h"

#include <stdio.h>

/* Private typedef -----------------------------------------------------------*/

#define Device_Addr        0xe8

/* Private define ------------------------------------------------------------*/

/* I2C控制线的定义 */

#define SCL_H         GPIOB->BSRR = GPIO_Pin_9          

#define SCL_L         GPIOB->BRR  = GPIO_Pin_9   

#define SDA_H         GPIOB->BSRR = GPIO_Pin_8

#define SDA_L         GPIOB->BRR  = GPIO_Pin_8

#define SCL_read      GPIOB->IDR  & GPIO_Pin_9

#define SDA_read      GPIOB->IDR  & GPIO_Pin_8

void I2C_GPIO_Config(void);

void I2C_delay(void);

bool I2C_Start(void);

void I2C_Stop(void);

void I2C_Ack(void);

void I2C_NoAck(void);

bool I2C_WaitAck(void);

void I2C_SendByte(u8 SendByte);

void I2C_FM_Init(void);

void I2C_Write(u8 address,u8 reg,u8 command);

//bool I2C_Write(uint8_t* pBuffer, uint8_t Write, uint8_t NumByteToWrite);

extern void Delay(__IO uint32_t nCount);

void FM_Configuration(void)

{

   GPIO_InitTypeDef  GPIO_InitStructure;  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

// RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);  

  /* 配置PB10,PB11为I2C的 SCL SDL */

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9| GPIO_Pin_8;            

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                               

  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

void I2C_FM_Init(void)

{

  /* I2C控制线配置 */

  FM_Configuration();

  /* I2C 初始化 */

  //I2C_Configuration();  

}

//模拟I2C信号

void I2C_INIT(void)           //i2c init

{  

     SDA_H;  

     SCL_H;  

}  

void I2C_Write(u8 address,u8 reg,u8 command) //address+register+command

{  

     I2C_INIT();

     I2C_Start();  

     I2C_SendByte(address);   

     I2C_Ack();

     I2C_SendByte(reg);  

     I2C_Ack();

     I2C_SendByte(command);  

     I2C_Ack();

     I2C_Stop();   

}  

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

* 名    称:void I2C_delay(void)

* 功    能:I2C 控制延时函数

* 入口参数:无

* 出口参数:无

* 说    明:无

* 调用方法:无

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

void I2C_delay(void)

{

   u8 i=100;

   while(i)

   {

     i--;

   }

}

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

* 名    称:bool I2C_Start(void)

* 功    能:I2C起始状态

* 入口参数:无

* 出口参数:无

* 说    明:无

* 调用方法:无

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

bool I2C_Start(void)

{

SDA_H;         //SDA置高

SCL_H;         //SCL置高

I2C_delay();

if(!SDA_read)return FALSE;        //SDA线为低电平则总线忙,退出

SDA_L;

I2C_delay();

if(SDA_read) return FALSE;        //SDA线为高电平则总线出错,退出

SDA_L;         //SDA置低

I2C_delay();

return TRUE;

}

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

* 名    称:void I2C_Stop(void)

* 功    能:I2C停止状态

* 入口参数:无

* 出口参数:无

* 说    明:无

* 调用方法:无

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

void I2C_Stop(void)

{

SCL_L;          

I2C_delay();

SDA_L;

I2C_delay();

SCL_H;

I2C_delay();

SDA_H;

I2C_delay();

}

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

* 名    称:void I2C_Ack(void)

* 功    能:I2C ACK应答

* 入口参数:无

* 出口参数:无

* 说    明:无

* 调用方法:无

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

void I2C_Ack(void)

{

SCL_L;

I2C_delay();

SDA_L;

I2C_delay();

SCL_H;

I2C_delay();

SCL_L;

I2C_delay();

}

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

* 名    称:void I2C_NoAck(void)

* 功    能:I2C 无应答

* 入口参数:无

* 出口参数:无

* 说    明:无

* 调用方法:无

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

void I2C_NoAck(void)

{

SCL_L;

I2C_delay();

SDA_H;

I2C_delay();

SCL_H;

I2C_delay();

SCL_L;

I2C_delay();

}

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

* 名    称:bool I2C_WaitAck(void)

* 功    能:I2C等待应答

* 入口参数:无

* 出口参数:无

* 说    明:无

* 调用方法:无

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

bool I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK

{

SCL_L;

I2C_delay();

SDA_H;

I2C_delay();

SCL_H;

I2C_delay();

if(SDA_read)

{

      SCL_L;

      return FALSE;

}

SCL_L;

return TRUE;

}

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

* 名    称:void I2C_SendByte(u8 SendByte)

* 功    能:发送数据字节

* 入口参数:无

* 出口参数:无

* 说    明:无

* 调用方法:无

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

void I2C_SendByte(u8 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;

}

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

* 名    称:u8 I2C_ReceiveByte(void)

* 功    能:I2C接收数据字节

* 入口参数:无

* 出口参数:无

* 说    明:无

* 调用方法:无

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

u8 I2C_ReceiveByte(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;

}


u8 read_byte(u8 address,u8 reg)  //address(with bit 0 set) + register

{  

    u8 dat;  

    I2C_INIT();  

    I2C_Start();  

    I2C_SendByte(address);  

     I2C_Ack();

    I2C_SendByte(reg);  

     I2C_Ack();

    I2C_Start();  

    I2C_SendByte(address+1);  

     I2C_Ack();

    dat = I2C_ReceiveByte();

    I2C_NoAck();

    I2C_Stop();  

    return dat;  

}  

//

//void change_i2c_address(unsigned char addr_old, unsigned char addr_new)

//// addr_old is the address now, addr_new will be the new address

//{         //that you want change to

//delayms(2000);

//I2C_Write(&write_command, WriteAddr, 3)            // Protect the eeprom ,you can delete this sentence

//write_byte(addr_old,2,0x9a);

//delayms(1);

//write_byte(addr_old,2,0x92);

//delayms(1);

//write_byte(addr_old,2,0x9e);

//delayms(1);

//write_byte(addr_old,2, addr_new);

//delayms(500);         //Protect the eeprom, you can delete this sentence

//}


static void Delay_ARMJISHU(__IO uint32_t nCount)

{

  for (; nCount != 0; nCount--);

}


void detect(void)        //0xe8(address) + 0xb0(command)

{

u8 i;

//        u8 I2c_voice[3]={0xe8,2,0xb0};

u8 I2c_Buf[2];

I2C_Write(Device_Addr,2,0xb4);

//        I2C_Write(I2c_voice, Device_Addr,3);           //use command "0xb0" to detect the distance

    Delay_ARMJISHU(360000);         //安全延时,如果显示不清晰可以将延时调大一些

//delayms(80);             //如果是探测温度此处延时需根据表1所列时间相应延长

//display(range);         //等待探测结束,count值调小将减小探测等待时间

while(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9));//display(range);

I2c_Buf[0]=read_byte(Device_Addr,2);

I2c_Buf[1]=read_byte(Device_Addr,3);

for(i=0;i<=2;i++)

{

printf("0x%X\t", I2c_Buf);

}

}


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top