zoukankan      html  css  js  c++  java
  • STM32 模拟I2C (STM32F051)


    /**
      ******************************************************************************
      * @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 
    ");
      }    
      
      IIC_Send_Byte(0xf5);
    	IIC_Wait_Ack(); 	 										  		   
    	
      IIC_Send_Byte( DataToWrite ); 
    	IIC_Wait_Ack();  		    	   
      
      IIC_Stop();
    	delayms(10);	 
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Linux 配置 nginx + php
    Laravel 网站项目目录结构规划
    配置服务器 Ubuntu 记录+踩坑
    JavaScript 单例,Hash,抛异常
    易理解版八皇后
    获取bing每日图片
    OpenGL 学习笔记 01 环境配置
    [瞎JB写] C++多态
    c++ initialize_list
    最长上升子序列的二分优化
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4634037.html
Copyright © 2011-2022 走看看