打印

牛人帮忙看看这个程序

[复制链接]
3054|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
永不落的星|  楼主 | 2010-12-13 16:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
高手请帮忙看一下,下面的代码调试只显示初始化信息,传感器的信息完全没有反应,由于刚转入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  
        }  
}
沙发
kvdong| | 2010-12-13 16:43 | 只看该作者
#define DATA_HIGH() TRISB2=1 //设置数据口为输入
#define DATA_LOW()  TRISB2=0 //设置数据口为输出
#define SCK_HIGH() TRISB1=1
#define SCK_LOW() TRISB1=0
你的DATA_HIGH()是定义数据方向的(输入或者输出)。操作端口应该用PORTB。

试试改为以下程序段

#define DATA_IN() TRISB2=1 //设置数据口为输入
#define DATA_OUT()  TRISB2=0 //设置数据口为输出
#define SCK_IN() TRISB1=1
#define SCK_OUT() TRISB1=0

#define DATA_HIGH() RB2=1 //设置数据口输出高电平
#define DATA_LOW()  RB2=0 //设置数据口输出低电平
#define SCK_HIGH() RB1=1
#define SCK_LOW() RB1=0

使用特权

评论回复
板凳
yewuyi| | 2010-12-13 16:46 | 只看该作者
牛人都很忙,没空看那别人写的大把大把的代码。

使用特权

评论回复
地板
yewuyi| | 2010-12-13 16:48 | 只看该作者
既然是刚入行,就慢慢一点一点看,一点一点DEBUG分析,动不动贴一摞代码,而且也不具体说明想问什么问题,你认为大家时间都好闲哦!?

使用特权

评论回复
5
kvdong| | 2010-12-13 16:48 | 只看该作者
补充:在写端口之前,先DATA_OUT();读端口之前,先DATA_IN();
SCK方向一直用输出就可以了 SCK_OUT()

用这个方法修正下你的传感器读写程序,应该就可以了

使用特权

评论回复
6
永不落的星|  楼主 | 2010-12-14 09:04 | 只看该作者
各位不好意思啦 多多包涵 呵呵
谢谢楼上的朋友 把端口设置改了 还是不行 忘说一个问题了 就是编译有2个警告 wendu=10*temp_val.f;
shidu=10*humi_val.f;浮点数和整型转化的问题 implicit conversion of float to integer   有时间帮忙看一下 谢谢

使用特权

评论回复
7
liumapple| | 2010-12-20 14:27 | 只看该作者
humi_val.f这个是浮点型。shidu是整型。浮点型赋值给整型当然会警告

使用特权

评论回复
8
tog10| | 2010-12-21 23:11 | 只看该作者
编译通过了说下呀。应该是温湿度控制的程序。

使用特权

评论回复
9
永不落的星|  楼主 | 2010-12-26 16:46 | 只看该作者
好久没进来了 呵呵 谢谢各位 问题已经搞定了  是读MSB和LSB的高低位搞反了

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
SLEET1986 + 1
10
SLEET1986| | 2011-1-3 16:37 | 只看该作者
说明了问题,不错,给了别人指引---

使用特权

评论回复
11
21passteenic| | 2011-1-3 18:59 | 只看该作者
PIC有很多的芯片,发帖要说明用的哪一类型的芯片以及大概的接口,不然有时候会有疑问,牛人们看了不知如何回答

使用特权

评论回复
12
315199692| | 2014-6-13 20:53 | 只看该作者
永不落的星 发表于 2010-12-26 16:46
好久没进来了 呵呵 谢谢各位 问题已经搞定了  是读MSB和LSB的高低位搞反了

能详细说下吗  我也是和你一样的程序  就是不显示呀  调了好久了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

72

帖子

0

粉丝