STM32F767硬件IIC

2019-07-20 12:05发布

我在调STM32F767的硬件IIC(作死用寄存器)(STM32做主机读取AT24C02)的时候发现不论我发什么AT24C02始终返回NACK,用示波器检测PH4,PH5始终为低电平,我甚至都怀疑我的IO口没有接到IIC2上,
然后我用STM32CUBE看了一下配置过程,发现一开始IIC2的IO默认没有映射到PH4,PH5不知道要不要特殊设一下,但是USART1用STM32CUBE配置的时候也没有映射到PA9PA10上啊,我也没看见特殊设啊
还有我看了论坛里的大佬关于其他MCU的硬件IIC配置,我忘了谁了提到要按一定顺序,然后我就按《STM32F7中文参考手册》的配置了一下,也并没有什么卵用
IIC2初始化
[mw_shl_code=c,true]void iic2_init(void)//APB1为54MHZ
{
    iic2_gpio_init();       //iic接口使能
    RCC->APB1ENR|=1<<22;    //使能IIC2时钟
    I2C2->CR1=0;
    I2C2->CR2=0;            //先清0
    I2C2->TIMINGR=0;
    //对于模拟噪声滤波0为使能
    I2C2->CR1|=1<<12;       //模拟噪声滤波使能
    I2C2->CR1|=0X1<<8;      //
   
    I2C2->TIMINGR|=0x0<<28; //不分频Tpresc=(X+1)*Ti2clk
    I2C2->TIMINGR|=0x3<<20; //见STM32F7中文参考手册P898
    I2C2->TIMINGR|=0x0<<16;
    I2C2->TIMINGR|=0x3d<<8;
    I2C2->TIMINGR|=0x5b<<0;
   
    I2C2->CR1|=1<<17;       //不延长时钟
    //对于DMA 0为失能
    I2C2->CR1|=0<<15;       //DMA接收
    I2C2->CR1|=0<<14;       //DMA发送
    //对于中断0为失能
    I2C2->CR1|=0<<7;        //错误中断
    I2C2->CR1|=0<<6;        //传输完成中断
    I2C2->CR1|=0<<5;        //停止位检测中断
    I2C2->CR1|=0<<4;        //接收定时应答中断
    I2C2->CR1|=0<<3;        //地址匹配中断
    I2C2->CR1|=0<<2;        //接收中断
    I2C2->CR1|=0<<1;        //发送中断
   
    I2C2->CR2|=1<<25;       //自动结束
    I2C2->CR2|=1<<16;
    I2C2->CR2|=1<<14;       //停止位   
    I2C2->CR2&=~(1<<11);    //7位
   
    I2C2->CR1|=1<<0;       //IIC2使能
}
void iic2_gpio_init(void)
{
           RCC->AHB1ENR|=1<<7;           //使能PORTH口时钟  
        gpio_set(GPIOH,PIN4|PIN5,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PH4,PH5,复用功能,上拉输出
        gpio_af_set (GPIOH,4,4);        //PH4,AF4
        gpio_af_set(GPIOH,5,4);//PH5,AF4
}[/mw_shl_code]
IIC2发送
[mw_shl_code=c,true]void iic2_send_byte(u8 dat)
{
    while(!(I2C2->ISR &(1<<0)));
    I2C2->CR1&=~(1<<0);     //IIC2失能
    I2C2->ICR|=1<<3;    //start位清0
    I2C2->CR2&=~(1<<11);    //7位
    I2C2->CR2|=1<<16;
    I2C2->CR1|=1<<0;       //IIC2使能
    I2C2->TXDR =dat;
    I2C2->CR2 |=1<<13;
    while(!(I2C2->ISR &(1<<0)))
    {
        if(I2C2->ISR&(1<<4))//1
            break;
        
    }
    I2C2->ISR|=1<<0;
}[/mw_shl_code]
就是这段代码
然后不加
if(I2C2->ISR&(1<<4))//1
break;
就卡死
加了是不卡了,但是一直NACK
就是没法送出去
IIC接收
[mw_shl_code=c,true]u8 iic2_read_byte(void)
{
    I2C2->CR2|=1<<16;
    I2C2->CR2 |=1<<13;
    while(!(I2C2->ISR &(1<<2)));
    return I2C2->RXDR ;
}[/mw_shl_code]
程序一直卡在while(!(I2C2->ISR &(1<<2)));这里
IIC地址设置
[mw_shl_code=c,true]void iic2_set_addr(u8 addr)
{
    I2C2->CR1&=~(1<<0);     //IIC2失能
    I2C2->ICR|=1<<3;    //start位清0
    if(!(addr&(1<<0)))//0
    {
        I2C2->CR2&=~(1<<10);
    }
    else
    {
        I2C2->CR2|=1<<10;
    }
    I2C2->CR2|=addr;
    I2C2->CR1|=1<<0;       //IIC2使能
}[/mw_shl_code]
AT24C02相关
[mw_shl_code=c,true]#define at24cxx_iic_read_byte()     iic2_read_byte()
#define at24cxx_iic_send_byte(x)    iic2_send_byte(x)
#define at24cxx_iic_set_addr(x)     iic2_set_addr(x)
#endif



u8 at24cxx_read_one_byte(u16 addr)
{
    at24cxx_iic_set_addr (0XA0);
    if(EE_TYPE>AT24C16)
        {
                at24cxx_iic_send_byte (addr>>8);  
        }
    at24cxx_iic_send_byte(addr%256);
    at24cxx_iic_set_addr(0xa1);
    return at24cxx_iic_read_byte ();
}
void at24cxx_send_one_byte(u16 addr,u8 dat)
{
    at24cxx_iic_set_addr (0XA0);
    if(EE_TYPE>AT24C16)
        {
                at24cxx_iic_send_byte (addr>>8);  
        }
    at24cxx_iic_send_byte(addr%256);
    at24cxx_iic_send_byte (dat);
}
[/mw_shl_code]
我也不知道发生了什么
如果有大佬发现了弱智的问题,请不要嘲笑我,毕竟完全抛开原子哥自己搞还是第一次(之前毕竟有原子哥的经验可供参考)

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。