中级会员
 
- 积分
- 203
- 金钱
- 203
- 注册时间
- 2016-1-14
- 在线时间
- 69 小时
|
1金钱
这几天调试两个 Honeywell传感哭器。相同的程序一个正常,一个总是出现异常值。串口数据如下:
几天了,找不到原因。之前用原子的IIC,有问题。自己改了下程序,还是不行。
这是手册中的时序 。
下面是代码。不知道问题出在哪里
void SM3041_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SM3041_IIC_SCL=1;
SM3041_IIC_SDA=1;
}
//产生SM3041_IIC起始信号
void SM3041_IIC_Start(void)
{
SM3041_SDA_OUT(); //sda线输出
SM3041_IIC_SDA=1;
SM3041_IIC_SCL=1;
delay_us(4);
SM3041_IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
SM3041_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
delay_us(4);
}
//产生SM3041_IIC停止信号
void SM3041_IIC_Stop(void)
{
SM3041_SDA_OUT();//sda线输出
SM3041_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
SM3041_IIC_SCL=1;
delay_us(4);
SM3041_IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 SM3041_IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SM3041_SDA_IN(); //SDA设置为输入
SM3041_IIC_SDA=1;delay_us(3);
SM3041_IIC_SCL=1;delay_us(3);
while(SM3041_READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
SM3041_IIC_Stop();
return 1;
}
}
SM3041_IIC_SCL=0;//时钟输出0
delay_us(5);
return 0;
}
//产生ACK应答
void SM3041_IIC_Ack(void)
{
SM3041_IIC_SCL=0;
SM3041_SDA_OUT();
SM3041_IIC_SDA=0;
delay_us(2);
SM3041_IIC_SCL=1;
delay_us(2);
SM3041_IIC_SCL=0;
}
//不产生ACK应答
void SM3041_IIC_NAck(void)
{
SM3041_IIC_SCL=0;
SM3041_SDA_OUT();
SM3041_IIC_SDA=1;
delay_us(2);
SM3041_IIC_SCL=1;
delay_us(2);
SM3041_IIC_SCL=0;
}
//SM3041_IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void SM3041_IIC_Send_Byte(u8 txd)
{
u8 t;
SM3041_SDA_OUT();
SM3041_IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
SM3041_IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(4); //对TEA5767这三个延时都是必须的
SM3041_IIC_SCL=1;
delay_us(4);
SM3041_IIC_SCL=0;
delay_us(4);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 SM3041_IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
delay_us(5);
SM3041_IIC_SDA = 1;
delay_us(5);
SM3041_SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
receive<<=1;
SM3041_IIC_SCL=0;
delay_us(5);
SM3041_IIC_SCL=1;
delay_us(2);
if(SM3041_READ_SDA)
receive++;
delay_us(2);
}
SM3041_IIC_SCL = 0;
delay_us(2);
if (!ack)
SM3041_IIC_NAck();//发送nACK
else
SM3041_IIC_Ack(); //发送ACK
return receive;
}
u16 SM3041_Read_OneByte(void)
{
u8 temp;
u16 ReTemp = 0;
SM3041_IIC_Start();
SM3041_IIC_Send_Byte((0x49<<1)+1);
SM3041_IIC_Wait_Ack();
temp = SM3041_IIC_Read_Byte(1);
ReTemp = temp <<8;
temp = SM3041_IIC_Read_Byte(0);
ReTemp = ReTemp + temp;
SM3041_IIC_Stop();
return ReTemp;
}
u16 Get_SM3041_Average(u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=SM3041_Read_OneByte();
delay_ms(15);
}
return temp_val/times;
}
|
|