Thông báo

Collapse
No announcement yet.

Giúp mình code đo nhiệt độ và độ ẩm

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Giúp mình code đo nhiệt độ và độ ẩm

    Mình đang làm mạch đo nhiệt độ và độ ẩm dùng DS18B20 và HS1101. Code đo nhiệt độ mình có tham khảo bên minhhagroup nhưng khi mô phỏng trên protues thì bị hiện tượng sau:
    + Nhiệt độ ban đầu hiện thị đúng nhưng sau 1 khoảng thời gian thì bị lỗi
    + Mọi người xem giúp mình cái độ ẩm hok hiểu sao nó hiện thị ra số đó nữa
    + Trong khi mô phỏng thi thoảng mình điều chỉnh code thì nó báo lỗi là DS1822 RAM UNSUPPORTED
    Mình mò mấy ngày nay mà hok được, mong sự giúp đỡ của mọi người.

    Code:
    #include<REGX52.H>
    #include<stdio.h>
    
    #define RS P2_0
    #define RW P2_1        
    #define EN P2_2
    #define LCD_PORT P1
    #define DQ P2_6
    
    /////////khai bao bien toan cuc/////////////////
    unsigned char temp;
    unsigned char k;
    unsigned int tanso;
    unsigned int code f[100]={7410,7392,7374,7357,7340,7323,7307,7290,7274,7259,7243,7228,7213,7198,7183,7169,7155,7140,7127,7113,7099,7086,7072,7059,7046,7033,7020,7007,6995,6982,6969,6957,6945,6932,6920,6908,6896,6884,6872,6860,6848,6836,6824,6812,6800,6788,6776,6764,6752,6740,6728,6716,6704,6692,6680,6668,6656,6643,6631,6619,6606,6594,6581,6568,6556,6543,6530,6517,6504,6491,6477,6464,6450,6437,6423,6409,6395,6381,6367,6352,6338,6323,6309,6294,6279,6264,6248,6233,6217,6202,6186,6170,6154,6137,6121,6104,6087,6053,6036,6019};
    
    ////////cac ham de lay/////////////////////////
    void delay_ms(unsigned int Time)
    {
    	unsigned int i,j;
    	for(i=0;i<Time;i++)
    	{
    		for(j=0;j<125;j++);
    	}
    }
    
    void delay_us(unsigned int Time)
    {
    	unsigned int i,j;
    	for(i=0;i<Time;i++)
    	{
    		for(j=0;j<2;j++);
    	}
    } 
    
    void delay_18B20(unsigned char x)
    {
      unsigned char i;
      for(i=0;i<x;i++);
    }
    ///////////////////////////////////////////////
    
    ////////cac ham ve LCD 20X4////////////////////
    
    void LCDWriteCmd(unsigned char c)     //CT con ghi lenh len LCD
    {
     RS=0;
     RW=0;
     LCD_PORT=c;
     EN=1;
     EN=0;
     delay_ms(5);
    }
    
    void LCDWriteData(unsigned char c)     //CT con ghi du lieu tu LCD
    {
     RS=1;
     RW=0;
     LCD_PORT=c;
     EN=1;
     EN=0;
     delay_ms(5);
    }
    
    void LCD_init()          // Khoi tao LCD
    {
     delay_ms(15);
     LCDWriteCmd(0x38);
     LCDWriteCmd(0x38);
     LCDWriteCmd(0x0C);
     LCDWriteCmd(0x01);      
    }
    
    void LCD_clear()	//xoa man hinh LCD
    {
     LCDWriteCmd(0x01);
    }
    
    void LCD_home()		//dua con tro ve dau dong 1
    {
     LCDWriteCmd(0x80);
    }
    
    void LCD_putstr(unsigned char *s)	//ghi 1 chuoi len LCD
    {
     while (*s)
     {
      LCDWriteData(*s);
      s++;
     }
    }
    /////////////////////////////////////////////////////////////////
    
    ////////cac ham ve DS18B20//////////////////////////////////////
    
    void Init_DS18B20()	   //ham khoi tao DS18B20
     {
        unsigned char x=0;
        DQ = 1;
        delay_18B20(8);
        DQ = 0;
        delay_18B20(80);
        DQ = 1;
        delay_18B20(14);
        x=DQ;
        delay_18B20(20);
    	
     }
    
    unsigned char ReadOneChar()  //ham doc 1 byte vao DS18B20
     {
        unsigned char i=0;
        unsigned char dat = 0;
        for (i=8;i>0;i--)
        {
        	DQ = 0;
        	dat>>=1;
        	DQ = 1;
        	if(DQ)
        	dat|=0x80;
        	delay_18B20(5);
        }
        return(dat);
     }
    
    void WriteOneChar(unsigned char dat) //ham viet 1 byte vao DS18B20
    {
        unsigned char i=0;
        for (i=8; i>0; i--)
        {
        	DQ = 0;
        	DQ = dat&0x01;
    	    delay_18B20(5);
        	DQ = 1;
        	dat>>=1;
        }
    }
    
    unsigned char ReadTemp()
    {
        unsigned char a=0;
        unsigned char b=0;
        
    	Init_DS18B20();
        WriteOneChar(0xCC);
        WriteOneChar(0x44);
        delay_ms(100);
        
    	Init_DS18B20();
        WriteOneChar(0xCC);
        WriteOneChar(0xBE);
        delay_ms(100);
    
    	a=ReadOneChar();
    	b=ReadOneChar();
     	Init_DS18B20();
    	temp=(b<<4)|(a>>4);
    	return(temp);
    }
    ////////////////////////////////////////////////////////
    
    ////////ham ve HS1101//////////////////////////////////
    void ngat_trantimer0() interrupt 1 
    {	unsigned int Time;
     	TH0=0xFC;
    	TL0=0x2B;
    	Time++;
    	if(Time==1000)									   
    	{
    		Time=0;										  // dinh thoi 1s
    		TR1=0;
    		tanso=(((TH1&0x00ff)<<8)|(TL1&0x00ff));		  //tan so bang so xung dem duoc trong 1s
    		TH1=0;
    		TL1=0;
    		TR1=1;
    	}
    	TF0=0;	
    }
    
    unsigned char humid(unsigned int tanso)
    {	unsigned char k;
     	while(tanso<f[k])
    	{
    	 k++;
    	}
    	return(k);
    	
    } 	 
    //////////////////////////////////////////////////
    
    ////////ham main/////////////////////////////////
    
    void main()
    {
    	float Nhiet_Do;
    	unsigned char do_am;
    	unsigned char Lcd_Buff[5];
    	unsigned char Lcd_Buff1[5];
    	TMOD=0x51;
    	IE=0x82;                                           //thiet lap ngat timer 0
    	TR0=1;
    	LCD_init();    
    	LCD_clear(); 
    	LCD_home(); 
    	LCD_putstr("DO AN MON HOC 2");
    	LCDWriteCmd(0xC0);
    	LCD_putstr("DO NHIET DO & DO AM");
    	LCDWriteCmd(0x94);
    	LCD_putstr("NHIET DO:");
    	LCDWriteCmd(0xD4);
    	LCD_putstr("DO AM:");
    	delay_ms(50);
    	while(1)
    		{
    		
    			Nhiet_Do = ReadTemp();		
    			//sprintf(Lcd_Buff,"NHIET DO: %2.0f oC",Nhiet_Do);
    			sprintf(Lcd_Buff,"%.0f",Nhiet_Do);
    			LCDWriteCmd(0x9D);
    			LCD_putstr(Lcd_Buff);
    			delay_ms(300);
    
    			//do_am=humid();
    			//sprintf(Lcd_Buff,"DO AM: %2.0d",vitrf);
    			do_am=humid();
    			sprintf(Lcd_Buff1,"%d",do_am);
    			LCDWriteCmd(0xDC);
    			LCD_putstr(Lcd_Buff1);
    			delay_ms(300);
    		}
    }
    Hình ảnh

    File mô phỏng + Code
    CODE.zip

  • #2
    hok cóa ai giúp mình à

    Comment


    • #3
      Chương trình của minh hà ko hề sai. sai là do cách dùng của bạn
      bạn hiểu thế này nhé. các dạng giao tiếp SPI hay I2C... thì nó có 1 chân xung clock để tạo đồng bộ giữa 2 thiết bị còn vs thằng DS18b20 do nó là giao tiếp 1 dây nên ko có chân tạo clock mà chỉ có chân data do đó 2 thiết bị phải tự đồng bộ vs nhau về clock thế nên trong chương trình của bạn lúc nó đang giao tiếp vs DS18b20 nhưng có ngắt nó sẽ nhảy đến ngắt gây ra gián đoạn việc giao tiếp DS18b20 và sai giá trị đọc đc.
      để kết quả chính xác cần cho hàm đọc nhiệt độ vào ngắt và ưu tiên ngắt đó hơn các ngắt khác hoặc khi chạy hàm đó thì ko đc cho các ngắt nào hoạt động gây ra gián đoạn
      Website chính thức đổi địa chỉ website thành
      Mời các bạn ghé thăm !!!

      Comment


      • #4
        Mình sửa cái nhiệt độ thì hiển thị ok rồi. Nhưng giá trị độ ẩm toàn hiển thị số gì đâu hok, ra toàn 20k trong khi mình khai báo nó là unsigned char

        Comment


        • #5
          mình đang làm mạch hien thị nhiệt độ và độ ẩm qua led 7 doan dùng pic 16f778a ai co post len chia sẻ zí mình với thank

          Comment


          • #6
            Code:
            unsigned char humid(unsigned int tanso)
            {	
                    unsigned char k=0;
             	while(tanso<f[k])
            	{
            	 k++;
            	}
            	return(k);
            }
            Nên cho k 1 giá trị nào đó để khởi đầu, chứ đừng để random. Và theo như mình hiểu khi đọc code của bạn thì chỉ số của tần số f[] chính là % của độ ẩm do độ ẩm thường >=50% thì sao không cho k=100 sau đó giảm k thì tìm độ ẩm có phải nhanh hơn không?
            còn chỗ
            Code:
            void main()
            {
            	float Nhiet_Do;
            	unsigned char do_am;
            	unsigned char Lcd_Buff[5];
            	unsigned char Lcd_Buff1[5];
            	TMOD=0x51;
            	IE=0x82;                                           //thiet lap ngat timer 0
            	TR0=1;
            	LCD_init();    
            	LCD_clear(); 
            	LCD_home(); 
            	LCD_putstr("DO AN MON HOC 2");
            	LCDWriteCmd(0xC0);
            	LCD_putstr("DO NHIET DO & DO AM");
            	LCDWriteCmd(0x94);
            	LCD_putstr("NHIET DO:");
            	LCDWriteCmd(0xD4);
            	LCD_putstr("DO AM:");
            	delay_ms(50);
            	while(1)
            		{
            		
            			Nhiet_Do = ReadTemp();		
            			//sprintf(Lcd_Buff,"NHIET DO: %2.0f oC",Nhiet_Do);
            			sprintf(Lcd_Buff,"%.0f",Nhiet_Do);
            			LCDWriteCmd(0x9D);
            			LCD_putstr(Lcd_Buff);
            			delay_ms(300);
            
            			//do_am=humid();
            			//sprintf(Lcd_Buff,"DO AM: %2.0d",vitrf);
            			do_am=humid();
            			sprintf(Lcd_Buff1,"%d",do_am);
            			LCDWriteCmd(0xDC);
            			LCD_putstr(Lcd_Buff1);
            			delay_ms(300);
            		}
            }
            Chỗ tô đỏ sao không có tham số đầu vào?
            Mình chưa được tiếp xúc với mấy cái này bao giờ, bạn chuyển cho mình tài liệu mô tả về các linh kiện bạn dùng, nếu có thư viện kèm theo thì tốt rảnh thì mình làm cùng bạn vì dù sao mình cũng muốn thử làm việc với mấy linh kiện này

            Comment

            Về tác giả

            Collapse

            spk_lionking Tìm hiểu thêm về spk_lionking

            Bài viết mới nhất

            Collapse

            Đang tải...
            X