[mw_shl_code=c,true]初学STM,因为老师上课讲了IIC,就想来练练,刚开始按照自己的理解写的程序,读回的总是0xff,后来参照原子哥的程序,现在基本改的和例程差不多了,可是读回来temp仍然是0xff。我写的时候是先将45写入24c02的0x10单元,然后再读这个0x10,将读回的数通过串口发送。不知道程序哪出错了,希望哪位大神帮忙解觉,非常感谢![/mw_shl_code]
[mw_shl_code=c,true]#include <stm32f10x_map.h>
#include <stm32f10x_nvic.h>
#include "iic.h"
#include "sys.h"
#include "delay.h"
//IIC初始化
void iic_init(void)
{
RCC->APB2ENR|=1<<4;//使能PORTC时钟
GPIOC->CRH&=0xfff00fff;
GPIOC->CRH|=0x00033000;//PC11/PC12推挽输出
GPIOC->ODR|=3<<11;//
}
//发送应答信号
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_Out();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//发送非应答信号
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_Out();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
/*void iic_ack(u8 a)
{
IIC_SCL=0;
SDA_Out();
if(a)IIC_SDA=1;
else IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);//
IIC_SCL=0;
}*/
//产生起始信号
void iic_start(void)
{
SDA_Out(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;
delay_us(4);
IIC_SCL=0;
}
//产生终止信号
void iic_stop(void)
{
SDA_Out();
IIC_SCL=0;
IIC_SDA=0;
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;
delay_us(4);
}
//检查应答信号
u8 iic_check(void)
{
u8 ucErrTime=0;
SDA_In(); //SDA线输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
iic_stop();
return 1;
}
}
IIC_SCL=0;//时钟输出为0
return 0;
}
//写入一个字节
void iic_write(u8 txd)
{
u8 t;
SDA_Out();
IIC_SCL=0;//拉低时钟,开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读回一个字节
u8 iic_read(u8 ack)//ack为应答/非应答信号
{
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)
IIC_NAck();
else
IIC_Ack();
return receive;
}
//向指定地址写入一个字节
void WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
iic_start();
iic_write(0XA0); //发送写命令
iic_check();
iic_write(WriteAddr%256);//发送要写入单元地址
iic_check();
iic_write(DataToWrite); //发送待写入数据
iic_check();
iic_stop();//产生停止条件、、
delay_ms(10);
}
//从指定地址读回一个字节
u8 ReadOneByte(u16 ReadAddr)
{
u8 temp=0;
iic_start();
iic_write(0XA0); //发送写命令
iic_check();
iic_write(ReadAddr%256);//发送要读的地址
iic_check();
iic_start();
iic_write(0XA1); //进入接收模式
iic_check();
temp=iic_read(0);
iic_stop();
return temp;
}
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
---------------------------------
我用JTAG调试,发现在执行u8 ReadOneByte(u16 ReadAddr)函数,开始发送写命令检查到应答信号正常,当执行完这一句 iic_write(0XA1); //进入接收模式 ,接收到的就是非应答信号了,这是为什么?
---------------------------------
抓个时序看下什么样的
---------------------------------
调试IIC通信,还是最好看一下,SDA和SCL的时序。一般来讲,调试不过主要一个是SCL的频率的问题。再不然和电压也有关系,一般都是收不到ACK。抓个图给我们看看
同问 后来怎么调通的?
一周热门 更多>