问答

汇集网友智慧,解决技术难题

21ic问答首页 - 模拟IIC GD32

模拟IIC GD32

NUANXIXIA2022-09-14
GD32F427VK软件模拟IIC,但是IIC总会有收不到ACK的情况,

/*
* description:本文件为模拟I2C驱动代码
* version: 1.0
* Change Logs:
* Date           Author       Notes
* 2020-01-17     yina         create
*                             
*/

#include "audio_i2c.h"
#include "audio_port_i2c.h"
#include "systick.h"







/**********************************************************
* @NOTE    产生IIC起始信号
* @param   
* @return   
*********************************************************/
void audio_iic_start(void)
{
        audio_i2c_sda_out();     //sda线输出
        audio_i2c_sda_set(1);                    
        audio_i2c_scl_set(1);
        delay_1us(4);
        audio_i2c_sda_set(0);//START:when CLK is high,DATA change form high to low
        delay_1us(4);
        audio_i2c_scl_set(0);//钳住I2C总线,准备发送或接收数据
}          
/**********************************************************
* @note    产生IIC停止信号
* @param   
* @return   
*********************************************************/
void audio_iic_stop(void)
{
        audio_i2c_sda_out();//sda线输出
        audio_i2c_scl_set(0);
        audio_i2c_sda_set(0);//STOP:when CLK is high DATA change form low to high
        delay_1us(4);
        audio_i2c_scl_set(1);
        audio_i2c_sda_set(1);//发送I2C总线结束信号
    delay_1us(4);
                                                                          
}
/**********************************************************
* @note    等待应答信号到来
* @param   
* @return  1:接收应答失败  0:接收应答成功  
*********************************************************/
uint8_t audio_iic_wait_ack(void)
{
        uint8_t ucErrTime=0;
       
        audio_i2c_sda_in();      //SDA设置为输入  
        audio_i2c_sda_set(1);
        delay_1us(1);          
        audio_i2c_scl_set(1);
        delay_1us(1);         
        while(audio_i2c_sda_read())
        {
                ucErrTime++;
                if(ucErrTime>250)
                {
                        audio_iic_stop();
                        return 1;
                }
        }
        audio_i2c_scl_set(0);//时钟输出0
    audio_i2c_sda_out();   
        return 0;  
}
/**********************************************************
* @note    产生ACK应答信号
* @param   
* @return   
*********************************************************/
static void audio_iic_ack(void)
{
        audio_i2c_scl_set(0);
        audio_i2c_sda_out();
        audio_i2c_sda_set(0);
        delay_1us(2);
        audio_i2c_scl_set(1);
        delay_1us(2);
        audio_i2c_scl_set(0);
}
/**********************************************************
* @note    不产生ACK应答信号
* @param   
* @return   
*********************************************************/   
void audio_iic_noack(void)
{
        audio_i2c_scl_set(0);
        audio_i2c_sda_out();
        audio_i2c_sda_set(1);
        delay_1us(2);
        audio_i2c_scl_set(1);
        delay_1us(2);
        audio_i2c_scl_set(0);
}                                       
/**********************************************************
* @note     IIC发送一个字节
* @param   
* @return   1:有应答  0:无应答
*********************************************************/                          
void audio_iic_sendbyte(uint8_t txd)
{                        
        uint8_t t;   
        audio_i2c_sda_out();             
        audio_i2c_scl_set(0);//拉低时钟开始数据传输
        for(t=0;t<8;t++)
        {      
            if( (txd & 0x80) == 0x80 )
            {
                audio_i2c_sda_set(1);
            }
            else audio_i2c_sda_set(0);
//                        audio_i2c_sda_set((txd&0x80)>>7);
                        txd<<=1;           
                        delay_1us(2);   //对TEA5767这三个延时都是必须的
                        audio_i2c_scl_set(1);
                        delay_1us(2);
                        audio_i2c_scl_set(0);       
                        delay_1us(2);
        }         
}             


/**********************************************************
* @note     读1个字节,ack=1时,发送ACK,ack=0,发送nACK  
* @param   
* @return   1:有应答  0:无应答
*********************************************************/                          
uint8_t audio_iic_Readbyte(uint8_t txd)
{
     unsigned char i,receive=0;
        audio_i2c_sda_in();//SDA设置为输入
    for(i=0;i<8;i++ )
        {
        audio_i2c_scl_set(0);
        delay_1us(2);
                audio_i2c_scl_set(1);
        receive<<=1;
        if(audio_i2c_sda_read())receive++;   
                delay_1us(1);
    }
    audio_i2c_scl_set(0);
    audio_i2c_sda_out();   
    if (!txd)
        audio_iic_noack();//发送nACK
    else
        audio_iic_ack(); //发送ACK   
    return receive;
}


回答 +关注 5
1473人浏览 0人回答问题 分享 举报
0 个回答

您需要登录后才可以回复 登录 | 注册