打印
[STM32F1]

STM32软件IIC 程序 方便移植

[复制链接]
194|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
febgxu|  楼主 | 2023-5-25 16:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "myiic.h"
#include "delay.h"

//已删除所有延时 1 - 2us延时        若IIC通信出错或许是没有延时问题
//或者时钟源问题

void IIC_Init()
{
        GPIO_InitTypeDef  GPIO_InitStructure;
/****************************IIC_SDA初始化***********************************************/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_IIC_SDA_PORT, ENABLE);        //使能SDA连接端口时钟   /
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SDA;                                                                                //SDA端口配置                                           /
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                          //推挽输出                                                         /
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                        //IO口速度为50MHz                                 /
        GPIO_Init(GPIO_SDA_PORT, &GPIO_InitStructure);                                                                 //根据设定参数初始化SDA /
/****************************IIC_SCL初始化***********************************************/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_IIC_SCL_PORT, ENABLE);        //使能SCL连接端口时钟          /
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SCL;                                                                                //SCL端口配置                                                 /
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                          //推挽输出                                                         /
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                        //IO口速度为50MHz                                 /
        GPIO_Init(GPIO_SCL_PORT, &GPIO_InitStructure);                                                                 //根据设定参数初始化SCL /
/****************************************************************************************/
}


/**********************************************/
//                                                IIC Start
//开始信号:在SCL为高电平时,SDA由高电平向低电平跳变,开始传输数据。
/**********************************************/
void IIC_Start()
{
        SDA_OUT();
        IIC_SCL=1;
        IIC_SDA=1;
        delay_us(2);
        IIC_SDA=0;
        delay_us(2);
        IIC_SCL=0;
}


/**********************************************/
//                                                IIC Stop
//结束信号:在SCL为高电平时,SDA由低电平向高电平跳变,结束传输数据。
/**********************************************/
void IIC_Stop()
{
        SDA_OUT();
        IIC_SCL=1;
        IIC_SDA=0;
        delay_us(2);
        IIC_SDA=1;
        delay_us(2);

}

/**********************************************/
//                                                IIC主机产生ACK应答信号
/**********************************************/
void IIC_ACK(void)
{
        SDA_OUT();
        IIC_SCL=0;
        IIC_SDA=0;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}

/**********************************************/
//                                                IIC主机不产生ACK应答信号
/**********************************************/
void IIC_NACK(void)

{
        SDA_OUT();
        IIC_SCL=0;
        IIC_SDA=1;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}


/**********************************************/
//                                                IIC Wait Ack
//等待应答信号到来
//返回值        1,接收应答失败
//        0,接收应答成功
/**********************************************/
unsigned char IIC_Wait_Ack(void)
{
        u8 ucErrTime=0;
        SDA_IN();      //SDA设置为输入  
        IIC_SDA=1;
        IIC_SCL=1;
        delay_us(2);
        while(READ_SDA)
        {
                ucErrTime++;      
                if(ucErrTime>250)
                        {
                                IIC_Stop();
                                return 1;
                        }
        }
        IIC_SCL=0;//时钟输出0           
        return 0;  
}

/**********************************************
//                                                 IIC Write byte
//IIC写一个字节         
**********************************************/
void IIC_Write_Byte(unsigned char data)
{
        unsigned char i;   
        SDA_OUT();            
        IIC_SCL=0;//拉低时钟开始数据传输
        for(i=0;i<8;i++)
        {              
    IIC_SDA=(data&0x80)>>7;
    data=data<<1;           
//                delay_us(2);   //对TEA5767芯片这三个延时都是必须的
                IIC_SCL=1;
//        delay_us(2);
                IIC_SCL=0;      
//        delay_us(2);
        }
}

/**********************************************
// IIC Write Data
**********************************************/
void IIC_Write_Data(unsigned char Device_addr,unsigned char Reg_addr,unsigned char data)
{
  IIC_Start();
        SDA_OUT();
  IIC_Write_Byte(Device_addr | 0x00);        //器件地址(7位) + 读写位(读1写0)
        IIC_Wait_Ack();      
  IIC_Write_Byte(Reg_addr);                                                //要写入数据的寄存器地址
        IIC_Wait_Ack();      
  IIC_Write_Byte(data);
        IIC_Wait_Ack();      
  IIC_Stop();
}

/**********************************************
//                                                 IIC Read byte
//IIC读一个字节         
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
**********************************************/
unsigned char IIC_Read_Byte(unsigned char Ack_EN)
{
        unsigned char i,receive=0;
        SDA_IN();//SDA设置为输入
        for(i=0;i<8;i++ )
        {
                IIC_SCL=0;
                delay_us(2);
                IIC_SCL=1;
                receive<<=1;
    if(READ_SDA)receive++;   
                delay_us(1);
   }                                         
    if (!Ack_EN)
        IIC_NACK();//发送nACK
    else
        IIC_ACK(); //发送ACK   
    return receive;
}


/**********************************************
// IIC Read Data
**********************************************/
unsigned char IIC_Read_Data(unsigned char Device_addr,unsigned char Reg_addr,unsigned char ACK_EN)
{
        unsigned char receive;
        IIC_Start();
  IIC_Write_Byte(Device_addr | 0x00);        //器件地址(7位) + 读写位(写0)
        IIC_Wait_Ack();      
  IIC_Write_Byte(Reg_addr);                                                //要读数据的寄存器地址
        IIC_Wait_Ack();      
  IIC_Start();
        SDA_IN();
  IIC_Write_Byte(Device_addr | 0x01);        //器件地址(7位) + 读写位(读1)
        IIC_Wait_Ack();      
        receive=IIC_Read_Byte(0);
        IIC_Wait_Ack();      
  IIC_Stop();
        return receive;
}


使用特权

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

本版积分规则

38

主题

4786

帖子

2

粉丝