我在调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]
我也不知道发生了什么
如果有大佬发现了弱智的问题,请不要嘲笑我
,毕竟完全抛开原子哥自己搞还是第一次(之前毕竟有原子哥的经验可供参考)
一周热门 更多>