打印
[软件资料]

IIC通信

[复制链接]
448|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mickit|  楼主 | 2024-6-17 22:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


#include "myiic.h"

#define  I2C1_SCL_GPIO_PORT       CW_GPIOB
#define  I2C1_SCL_GPIO_PIN        GPIO_PIN_10   
#define  I2C1_SDA_GPIO_PORT       CW_GPIOB
#define  I2C1_SDA_GPIO_PIN        GPIO_PIN_11  

void delay_us(uint32_t us)
{
        while(us--)
        {
                __nop();
                __nop();
                __nop();
                __nop();
                __nop();
                __nop();
                __nop();
                __nop();
        }
       
}


void IIC_Init(void)
{
          //配置PB10 为输出
        //使能GPIOB时钟
        CW_SYSCTRL->AHBEN_f.GPIOB  = 1;
        //配置PB10 为输出
        CW_GPIOB->ANALOG_f.PIN10 = 0; //设置 GPIOx_ANALOG.PINy 为 0,将端口配置为数字功能;
        CW_GPIOB->DIR_f.PIN10 = 0;    //设置 GPIOx_DIR.PINy 为 0,将端口配置成输出;
        CW_GPIOB->OPENDRAIN_f.PIN10 = 0;  //0:推挽输出
        CW_GPIOB->ODR_f.PIN10 = 1;
       
        CW_GPIOB->ANALOG_f.PIN11 = 0; //设置 GPIOx_ANALOG.PINy 为 0,将端口配置为数字功能;
        CW_GPIOB->DIR_f.PIN11 = 0;    //设置 GPIOx_DIR.PINy 为 0,将端口配置成输出;
        CW_GPIOB->OPENDRAIN_f.PIN11 = 0;  //0:推挽输出
        CW_GPIOB->ODR_f.PIN11 = 1;
               
}
                                                                                                            
//IO方向设置(SDA)
/*********xxxxxxxxxxxxxx*************/
void SDA_IN()  
{
        CW_GPIOB->DIR_f.PIN11 = 1;    //设置 GPIOx_DIR.PINy 为 0,将端口配置成输出;
}

void SDA_OUT()
{
  CW_GPIOB->DIR_f.PIN11 = 0;    //设置 GPIOx_DIR.PINy 为 0,将端口配置成输出;
        CW_GPIOB->OPENDRAIN_f.PIN11 = 0;  //0:推挽输出
}

//产生IIC起始信号
void IIC_Start(void)
{
        SDA_OUT();     //sda线输出
        IIC_SDA=1;                    
        IIC_SCL=1;
        delay_us(4);
        IIC_SDA=0;//START:when CLK is high,DATA change form high to low
        delay_us(4);
        IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}       

//产生IIC停止信号
void IIC_Stop(void)
{
        SDA_OUT();//sda线输出
        IIC_SCL=0;
        IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
        delay_us(4);
        IIC_SCL=1;
        IIC_SDA=1;//发送I2C总线结束信号
        delay_us(4);                                                                  
}

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
/*********xxxx修改超时时间************/
uint8_t IIC_Wait_Ack(void)
{
        uint8_t ucErrTime=0;
        SDA_IN();      //SDA设置为输入  
        IIC_SDA=1;delay_us(3);          
        IIC_SCL=1;delay_us(3);         
        while(READ_SDA)
        {
                ucErrTime++;
                if(ucErrTime>250)
                {
                        //printf("超时\n");
                        IIC_Stop();
                        return 1;
                }
        }
        IIC_SCL=0;//时钟输出0           
        return 0;  
}

//产生ACK应答
void IIC_Ack(void)
{
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=0;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}

//不产生ACK应答                    
void IIC_NAck(void)
{
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=1;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}                       


//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答                          
void IIC_Send_Byte(uint8_t txd)
{                        
    uint8_t t;   
                SDA_OUT();             
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
                if((txd&0x80)>>7)
                        IIC_SDA=1;
                else
                        IIC_SDA=0;
                txd<<=1;           
                delay_us(2);   //对TEA5767这三个延时都是必须的
                IIC_SCL=1;
                delay_us(2);
                IIC_SCL=0;       
                delay_us(2);
    }         
}           


//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
uint8_t IIC_Read_Byte(unsigned char ack)
{
        unsigned char i,receive=0;
        SDA_IN();//SDA设置为输入
  for(i=0;i<8;i++ )
        {
        IIC_SCL=0;
        delay_us(100);
                    IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
                    delay_us(100);
    }                                         
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}





使用特权

评论回复
沙发
田舍郎| | 2024-6-17 22:55 | 只看该作者
io模拟的程序

使用特权

评论回复
板凳
OKAKAKO| | 2024-6-21 21:10 | 只看该作者
IIC通信需要有哪些注意事项

使用特权

评论回复
地板
中国龙芯CDX| | 2024-6-26 16:41 | 只看该作者
IIC过程需要注意什么?

使用特权

评论回复
5
jf101| | 2024-6-27 16:51 | 只看该作者
硬件IIC与IO模拟有什么区别?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

73

主题

1297

帖子

1

粉丝