高手请帮忙看一下,下面的代码调试只显示初始化信息,传感器的信息完全没有反应,由于刚转入PIC行业,不是很熟悉,大伙帮忙看看了
代码如下:
#include <pic.h>
#include <math.h>
__CONFIG(0x1832); //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
#define LCD_RS RA1
#define LCD_RW RA2
#define LCD_E RA3
#define LCD_data PORTD
#define SCK RB1 //定义通讯时钟端口
#define DATA RB2 //定义通讯数据端口
#define DATA_HIGH() TRISB2=1 //设置数据口为输入
#define DATA_LOW() TRISB2=0 //设置数据口为输出
#define SCK_HIGH() TRISB1=1
#define SCK_LOW() TRISB1=0
#define _nop_() asm("nop")
#define noACK 0 //用于判断是否结束通讯
#define ACK 1 //结束数据传输
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
typedef union
{ unsigned int i; //定义了两个共用体
float f;
} value;
enum {TEMP,HUMI}; //TEMP=0,HUMI=1
/******定义函数****************/
#define uchar unsigned char
#define uint unsigned int
void LCD_init(void); //初始化函数
void LCD_write_command(uchar command); //写指令函数
void LCD_write_data(uchar dat); //写数据函数
void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
void LCD_disp_str(uchar x,uchar y,const uchar *str); //LCD1602显示字符串函数
void DELAY(unsigned int i); //延时函数
void init_uart(); //Uart初始化
void s_transstart(void); //启动传输函数
void s_connectionreset(void); //连接复位函数
char s_write_byte(unsigned char value);//SHT11写函数
char s_read_byte(unsigned char ack); //SHT11读函数
char s_read_statusreg(uchar *p_value,uchar *p_checksum);//读状态寄存器数据函数
char s_write_statusreg(uchar *p_value);//写状态寄存器数据函数
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//测量温湿度函数
void calc_11(float *p_humidity ,float *p_temperature);//测量温湿度函数
void LCD_init(void) /*初始化函数*/
{
DELAY(10);
LCD_write_command(0x38);//设置8位格式,2行,5x7
DELAY(10);
LCD_write_command(0x0c);//整体显示,关光标,不闪烁
DELAY(10);
LCD_write_command(0x06);//设定输入方式,增量不移位
DELAY(10);
LCD_write_command(0x01);//清除屏幕显示
DELAY(100); //延时清屏,延时函数
}
void LCD_write_command(uchar dat) /*写指令函数*/
{
DELAY(10);
LCD_RS = 0; //指令
LCD_RW = 0; //写入
LCD_E = 1; //允许
LCD_data = dat;
DELAY(10);
LCD_E = 0;
DELAY(10);
}
void LCD_write_data(uchar dat) /*写数据函数*/
{
DELAY(10);
LCD_RS=1; //数据
LCD_RW=0; //写入
LCD_E=1; //允许
LCD_data=dat;
DELAY(10);
LCD_E=0;
DELAY(10);
}
void LCD_disp_char(uchar x,uchar y,uchar dat) /*在某个屏幕位置上显示一个字符,X(0-15),y(1-2)*/
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
void LCD_disp_str(uchar x,uchar y,const uchar *str) /*LCD1602显示字符串函数*/
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
while(*str!='\0')
{
LCD_write_data(*str);
str++;
}
}
void DELAY(unsigned int i)
{
for (i;--i;) continue;
}
void s_transstart(void) /*启动传输函数*/
{
DATA_HIGH(); SCK_LOW(); //状态初始化
_nop_();
SCK_HIGH();
_nop_();
DATA_LOW();
_nop_();
SCK_LOW();
_nop_();_nop_();_nop_();
SCK_HIGH();
_nop_();
DATA_HIGH();
_nop_();
SCK_LOW();
}
void s_connectionreset(void) /*连接复位函数*/
{
unsigned char i;
DATA_HIGH(); SCK_LOW(); //状态初始化
for(i=0;i<9;i++) //DATA保持高,SCK触发9次,发送启动传输,通讯开始复位
{
SCK_HIGH();
SCK_LOW();
}
s_transstart(); //transmission start
}
char s_write_byte(unsigned char value) /*SHT11写函数*/
{
unsigned char i,error=0;
for (i=0x80;i>0;i>>=1) //循环右移,发送8位数据
{
if (i & value) DATA_HIGH(); //写 SENSI-BUS
else DATA_LOW();
SCK_HIGH();
_nop_();_nop_();_nop_(); // 3 us
SCK_LOW();
}
DATA_HIGH(); //释放数据线
SCK_HIGH(); //clk #9 for ack
error=DATA; //检查应答信号,确认通讯正常
_nop_();_nop_();_nop_();
SCK_LOW();
DATA_HIGH(); //释放数据线
return error; //返回:0通讯成功,1通讯失败
}
char s_read_byte(unsigned char ack) /*SHT11读函数*/
{
unsigned char i,val=0;
DATA_HIGH();
for (i=0x80;i>0;i>>=1) // 循环右移,发送8位数据
{ SCK_HIGH(); //读 SENSI-BUS
if (DATA) val=(val | i); //读一位数据线值
_nop_();_nop_();_nop_(); // 3 us
SCK_LOW();
}
if(ack==1)DATA_LOW(); //如果 "ack==1" , 拉低数据线
else DATA_HIGH(); //如果是校验(ack==0),读取完后结束通讯
_nop_();_nop_();_nop_(); // 3 us
SCK_HIGH(); //clk #9 for ack
_nop_();_nop_();_nop_(); // 3 us
SCK_LOW();
_nop_();_nop_();_nop_(); // 3 us
DATA_HIGH(); //释放数据线
return val;
}
char s_read_statusreg(uchar *p_value,uchar *p_checksum)/*读状态寄存器数据函数*/
{
uchar error=0;
s_transstart();
error=s_write_byte(STATUS_REG_R); //给传感器发送命令
*p_value=s_read_byte(ACK); //读状态寄存器(8-bit)
*p_checksum=s_read_byte(noACK); //读checksum(8-bit)
return error;
}
char s_write_statusreg(uchar *p_value)/*写状态寄存器数据函数*/
{
uchar error=0;
s_transstart();
error+=s_write_byte(STATUS_REG_W); //发寄存器命令
error+=s_write_byte(*p_value);//从状态寄存器发送数据
return error;//error>=1 in case of response from the sensor
}
void init_uart() /*Uart初始化*/
{
ADCON1=0x07;
TRISB=0x00;
TRISD=0x00;
TRISA=0x00;
}
char s_measure(uchar *p_value, uchar *p_checksum, uchar mode) /*测量温湿度函数*/
{
unsigned error=0;
uint i;
s_transstart(); //调用传输启动函数
switch(mode){ //给传感器发送指令 TEMP位温度 HUMI位湿度
case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i<65535;i++) if(DATA==0) break; //延时等待直到测量完成
if(DATA) error+=1; // 超时,测量错误
*(p_value) =s_read_byte(ACK); //先读MSB
*(p_value+1)=s_read_byte(ACK); //后读LSB
*p_checksum =s_read_byte(noACK); //read checksum CRC
return error;
}
void calc_sht11(float *p_humidity ,float *p_temperature) /*计算温湿度函数*/
{ const float C1=-4.0; // 湿度默认为12位
const float C2=+0.0405;
const float C3=-0.0000028;
const float T1=+0.01; // 14位 5v
const float T2=+0.00008;
float rh=*p_humidity; // rh:Humidity 12 bit 湿度默认为12位
float t=*p_temperature; // t:temperature 14 bit 温度默认为14位
float rh_lin; //湿度
float rh_true; // 温度对相对湿度的补偿
float t_C; // 温度
t_C=t*0.01 - 40; //temp补偿
rh_lin=C3*rh*rh + C2*rh + C1; //相对humi非线性补偿
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相对湿度对于温度依赖性补偿
if(rh_true>100)rh_true=100; //湿度最大修正
if(rh_true<0.1)rh_true=0.1; //最小修正
*p_temperature=t_C; //return 温度
*p_humidity=rh_true; //return 湿度
}
/*************************主函数****************************/
void main(void)
{
value humi_val,temp_val;
uchar error,checksum;
uint wendu,shidu;
init_uart();
LCD_init();
LCD_disp_str(0,1,"WELCOME TO SIKO!");
DELAY(10000);
LCD_write_command(0x01);
s_connectionreset();
LCD_disp_str(0,1,"TE");
LCD_disp_str(0,2,"RH");
LCD_disp_str(2,1,"TTT.TC");/*初始化温度显示区*/
LCD_disp_str(2,2,"RRR.R%");/*初始化湿度显示区*/
DELAY(20000); //延时0.2s
while(1)
{ error=0;
error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI); //测湿度
error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP); //测温度
if(error!=0) s_connectionreset(); //错误则复位
else
{ humi_val.f=(float)humi_val.i; //转为浮点数
temp_val.f=(float)temp_val.i; //转为浮点数
calc_sht11(&humi_val.f,&temp_val.f); //计算温湿度
wendu=10*temp_val.f;
LCD_disp_char(2,1,wendu/1000+'0'); //显示温度百位
LCD_disp_char(3,1,(wendu%1000)/100+'0'); //显示温度十位
LCD_disp_char(4,1,(wendu%100)/10+'0'); //显示温度个位
LCD_disp_char(6,1,(wendu%10)+'0'); //显示温度小数点后第一位
shidu=10*humi_val.f;
LCD_disp_char(2,2,shidu/1000+'0'); //显示湿度百位
LCD_disp_char(3,2,(shidu%1000)/100+'0'); //显示湿度十位
LCD_disp_char(4,2,(shidu%100)/10+'0'); //显示湿度个位
LCD_disp_char(6,2,(shidu%10)+'0'); //显示湿度小数点后第一位
}
//----------wait approx. 0.8s to avoid heating up SHTxx------------------------------
DELAY(80000); //延时约0.8s
}
} |
|