开源,STM32口线模拟I2C程序

2019-12-31 19:20发布

<p> 在STM32的I2C上摔了一跤,测试了官方提供的几个例程和库,都有不同缺陷,也无法弥补:</p><br><p> 1、查询方式,在连续读数据的过程中不能中断</p><br><p> 2、DMA方式类似,在同一DMA中I2C的级别必须最高,否则同1.</p><br><p> 3、中断方式也不能有更高优先级中断I2C,否则同1.</p><br><p> 鉴于以上原因,无奈的口线模拟了I2C。(仅仅代表个人看法,欢迎指正)</p><br><p> 附件中的项目文件已经过测试,为感谢OUR这几年的帮助,先开源这个小程序。</p><br><p>链接:&nbsp;https://pan.baidu.com/s/1by6r7jLqoLJuGR8bl6Sk4A&nbsp;提取码:&nbsp;jfkn&nbsp;复制这段内容后打开百度 {MOD}手机App,操作更方便哦</p><p><br></p>
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
97条回答
way2888
2020-01-07 08:08
/****************************************/       
#define Set_24XXX_SDA(void)        {PIN_SDA=1;}
#define Clr_24XXX_SDA(void)        {PIN_SDA=0;}
#define Get_24XXX_SDA(void)        {PIN_SDA;}          
#define Set_24XXX_SCL(void)        {PIN_SCL=1;}
#define Clr_24XXX_SCL(void)        {PIN_SCL=0;}                                                                  
/****************************************/
static void nop(void)
{        asm("nop");
        asm("nop");
        asm("nop");
}                               
/****************************************/                                                                  
static void ProgrameDelay(int16u x)
{        while(x--);
}
/****************************************/
static void Start(void)
{        Clr_24XXX_SCL();     
        Set_24XXX_SDA();
        Set_24XXX_SCL();
        nop();
        Clr_24XXX_SDA();
        nop();
        Clr_24XXX_SCL();
        Set_24XXX_SDA();     
}
/****************************************/
void Stop(void)
{        Clr_24XXX_SCL();
        Clr_24XXX_SDA();
        Set_24XXX_SCL();
        nop();
        Set_24XXX_SDA();
        nop();
        Clr_24XXX_SCL();
}                                                                                         
/****************************************/
static int8u GetAck(void)
{        int8u ack;
        Clr_24XXX_SCL();
        Set_24XXX_SDA();
        Set_24XXX_SCL();
        nop();
        ack= Get_24XXX_SDA();                 
        Clr_24XXX_SCL();
        return ack;
}
/****************************************/
static void Ack(void)
{        Clr_24XXX_SDA();
        Set_24XXX_SCL();
        nop();
        Clr_24XXX_SCL();
        nop();
        Set_24XXX_SDA();
}                          
/****************************************/
static void Nack(void)
{        Set_24XXX_SDA();
        Set_24XXX_SCL();
        nop();
        Clr_24XXX_SCL();
}                                  
/****************************************/
static void SendByte(int8u sendbyte)
{        int8u i;
        for(i=8;i>0;i--)
           {        Clr_24XXX_SCL();
                if(sendbyte & 0x80)
                {        Set_24XXX_SDA();
                }
                else
                {        Clr_24XXX_SDA();
                }
                sendbyte<<= 1;
                Set_24XXX_SCL();
                nop();
           }
        Clr_24XXX_SCL();
}                                                          
/****************************************/
static int8u ReceiveByte(void)
{        int8u resualt,i=8;
        Clr_24XXX_SCL();
        while(i--)
        {        Set_24XXX_SCL();
                resualt= (resualt<<1)|Get_24XXX_SDA();  
                Clr_24XXX_SCL();
        }
        return resualt;
}
/****************************************/       
int8u Rw24XXX(int16u address,int8u *buf,int16u number,int8u control)
{        int16u i;
        int8u *ptr;
        int8u error=1;
        int8s time=3;
        while(1)
           {        if(--time < 0) break;
                ptr= buf;
                Start();
                   SendByte(control&0xfe); if(GetAck())continue;       
                   SendByte(address>>8); if(GetAck())continue;        //如果地址小于2字节的,如24c02,04,16,32可以屏蔽此句
                   SendByte(address); if(GetAck())continue;

                   if(!(control&0x01))
            {        i= number;
                      error= 0;                     
                      while(i--)
                {        SendByte(*ptr++); if(!GetAck())continue;
                        error= 1;
                        break;
                }
                      if(error == 1) continue;
                      break;
            }
                   else
            {        Start();
                    SendByte(control); if(GetAck())continue;
                    while(--number)
                    {        *ptr++= ReceiveByte();
                            Ack();
                    }
                    *ptr= ReceiveByte();        
                    Nack();
                    error= 0;
                    break;
            }
        }
        Stop();
        if(!(control&0x01))
        {        ProgrameDelay(1000);
        }
        return error;
}                                          
/****************************************/

一周热门 更多>