单片机
返回首页

STM32 模拟I2C (STM32F051)

2018-04-15 来源:eefocus

/** 

  ****************************************************************************** 

  * @file      i2c simu.c 

  * @brief     simulation function 

  * @CPU       STM32F051 

  * @compiler  Keil uVision V4.74 

  * @author    MetalSeed 

  * @copyright WSHHB 

  * @version   V1.0.0 

  * @date      18-Sept-2014 

  * @modifydate20-Sept-2014 

  ****************************************************************************** 

  * @attention 

  */  

  

#include 'boardAPI.h'  

#include 'i2cSimu.h'  

#include 'delay.h'  

#include 'uart.h'  

  

GPIO_InitTypeDef        GPIO_InitStructure;    

     

    

/** 

  * @brief  IIC Init 

  * @param  A: 

  * @retval None 

  */  

void IIC_Init(void)  

{                          

    RCC_AHBPeriphClockCmd(  RCC_AHBPeriph_GPIOF, ENABLE );    

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ;   //ÍÆÍìÊä³ö  

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

    GPIO_Init(GPIOF, &GPIO_InitStructure);  

    GPIO_SetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7);  //PB10,PB11 Êä³ö¸ß  

}  

  

/** 

  * @brief  Set SDA Pin as Output Mode 

  * @retval None 

  */  

void SDA_OUT()    

{    

  GPIO_StructInit(&GPIO_InitStructure);    

  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;    

  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;    

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     

  GPIO_Init(GPIOF, &GPIO_InitStructure);    

}    

  

/** 

  * @brief  Set SDA Pin as Input Mode 

  * @retval None 

  */  

void SDA_IN()    

{    

  GPIO_StructInit(&GPIO_InitStructure);    

  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;    

  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;  

  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;// !!!  

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     

  GPIO_Init(GPIOF, &GPIO_InitStructure);    

}   

  

/** 

  * @brief  read input voltage from SDA pin 

  * @retval None 

  */  

BYTE SDA_READ()  

{  

  return GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_7);  

}  

  

/** 

  * @brief  output high form SDA pin 

  * @retval None 

  */  

void IIC_SDA_1()  

{  

  GPIO_SetBits(GPIOF, GPIO_Pin_7);  

}  

  

/** 

  * @brief  output low form SDA pin 

  * @retval None 

  */  

void IIC_SDA_0()  

{  

  GPIO_ResetBits(GPIOF, GPIO_Pin_7);  

}  

  

/** 

  * @brief  output high form SCL pin 

  * @retval None 

  */  

void IIC_SCL_1()  

{  

GPIO_SetBits(GPIOF, GPIO_Pin_6);  

}  

  

/** 

  * @brief  output LOW form SCL pin 

  * @retval None 

  */  

void IIC_SCL_0()  

{  

GPIO_ResetBits(GPIOF, GPIO_Pin_6);    

}  

  

  

/** 

* @brief  Simulate IIC conmunication :Create Start signal 

  * @retval None 

  */  

void IIC_Start(void)  

{  

    SDA_OUT();     //sda output  

    IIC_SDA_1();            

    IIC_SCL_1();  

    delayus(4);  

    IIC_SDA_0();   //START:when CLK is high,DATA change form high to low   

    delayus(4);  

    IIC_SCL_0();   //hold scl line, prepare to transmit data  

}       

  

/** 

  * @brief  Simulate IIC conmunication : Create Stop signal 

  * @retval None 

  */  

void IIC_Stop(void)  

{  

    SDA_OUT();    //sda output mode   

    IIC_SCL_0();  

    IIC_SDA_0();  //STOP:when CLK is high DATA change form low to high  

    delayus(4);  

    IIC_SCL_1();   

    IIC_SDA_1();  //indicate transmit over  

    delayus(4);                               

}  

  

/** 

* @brief  Simulate IIC conmunication : wait for target device's ACK 

* @retval ACK (0) : receive success 

* @retval NACK(1) : receive unsuccess 

  */  

BYTE IIC_Wait_Ack(void)  

{  

    BYTE ucErrTime = 0;  

    SDA_IN();      //set as input mode  

    IIC_SDA_1();  

  delayus(1);        

    IIC_SCL_1();  

  delayus(1);      

    while(SDA_READ())  

    {  

        ucErrTime++;  

        if(ucErrTime > 250)  

        {  

            IIC_Stop();  

            return 1;  

        }  

    }  

    IIC_SCL_0(); //release scl line  

    return 0;    

}   

  

/** 

  * @brief  Simulate IIC conmunication : make an ACK 

  * @retval None 

  */  

void IIC_Ack(void)  

{  

    IIC_SCL_0();  

    SDA_OUT();  

    IIC_SDA_0();  

    delayus(2);  

    IIC_SCL_1();  

    delayus(2);  

    IIC_SCL_0();  

}  

  

/** 

  * @brief  Simulate IIC conmunication : don't make an ACK 

  * @retval None 

  */  

void IIC_NAck(void)  

{  

    IIC_SCL_0();  

    SDA_OUT();  

    IIC_SDA_1();  

    delayus(2);  

    IIC_SCL_1();  

    delayus(2);  

    IIC_SCL_0();  

}                                          

  

  

/** 

  * @brief  Simulate IIC conmunication : Transmit one byte Data 

  * @param  txd: data to be transmit 

  * @retval None 

  */  

void IIC_Send_Byte(BYTE txd)  

{                          

  BYTE i;     

  SDA_OUT();          

  IIC_SCL_0();//push down scl  to start transmit data  

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

  {                

    if(txd & 0x80)  

    {  

      IIC_SDA_1();  

    }  

    else  

    {  

      IIC_SDA_0();  

    }  

    txd <<= 1;        

    delayus(2);     

    IIC_SCL_1();  

    delayus(2);   

    IIC_SCL_0();      

    delayus(2);  

  }    

}       

  

//¶Á1¸ö×Ö½Ú£¬ack=1ʱ£¬·¢ËÍACK£¬ack=0£¬·¢ËÍnACK     

/** 

  * @brief  Simulate IIC conmunication : Receive one byte Data 

  * @param  ack: Whether transmit ACK 

  * @retval the data have been receive 

  */  

BYTE IIC_Read_Byte(unsigned char ack)  

{  

    unsigned char i, res = 0;  

    SDA_IN();               //SDA input mode  

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

    {  

    IIC_SCL_0();   

    delayus(2);  

    IIC_SCL_1();  

    res <<= 1;  

    if(SDA_READ())  

    {  

      res++;   

    }        

        delayus(1);   

  }                    

  if (!ack)  

  {  

    IIC_NAck();//make NACK  

  }  

  else  

  {  

    IIC_Ack(); //make ACK  

  }  

  return res;  

}  

  

  

/*JUST SOME TEST FUNTION DEMO*/  

BYTE ReadData()  

{                   

    BYTE temp=0;                                                                                   

  IIC_Start();    

      

  IIC_Send_Byte(0x80);   

    IIC_Wait_Ack();   

    

  IIC_Send_Byte(0xf5);   

    IIC_Wait_Ack();       

      

  IIC_Start();               

    IIC_Send_Byte(0XA1);   

    IIC_Wait_Ack();    

    

  temp=IIC_Read_Byte(0);             

  IIC_Stop();  

    return temp;  

}  

  

void WriteData(BYTE DataToWrite)  

{                                                                                              

  IIC_Start();    

  IIC_Send_Byte(0x80);  

  if( IIC_Wait_Ack() == 0)  

  {  

     printf('Recieve ACK \n');  

  }      

    

  IIC_Send_Byte(0xf5);  

    IIC_Wait_Ack();                                                          

      

  IIC_Send_Byte( DataToWrite );   

    IIC_Wait_Ack();                      

    

  IIC_Stop();  

    delayms(10);       

}  


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • CCD图像传感器在微光电视系统中的应用

  • 光控音效发生器电路

  • 一个简单的警笛电路图

  • 一个简单的立体声平衡指示器电路

  • 使用NE555和磁簧开关的橱柜照明电路

  • 电谐波图形均衡器示意图

    相关电子头条文章