打印

f149调DHT11的程序问题

[复制链接]
698|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CaLipton|  楼主 | 2018-5-26 16:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MSP430f149调DHT11的程序,液晶上温度显示50以上怎么回事
#include  <msp430x14x.h>
#include "1602.c"
#define uchar unsigned char
#define uint  unsigned int
#define HIGH P2OUT|=BIT1;
#define LOW P2OUT&=~BIT1;
char temph,templ,humdh,humdl,check,cal;
uchar shuzu[]={0,1,2,3,4,5,6};

void delay_1ms(uint z)
{
   uint i,j;
   for(i=z;i>0;i--)  
        for(j=80;j>0;j--);
}        

void DelayNus(uint n)//延时1US函数
{
   
    TACTL|= TASSEL_2+TACLR+ID_3;//定时器A,时钟为SCLK,8分频;   
    TACTL |= MC_1;           //增计数到CCR0
    TACCR0 = n;
    while((TACTL & BIT0)!=0x01);  //等待
    TACTL &= ~MC_1;          //停止计数
    TACTL &= ~BIT0;          //清除中断标志
}

void init_clk()
{
    int i;
    WDTCTL=WDTPW+WDTHOLD;
    BCSCTL1&=~XT2OFF;
    do
    {
      IFG1 &=~OFIFG;
      for(i=0xff;i>0;i--);
    }
    while(IFG1&OFIFG);
    BCSCTL2|= SELM_2+SELS;//SCLK,MCLK都选择为外部时钟     
}

char receive(void)               //接受函数
{
  char temp,cnt=0;                      //临时变量用于存储接受数据
  while(cnt<8)
  {
      while((P2IN&BIT1)==0);              //等待50us的低电平结束
      DelayNus(35);  
      if(P2IN&BIT1)                       //长于30us定义为1
      {
        temp++;                       
        temp<<=1;
        while(P2IN&BIT1);             //结束高电平,即下一位数据的到来
      }
      else
      {
        temp<<=1;
      }
      if(cnt!=7)
         while(!(P2IN&BIT1));              //最后一次给函数返回留下时间
      cnt++;
  }
  return temp;
}
void work_data(void)
{
  P2DIR |= BIT1;    //设置P2.1为输出状态
  HIGH;
  _NOP();_NOP();_NOP();
  LOW;
  DelayNus(18000);    //开始信号
  HIGH;
  DelayNus(30);
  P2DIR&=~BIT1;    //设置P2.1为输入状态,检测传感器响应
  DelayNus(20);     //20US后  P2IN  是否为低电平,不为低电平 说明复位失败,重新开始
  while((P2IN&BIT1)!=0)//如果没有检测到响应信号 继续发送开始信号
  {
      P2DIR |= BIT1;    //设置P2.1为输出状态
      HIGH;
      _NOP();_NOP();_NOP();
      LOW;
      DelayNus(18000);    //开始信号
      HIGH;
      DelayNus(30);
      P2DIR&=~BIT1;    //设置P2.1为输入状态,检测传感器响应
      DelayNus(20);
  }
  while((P2IN&BIT1)==0);//等待拉高,准备输出数据
  while(P2IN&BIT1);  //等待低电平,输出数据
                     //下面开始接受数据  
  humdh=receive();
  humdl=receive();
  temph=receive();
  templ=receive();
  check=receive();
  cal=humdh+humdl+temph+templ;
}

void main()
{            
    char R_shi,R_ge,T_shi,T_ge,T_xs1,T_xs2,R_xs;
    WDTCTL=WDTPW+WDTHOLD;
    P2DIR=0XFF;
    P2OUT=0X00;
    init_clk();
    yejing_init();
    while(1)
     {
      work_data();
      if(check==cal)
      {
        R_shi = 0x30+humdh / 10;
        R_ge = 0x30+humdh % 10;
        R_xs = 0x30+humdl / 10;
        T_shi = 0x30+temph /10;
        T_ge = 0x30+temph % 10;
        T_xs1 = 0x30+templ / 10;
        T_xs2 = 0x30+templ % 10;
        
        
        shuzu[0] = R_shi;
        shuzu[1] = R_ge;
        shuzu[2] = R_xs;
        shuzu[3] = T_shi;
        shuzu[4] = T_ge;
        shuzu[5] = T_xs1;
        shuzu[6] = T_xs2;
        
      LCD_write_char(0,0,shuzu[0]);
      LCD_write_char(1,0,shuzu[1]);
      LCD_write_str(2,0,".");
      LCD_write_char(3,0,shuzu[2]);
      
      LCD_write_char(0,1,shuzu[3]);
      LCD_write_char(1,1,shuzu[4]);
      LCD_write_str(2,1,".");
      LCD_write_char(3,1,shuzu[5]);
      LCD_write_char(4,1,shuzu[6]);
      delay_1ms(3000);//等待下次采样
    }
}
}


/***********************************************
1602液晶显示程序,主程序中如下写
unsigned char dis[]={1,2,3,4,5,6};
yejing_init(  )初始化
LCD_write_str(0,0,"welloooo");//输出字符串
LCD_write_char(4,1,48+dis[0]);//输出数组

IO P4 RS P25 RW  P24  EN P23
************************************************/
#include <msp430x14x.h>

#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) //延时
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))

#define RS_CLR                P2OUT &= ~BIT5           //RS置低
#define RS_SET                P2OUT |=  BIT5           //RS置高
#define RW_CLR                P2OUT &= ~BIT4           //RW置低
#define RW_SET                P2OUT |=  BIT4          //RW置高
#define EN_CLR                P2OUT &= ~BIT3           //E置低
#define EN_SET                P2OUT |=  BIT3           //E置高
#define DataPort        P4OUT                     //P4口为数据口

#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long

/***************************初始化IO口子程序***********************/
void Port_init()
{

        P4SEL = 0x00;
        P4DIR = 0xFF;                   //数据口输出模式
        P2SEL = 0x00;
        P2DIR|= BIT5 + BIT4 + BIT3;     //控制口设置为输出模式
}

/**************************显示屏命令写入函数***********************/
void LCD_write_com(unsigned char com)
{        
        RS_CLR;
        RW_CLR;
        EN_SET;
        DataPort = com;                 //命令写入端口
        delay_ms(5);
        EN_CLR;
}

/************************显示屏数据写入函数************/
void LCD_write_data(unsigned char data)
{
        RS_SET;
        RW_CLR;
        EN_SET;
        DataPort = data;                //数据写入端口
        delay_ms(5);
        EN_CLR;
}

/*****************************显示屏清空显示*********************/
void LCD_clear(void)
{
        LCD_write_com(0x01);            //清屏幕显示
        delay_ms(5);
}

/****************************显示屏字符串写入函数************************/
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
{
        
    if (y == 0)
    {
            LCD_write_com(0x80 + x);        //第一行显示
    }
    else
    {
            LCD_write_com(0xC0 + x);        //第二行显示
    }
   
    while (*s)
    {
            LCD_write_data( *s);
            s ++;
    }
}

//***********************************************************************
//        显示屏单字符写入函数
//***********************************************************************
void LCD_write_char(unsigned char x,unsigned char y,unsigned char data)
{
        
    if (y == 0)
    {
            LCD_write_com(0x80 + x);        //第一行显示
    }
    else
    {
            LCD_write_com(0xC0 + x);        //第二行显示
    }
   
    LCD_write_data( data);  
}


/*********************系统时钟初始化*********************/
void Clock_Init()
{
  uchar i;
  BCSCTL1&=~XT2OFF;                 //打开XT2振荡器
  BCSCTL2|=SELM1+SELS;              //MCLK为8MHZ,SMCLK为8MHZ
  do{
    IFG1&=~OFIFG;                   //清楚振荡器错误标志
    for(i=0;i<100;i++)
       _NOP();
  }
  while((IFG1&OFIFG)!=0);           //如果标志位1,则继续循环等待
  IFG1&=~OFIFG;
}

/***************显示屏初始化函数***********************/
void LCD_init(void)
{
    LCD_write_com(0x38);                //显示模式设置  
    delay_ms(5);
    LCD_write_com(0x08);                //显示关闭
    delay_ms(5);
    LCD_write_com(0x01);                //显示清屏
    delay_ms(5);
    LCD_write_com(0x06);                //显示光标移动设置
    delay_ms(5);
    LCD_write_com(0x0C);                //显示开及光标设置
    delay_ms(5);
}
void yejing_init(void)
{
    // Clock_Init();                       //系统时钟设置
     Port_init();                        //系统初始化,设置IO口属性
     delay_ms(100);                      //延时100ms
     LCD_init();                         //液晶参数初始化设置
     LCD_clear();                        //清屏
}

相关帖子

沙发
Rospiers| | 2018-5-26 16:47 | 只看该作者
while((P2IN&BIT1)==0);//等待拉高,准备输出数据
改成
while((P2IN&BIT1)==1);//等待拉高,准备输出数据

使用特权

评论回复
板凳
Lewisnx| | 2018-5-26 17:04 | 只看该作者
我也遇到了,温度特别高,不知道楼主解决没有

使用特权

评论回复
地板
dirtwillfly| | 2018-5-26 17:14 | 只看该作者
要不是读数错了,就是显示的时候显示错了
就这两种可能

使用特权

评论回复
5
CCompton| | 2018-5-26 17:17 | 只看该作者
while((P2IN&BIT1)==1);//等待拉高,准备输出数据
这句话不就是相当于直接屏蔽,下面有while((P2IN&BIT1);
DHT11不是有响应80us时间吗,程序貌似直接跳过这一步了,楼主怎么认为,怎么解释时序

使用特权

评论回复
6
Richardd| | 2018-5-26 17:33 | 只看该作者
为什么程序直接跳过这一步了
楼主设置断点看看

使用特权

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

本版积分规则

126

主题

369

帖子

0

粉丝