STM32F1 模拟I2C驱动DAC(LTC2605)程序

由于在电路设计上将SCL、SDA线拉太长导致硬件I2C时常出问题,所以考虑用模拟I2C解决,这里参考别人的代码然后自己应用到24位DAC(LTC2605)上,已移植成功。

(1).simulate_i2c.c

#include "stm32f10x.h"
#include "simulate_i2c.h"
 
#define HIGH 1
#define LOW 0
 
#define TRUE 1
#define FALSE 0

#define Master_Address 0x0A  
#define WR 0X00
#define RD 0X01
 
#define SCL_H      GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define SCL_L      GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define SDA_H             GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define SDA_L             GPIO_ResetBits(GPIOB,GPIO_Pin_7)

 
void delay_us(u16 time)
{    
   u16 i = 0;  
   while(time--)
   {
      i = 10;  
      while(i--);    
   }
}
 
void I2C_INIT(void)
{
    GPIO_InitTypeDef GPIO_Init_Structure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_Init_Structure.GPIO_Pin = GPIO_Pin_6;
    GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_Init_Structure);
    GPIO_SetBits(GPIOB,GPIO_Pin_6);
}
 
void SDA_OUT(){
     GPIO_InitTypeDef  GPIO_InitStructure;
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  //????
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO????50MHz
   GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void SDA_IN(){
     GPIO_InitTypeDef  GPIO_InitStructure;
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  //????,?????????????
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO????50MHz
   GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void I2C_Start(void)
{
    SDA_OUT();     
    
    SDA_H;
    SCL_H;

    delay_us(5);

    SDA_L;
    delay_us(5);
    
    SCL_L;
}
 

void I2C_Stop(void)
{
    SDA_OUT();
    
    SCL_L;

    SDA_L;
    
     delay_us(5);
    
    SCL_H;
    
    SDA_H;
    delay_us(5);                                   
}

扫描二维码关注公众号,回复: 4642574 查看本文章

u8 I2C_Wait_Ack(void)
{
      u8 ucErrTime = 0; 
      SDA_H;
    delay_us(5);
    
        SDA_IN();      
    
        SCL_H;
    delay_us(5);     
    
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7))
        {
            ucErrTime++;
            if(ucErrTime > 250)
            {
                return FALSE;
            }
        }
    
        SCL_L;

    
      return TRUE;  
}
 

void I2C_Ack(void)
{
   
    SCL_L;
    
    SDA_OUT();
    
    SDA_L;
    
    delay_us(5);
    
    SCL_H;
    
    delay_us(5);
    
    SCL_L;

}
 

void I2C_NAck(void)
{
    SCL_L;
    SDA_OUT();
    
    SDA_H;
    delay_us(5);
    
    SCL_H;
    delay_us(5);
    
    SCL_L;
}
 
void I2C_Send_Byte(u8 txd)
{                        
    u8 t;  
   
        SDA_OUT();      
     
        SCL_L;
    for(t = 0; t < 8; t++)
    {     
        if((txd&0x80) >> 7)
            SDA_H;
        else
            SDA_L;
        
        txd <<= 1; 
       
        delay_us(5);   
        
        SCL_H;
        
        delay_us(5);
        
        SCL_L;
        
        delay_us(5);
    }     

 
u8 I2C_Read_Byte(void)
{
    unsigned char i, receive = 0;
    
    SDA_IN();
    
    for(i = 0; i < 8; i++ )
    {

            SCL_L;
            delay_us(5);
        
          SCL_L;
            
            receive = (receive << 1) | GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7);
        
          delay_us(5); 
    }
    
    return receive;
}

u8 Write_Temp_Value(u16 temp_input)
{
    u8 Data[2];
    Data[0]= temp_input&0x00ff;
  Data[1]= (temp_input>>8)&0x00ff;

    I2C_Start(); 
    
    I2C_Send_Byte(0x20);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Send_Byte(0x22);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Send_Byte(Data[1]);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Send_Byte(Data[0]);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Stop();
    return 0;
}
    
    
u8 Write_Pre_In(u16 pre_In_input)
{
    u8 Data[2];
    Data[0]= pre_In_input&0x00ff;
  Data[1]= (pre_In_input>>8)&0x00ff;
    
    I2C_Start();
    
    I2C_Send_Byte(0x20);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Send_Byte(0x21);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }

    I2C_Send_Byte(Data[1]);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Send_Byte(Data[0]);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Stop();
    return 0;
}

u8 Write_Pre_Out(u16 pre_Out_input)
{
    u8 Data[2];
    Data[0]= pre_Out_input&0x00ff;
  Data[1]= (pre_Out_input>>8)&0x00ff;
    
    I2C_Start();
    
    I2C_Send_Byte(0x20);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Send_Byte(0x20);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }

    I2C_Send_Byte(Data[1]);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Send_Byte(Data[0]);
    if(!I2C_Wait_Ack()){
        I2C_Stop();
        return 0;
    }
    
    I2C_Stop();
    return 0;
}

(2). simulate_i2c.h

#ifndef __SIMULATE_I2C_H__
#define    __SIMULATE_I2C_H__

#include "stm32f10x.h"

void delay_us(u16 time);
void I2C_INIT(void);
void SDA_OUT();
void SDA_IN();
void I2C_Start(void);
void I2C_Stop(void);
u8 I2C_Wait_Ack(void);
void I2C_Ack(void);
void I2C_NAck(void);
void I2C_Send_Byte(u8 txd);
u8 I2C_Read_Byte(void);
u8 Write_Temp_Value(u16 temp_input);
u8 Write_Pre_In(u16 pre_In_input);
u8 Write_Pre_Out(u16 pre_Out_input);

#endif /* __I2C_DRIVE_MCP_H */

(3). main.c

int main(void){

I2C_INIT();

Write_Temp_Value(65535); 

}

猜你喜欢

转载自blog.csdn.net/m0_37827405/article/details/85112674