利用M16采集SHT10,通过485输出。测试输出test1的值为06,说明write_Bytes写命令返回ACK是1,而不是0.麻烦各位帮忙一下看哪错了,谢谢!
#define F_CPU 7372800UL
#define DIR_TX PORTD|=(1<<2)
uint8 a=0x00;
uint8 b=0x00;
uint8 c=0x00;
uint8 test1=0;
uint8 test2=0;
enum {SHT1X_TEMP, SHT1X_HUMI};
void UART_Init(uint32 Baud)
{
UCSRC = 0x86; //异步模式,无校验,停止位1,字符长度8位,
UBRRL= (F_CPU/Baud/16-1)%256; //在Codeblocks中已配置F_CPU为8M
UBRRH= (F_CPU/Baud/16-1)/256;
UCSRB = 0x98;
DDRD|=(1<<2); // DDRD|=(1<<PD2); 把485EN配置成输出
DIR_TX;
}
void uart_send(uint8 e_DATA)
{
UDR=e_DATA;
}
void SHT1x_Init(void)
{
SHT10_SCK_Out;
SHT10_DATA_Out;
SHT10_SCK_L;
SHT10_DATA_H;
SHT10_ConReset(); //复位通讯
}
//*************************************************************
// Function :SHT10_WriteByte
// Description:写1字节,主要用来写地址+命令(如示例时序000 00101)
// Input : value:要写入的字节
// return : err: 0-正确 1-错误 ,【返回的为应答位】
//*************************************************************/
uint8 SHT10_WriteByte(uint8 value)
{
uint8 i, err = 0;
SHT10_DATA_Out;
SHT10_DATA_H;
SHT10_SCK_L;
//设置DATA数据线为输出
for(i = 0x80; i > 0; i/=2) //写1个字节 1000 0000 另一种写法for(i = 0x80; i > 0; i /= 2)
{
if(i & value) //获取value每一位的值。
SHT10_DATA_H;
else
SHT10_DATA_L;
delay_1us();
SHT10_SCK_H;
delay_3us();
delay_3us();
SHT10_SCK_L;
delay_1us();
}
SHT10_DATA_H; //注意此处 ,把DATA置为高,看传感器是否拉低来ack
SHT10_SCK_H;
SHT10_DATA_In; //设置DATA数据线为输入,释放DATA线
if(SHT10_DATA_Read==0)
{
err=0;
}
else
{
err=5;
}
SHT10_SCK_L;
delay_1us();
return err; //返回01问题所在
}
///*************************************************************
// Function :SHT10_ReadByte
// Description:读1字节数据. 主要是读数据和校验
// Input : Ack: 0-不应答 1-应答 (读完数据后一般给个应答信号为好)
// return : val读出的值
//*************************************************************/
uint8 SHT10_ReadByte(uint8 Ack)
{
uint8 i,val = 0;
SHT10_DATA_Out; //释放数据线
SHT10_DATA_H;
SHT10_DATA_In;
for(i = 0x80; i > 0; i/= 2) //读取1字节的数据
{
SHT10_SCK_H;
delay_1us();
if(SHT10_DATA_Read==0x02) val = (val | i); //PINC&0X02 , 识别是1还是0,==0x02,说明传输过来的是1
SHT10_SCK_L;
delay_1us();
}
delay_1us();
SHT10_DATA_Out;
delay_1us();
if(Ack) //Ack: 0-不应答 1-应答
SHT10_DATA_L; //应答,则会接下去读接下去的数据(校验数据)
else
SHT10_DATA_H; //不应答,数据至此结束
delay_1us();
SHT10_SCK_H;
delay_3us();
delay_3us();
SHT10_SCK_L;
delay_1us();
SHT10_DATA_H;
return val; //返回读到的值
}
///*************************************************************
// Function :SHT10_TransStart
// Description:开始传输信号,时序如下:
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
// Input : none
// return : none
//*************************************************************/
void SHT10_TransStart(void)
{
SHT10_DATA_Out; //设置DATA数据线为输出
SHT10_DATA_H;
SHT10_SCK_L; //初始状态
delay_1us();
SHT10_SCK_H;
delay_1us();
SHT10_DATA_L;
delay_1us();
SHT10_SCK_L;
delay_3us();
delay_3us();
SHT10_SCK_H;
delay_1us();
SHT10_DATA_H;
delay_1us();
SHT10_SCK_L;
delay_1us();
}
///*************************************************************
// Function :SHT10_ConReset
// Description:通讯复位,主要是把通信的时序重新理一下,不修改寄存器内容。时序如下:
// _____________________________________________________ ________
// DATA: |_______|
// _ _ __ _ __ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |_____| |____| |______
// Input : none
// return : none
//*************************************************************/
void SHT10_ConReset(void)
{
uint8 i;
SHT10_DATA_Out;
SHT10_DATA_H;
SHT10_SCK_L; //起始状态
for(i = 0; i < 9; i++) //触发SCK时钟9c次
{
SHT10_SCK_H;
delay_1us();
SHT10_SCK_L;
delay_1us();
}
delay_1us();
SHT10_TransStart(); //启动传输
}
///*************************************************************
// Function :SHT10_SoftReset
// Description:软复位, 主要是复位状态寄存器为默认状态
// Input : none
// return : err: 0-正确 1-错误
//*************************************************************/
uint8 SHT10_SoftReset(void)
{
uint8 err = 0;
SHT10_ConReset(); //通讯复位 主要是复位时序
err += SHT10_WriteByte(SOFTRESET); //写RESET复位命令 #define SOFTRESET 0x1E //000 11110 复位命令
return err;
}
///*************************************************************
// Function :SHT10_ReadStatusReg
// Description:读状态寄存器
// Input : p_value-读到的数据;p_checksun-读到的校验数据
// return : err: 0-正确 1-错误
//*************************************************************/
uint8 SHT10_ReadStatusReg(uint8 *p_value, uint8 *p_checksum)
{
uint8 err = 0;
SHT10_TransStart(); //开始传输
err = SHT10_WriteByte(STATUS_REG_R); //写STATUS_REG_R读取状态寄存器命令 //000 00111
*p_value = SHT10_ReadByte(ACK); //读取状态数据 ACK=1
*p_checksum = SHT10_ReadByte(noACK); //读取检验和数据
return err;
}
///*************************************************************
// Function :SHT10_WriteStatusReg
// Description:写状态寄存器
// Input : p_value-要写入的数据值
// return : err: 0-正确 1-错误
//*************************************************************/
uint8 SHT10_WriteStatusReg(uint8 *p_value)
{
uint8 err = 0;
SHT10_TransStart(); //开始传输
err += SHT10_WriteByte(STATUS_REG_W); //写STATUS_REG_W写状态寄存器命令
err += SHT10_WriteByte(*p_value); //写入配置值
return err;
}
///*************************************************************
// Function :SHT10_Measure
// Description:从温湿度传感器读取温湿度
// Input : p_value-读到的值;p_checksum-读到的校验数
// return : err: 0-正确 1—错误
//*************************************************************/
uint8 SHT10_Measure(float *p_value, uint8 *p_checksum, uint8 mode)
{
uint8 err = 0;
uint32 i;
int8 value_H = 0;
int8 value_L = 0;
SHT10_TransStart(); //开始传输
switch(mode)
{
case SHT1X_TEMP: //测量温度
err += SHT10_WriteByte(MEASURE_TEMP);//写MEASURE_TEMP测量温度命令
break;
case SHT1X_HUMI:
err += SHT10_WriteByte(MEASURE_HUMI);//写MEASURE_HUMI测量湿度命令
break;
default:
break;
}
SHT10_DATA_In;
delay_1ms();
for(i = 0; i < 65535; i++)
{
if(SHT10_DATA_Read==0)
break; //等待DATA信号被拉低
}
if(SHT10_DATA_Read)
{err += 1; //如果等待超时了
test1=err; //02
}
value_H = SHT10_ReadByte(ACK);
value_L = SHT10_ReadByte(ACK);
*p_checksum = SHT10_ReadByte(noACK); //读取校验数据
*p_value = (value_H << 8) | value_L;
return err;
}
void SHT10_WORK_Value(void)
{
float temp_read;
float humi_read;
uint8 err1 = 0,err2 = 0,checksum = 0;
err1 += SHT10_Measure(&temp_read, &checksum, SHT1X_TEMP); //获取温度测量值
err2 += SHT10_Measure(&humi_read, &checksum, SHT1X_HUMI); //获取湿度测量值
if(err1 != 0)
{
test2=err1;
a=0x11;
b=0x12;
c=0x13;
// SHT10_ConReset(); //原文有此行
}
else if(err2 != 0)
{
a=0x04;
b=0x05;
c=0x06;
// SHT10_ConReset(); //原文有此行
}
else
{
a = 0x07;
b = 0x08;
c = 0x09;
}
}
void main(void)
{
// delay_nms(11);
UART_Init(9600) ;
SHT1x_Init();
while(1)
{
SHT10_WORK_Value();
uart_send(test1);
delay_nms(1000);
uart_send(test2);
delay_nms(1000);
uart_send(a);
delay_nms(1000);
uart_send(b);
delay_nms(1000);
uart_send(c);
delay_nms(1000);
}
}