栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

基于固件库的软件i2c

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于固件库的软件i2c

    软件i2c通过模拟i2c时序配置普通的gpio引脚,首先封装一个函数

    static void OLED_GPIO_Init(void)
    {
    	GPIO_InitTypeDef GPIO_InitStructure;	 
    	
    	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);	 
    
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_pp;		
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
    	GPIO_Init(GPIOB,&GPIO_InitStructure);	  
    	
    	OLED_SCLK_Set();	 
    	OLED_SDIN_Set();	 
    }
    

    在起始条件未开始之前把SDA,SCL拉高

      接着封装模拟起始信号函数,在SCL高电平时,SDA从高电平向低电平跳变,发出起始信号,最后时钟线置低数据开始准备传输。

      static void OLED_IIC_Start(void)
      {
      
      	OLED_SCLK_Set();	 
      	OLED_SDIN_Set();   
      	   delay_us(1);
      	OLED_SDIN_CLr();	 
      	   delay_us(1);
      	OLED_SCLK_CLr();	 
      
      	   delay_us(1);
      }
      

        然后是封装i2c停止信号,在时钟线为高电平期间,SDA由低变高

        static void OLED_IIC_Stop(void)
        {
        	OLED_SDIN_CLr();	
        	   delay_us(1);
        	OLED_SCLK_Set();  / * 时钟线置高 */ 
        	   delay_us(1);
        	OLED_SDIN_Set();  
        	   delay_us(1);
        }
        

        4.应答信号

        发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号,就是由从机去拉低SDA线。

        当主机发送了8位数据后,会再产生一个时钟,此时主机放开SDA的控制,读取SDA电平,在上拉电阻的影响下,
        此时SDA默认为高,必须从机拉低,以确认收到数据。

        对于反馈有效应答位ACK的要求是,接收器在第九个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平,也就是说在时钟线为高期间数据线为低电平则为有效反馈。

        static unsigned char IIC_Wait_Ack(void)
        {
        	unsigned char ack;  
        
        	OLED_SCLK_CLr();	 
        	 delay_us(1);
        	OLED_SDIN_Set();	 
        	 delay_us(1);
        	OLED_SCLK_Set();	 
        	 delay_us(1);
        
        
        if(OLED_READ_SDIN())	
        ack = IIC_NO_ACK;	  
        delay_us(1);
        
        	return ack;  
        }
        

          发送一个字节i2c数据,数据高位先行
          此涉及数据有效性
          SDA的高或低电平状态只有在 SCL 线的时钟信号是低电平时才能改变。
          SDA在SCLSCL的上升沿到来前准备好,并在下降沿到来之前必须稳定。
          为高电平时表示有效数据,SDA为高电平表示“1”,低电平表示“0”;SCL为低电平时表示无效数据,此时
          SDA会进行电平切换,为下次数据表示做准备。数据有效性示意图如图所示。

          static void Write_IIC_Byte(unsigned char IIC_Byte)
          {
          unsigned char i; //定义变量
          for(i=0;i<8;i++) 
          	{
          		OLED_SCLK_CLr();	
          		 delay_us(1);
          
          		if(IIC_Byte & 0x80)   
          		  	OLED_SDIN_Set();  
          		else
          			OLED_SDIN_CLr();	
          
          
          		IIC_Byte <<= 1;  
          		 delay_us(1);
          		OLED_SCLK_Set();  
          		 delay_us(1);
          	}
          	   OLED_SCLK_CLr();	
          		 delay_us(1);
          
          	while(IIC_Wait_Ack());	
          }
          

            I2c写命令

            static void Write_IIC_Command(unsigned char IIC_Command)
            {
               OLED_IIC_Start();
               Write_IIC_Byte(0x78); 
               Write_IIC_Byte(0x00);
               Write_IIC_Byte(IIC_Command); 
               OLED_IIC_Stop();  
            }
            I2c写数据
            static void Write_IIC_Data(unsigned char IIC_Data)
            {
               OLED_IIC_Start();
               Write_IIC_Byte(0x78);	
               Write_IIC_Byte(0x40);  	
               Write_IIC_Byte(IIC_Data);
               OLED_IIC_Stop();		
            }
            

            代码整合
            .c代码

            #include "stm32f10x.h"
            #include "oled.h"
            #include "oledfont.h"
            #include "delay.h"
            static void OLED_GPIO_Init(void)
            {
            	GPIO_InitTypeDef GPIO_InitStructure;	
            	
            	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);	
            	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;	
            	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
            	GPIO_Init(GPIOB,&GPIO_InitStructure);	
            	
            	OLED_SCLK_Set();	
            	OLED_SDIN_Set();	
            }
            
            
            static void OLED_IIC_Start(void)
            {
            
            	OLED_SCLK_Set();	
            	OLED_SDIN_Set();	
            	   delay_us(1);
            	OLED_SDIN_CLr();	
            	   delay_us(1);
            	OLED_SCLK_CLr();	
            	   delay_us(1);
            }
            
            static void OLED_IIC_Stop(void)
            {
            	OLED_SDIN_CLr();
            	   delay_us(1);
            	OLED_SCLK_Set();	
            	   delay_us(1);
            	OLED_SDIN_Set();	
            	   delay_us(1);
            }
            
            
            static unsigned char IIC_Wait_Ack(void)
            {
            	unsigned char ack;
            
            	OLED_SCLK_CLr();
            	 delay_us(1);
            	OLED_SDIN_Set();	
            	 delay_us(1);
            	OLED_SCLK_Set();	
            	 delay_us(1);
            
            	if(OLED_READ_SDIN())	
            		ack = IIC_NO_ACK;	/
            	else
            		ack = IIC_ACK;		
            
            	OLED_SCLK_CLr();
            	 delay_us(1);
            
            	return ack;	
            }
            
            
            static void Write_IIC_Byte(unsigned char IIC_Byte)
            {
            	unsigned char i;  
            	for(i=0;i<8;i++) 
            	{
            		OLED_SCLK_CLr();	
            		 delay_us(1);
            
            		if(IIC_Byte & 0x80)	
            		  	OLED_SDIN_Set();
            		else
            			OLED_SDIN_CLr();	
            
            		IIC_Byte <<= 1;  
            		 delay_us(1);
            		OLED_SCLK_Set(); 
            		 delay_us(1);
            	}
            	OLED_SCLK_CLr();	
            		 delay_us(1);
            
            	while(IIC_Wait_Ack());	
            }
            
            
            
            static void Write_IIC_Command(unsigned char IIC_Command)
            {
               OLED_IIC_Start();
               Write_IIC_Byte(0x78);
               Write_IIC_Byte(0x00);
               Write_IIC_Byte(IIC_Command);
               OLED_IIC_Stop();  
            }
            
            
            static void Write_IIC_Data(unsigned char IIC_Data)
            {
               OLED_IIC_Start();
               Write_IIC_Byte(0x78);	
               Write_IIC_Byte(0x40);	
               Write_IIC_Byte(IIC_Data);
               OLED_IIC_Stop();		
            

            .h代码

            #ifndef _OLED_H_
            #define _OLED_H_
            
            #include "stm32f10x.h"
            
            
            #define  OLED_SCLK_Set()    GPIO_SetBits(GPIOB,GPIO_Pin_0)  
            #define  OLED_SCLK_CLr()    GPIO_ResetBits(GPIOB,GPIO_Pin_0) 
            #define  OLED_SDIN_Set()    GPIO_SetBits(GPIOB,GPIO_Pin_1) 
            #define  OLED_SDIN_CLr()    GPIO_ResetBits(GPIOB,GPIO_Pin_1) 
            #define  OLED_READ_SDIN()    GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_1)
               
            #define IIC_ACK  0 
            #define IIC_NO_ACK  1  
            
            转载请注明:文章转载自 www.mshxw.com
            本文地址:https://www.mshxw.com/it/737902.html
            我们一直用心在做
            关于我们 文章归档 网站地图 联系我们

            版权所有 (c)2021-2022 MSHXW.COM

            ICP备案号:晋ICP备2021003244-6号