<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        AVR單片機溫度計

        作者:未知   來源:不詳   點擊數:  更新時間:2014年06月28日   【字體:

         自帶吐槽功能。

         
         
         
        估計每年都會有好多苦逼畢業設計是做這個吧,送上源代碼:
         
         
         
        #include
        #include
        #include <1602.h>
        #include
         
        unsigned char i;
        int temp;
         
        void timer0_init()
        {
         DDRD|=0x30;       //PortD=00110000,OC1B(PortD4)引腳輸出
         TCCR1A|=0x63;            //01(匹配時電平取反)10(匹配時清零,TOP時置位)0011(15模式)
         TCCR1B|=0x1A;     //00011(15模式) 010(8分頻)
         OCR1A=2499;     //TOP值(OCR1A):1MHZ/目標50HZ/8分頻-1=2499
         OCR1B=63;     //匹配值:占空比20%,則=TOP值*0.2    舵機:2.5% ~ 12.5% : 63~300
        }
         
        void SetMotor(int tmp)
        {
         int i;
         int start=130;
         int end=300;    //該模塊只響應 -5 ~ 45 攝氏度的范圍 63
         tmp=tmp+5-2;     //變成0~50度范圍,偏移2度
         i=(end-start)/50;   //求出1攝氏度等于舵機轉多少角度
              
         if(tmp>48)     //輸出改變舵機角度
         {  OCR1B=start;  }
         else if(tmp<-2)
         {  OCR1B=end;  }
         else
         {  OCR1B=end-i*tmp; }
          
         
         
         
        int main(void)  
        {    
          lcd_init();                         //lcd初始化           
          lcd_dictate(1);                         //清屏,光標回位  
         timer0_init();
         
         lcd_gotoxy(0,0);
         lcd_putsf("Checking Sensor",15);  //溫度傳感器檢測
            gettemperature(); 
         SetMotor(0);
         _delay_ms(500);_delay_ms(500);
         SetMotor(52);
         _delay_ms(500);_delay_ms(500);
         lcd_dictate(1); 
         
         
         
          while(1)   
          { 
          lcd_gotoxy(0,0);
          lcd_putsf("Temperature:",12);
          lcd_gotoxy(15,0);
          lcd_putsf("C",1);
                temp=gettemperature();
          if(negative) {lcd_gotoxy(12,0);lcd_putsf("-",1);}
         
           lcd_gotoxy(13,0);
          lcd_byte(integer);
          
          if(integer>=35&&!negative) {lcd_gotoxy(0,1);lcd_putsf("Tips:Go Naked...",16);}
          else if(integer>=29&&!negative) {lcd_gotoxy(0,1);lcd_putsf("Tips:Buy Aircon!",16);}
          else if(integer>=20&&!negative) {lcd_gotoxy(0,1);lcd_putsf("Tips:Go Travel!!",16);}
          else if(integer>=10&&!negative) {lcd_gotoxy(0,1);lcd_putsf("Tips:Let's BBQ!",15);}
          else{lcd_gotoxy(0,1);lcd_putsf("Tips:Hibernate..",16);}
         
          SetMotor(temp);
             }  
        }   
         
         
         
        =================分割線==================
         
        #ifndef _1602lcd_INCLUDED_             //如果原來沒有宏定義本名字就...
        #define _1602lcd_INCLUDED_             //定義一下,防止多次被頭文件包含
        #include                 //本例使用7線連接(也可以使用6線,但是沒有讀"忙"功能,不推薦)
         
        //寫LCD,  datas是數據,高4位有效,rs決定datas是顯示還是指令,read_lcd決定是否需要讀取忙標志BF
        void lcd_h(unsigned char datas,unsigned char rs,unsigned char read_lcd)
        {  
          DDRA=0xFF;                    //RS/RW/E設置為輸出
         
         if(read_lcd)
            {       
               DDRB=0x00;              //先把4個數據口設置為輸入
          PORTA&=~(1<<0);    //RS=0;
               PORTA|=(1<<1);          //RW=1 讀BF
               PORTA|=(1<<2);    //E=1
               _delay_ms(10);          //等待,直到DB7=0,這里不等了 
            }
         if(rs==1)     //RS=rs,寫指令或者數據
         {
          PORTA|=(1<<0);
         }else{
          PORTA&=~(1<<0);
         }
         PORTA&=~(1<<1);    //RW=0,寫
         DDRB=0xFF;               //把4個數據口設置為輸出
         
           PORTA|=(1<<2);     //E=1
           if(datas&128) PORTB|=(1<<3); else PORTB&=~(1<<3);
           if(datas&64)  PORTB|=(1<<2); else PORTB&=~(1<<2);
           if(datas&32)  PORTB|=(1<<1); else PORTB&=~(1<<1);
           if(datas&16)  PORTB|=(1<<0); else PORTB&=~(1<<0);
           PORTA&=~(1<<2);    //E=0;LCD在E下降沿時對RS與DB4-DB7進行取樣
         
        void lcd_dictate(unsigned char data)  //寫指令函數
          lcd_h(data,0,1);                    //輸出高4位 
          lcd_h(data*16,0,1);                 //輸出低4位
         
        void lcd_putchar(unsigned char data)  //寫顯示函數
        {  
          lcd_h(data,1,1);                    //輸出高4位 
          lcd_h(data*16,1,1);                 //輸出低4位
         
        //初始化函數
        void lcd_init(void)
        {   
          _delay_ms(40);
          lcd_h(48,0,0); _delay_ms(12);         //這3條是初始化語句
          lcd_h(48,0,0); _delay_ms(10); 
          lcd_h(48,0,0);              
          lcd_h(32,0,1);                      //使能4位數據線
          lcd_dictate(40);                    //顯示參數設定
          lcd_dictate(12);                    //顯示參數設定
        }  
          
        //列/行定位函數,最開頭的地址是0列0行
        void lcd_gotoxy(unsigned char x, unsigned char y)  //列/行定位函數
        {      
          if(x<=19 && y<=3)                    //防止輸入的數據不正確
            {                                
              if(y==0) lcd_dictate(x+128);     //第0行的地址是從128開始
              if(y==1) lcd_dictate(x+192);     //第1行......
              if(y==2) lcd_dictate(x+148);
              if(y==3) lcd_dictate(x+212);
            }
        }     
         
        void lcd_hex(unsigned char byte_data)                //以十六進制顯示一個字節變量
        {
          unsigned char data; 
          
          data=byte_data>>4;                             //求高4位
          if(data<10) data+=48; else data+=55;    //轉化為ASCII值
          lcd_putchar(data);                             //顯示
          
          data=byte_data&15;                             //求低4位
          if(data<10) data+=48; else data+=55;    //轉化為ASCII值
          lcd_putchar(data);                             //顯示
        }  
         
        void lcd_byte(unsigned char byte_data)                //以十進制顯示一個字節變量
        {
          unsigned char data; 
          
          data=byte_data/100;                            //求百位數
          lcd_putchar(data+48);                          //轉化為ASCII值再顯示
          
          data=byte_data/10;                          //求十位數
          lcd_putchar(data+48);                          //轉化為ASCII值再顯示
          
          data=byte_data;                             //求個位數
          lcd_putchar(data+48);                          //轉化為ASCII再再顯示
        }  
         
        void lcd_putsf(flash unsigned char *string , unsigned char n) //顯示FLASH里面的字符串
        {        
          unsigned char i=0;
          while(i
               {  
                 lcd_putchar( string[ i ] ) ;                 //順序顯示字符
                 i++;                         
               }
        }
        #endif
         
        =================分割線==================
         
        //monobus.h文件,用于操作DS18B20/DS2401等單總線器件,本單片機頻率有點快,//delay_us(480)代表延時480微妙,實際要用2條指令達到480us,其他單片機延時準確的話可以用一條
         
        #define monobus_1  DDRC&=~(1<<1)     //設置單片機IO為輸入,由于總線存在上拉電阻,所以此時電平是1
        #define monobus_0  DDRC|=(1<<1)     //設置單片機IO為輸出,配合默認的 PORTC.0=0 則輸出0電平
        #define monobus_in PINC&(1<<1)       //檢測總線(從機)的電平狀態
        #include
         
        unsigned char negative,integer;    //求出溫度的符號,整數部分
         
         
        void monobus_init(void)          //復位,不檢測從機設備是否存在(只要沒有虛焊就肯定存在的) 
        {
           monobus_0;
           //delay_us(480);
           _delay_us(480);
           _delay_us(480);
           monobus_1;  
         while(monobus_in);
         while(!monobus_in);
           //delay_us(480);
           _delay_us(480);
           _delay_us(480);
         
        }
         
        void write_monobus(unsigned char data)     //向單總線的從機寫入數據(先寫低位再寫高位,與SPI相反)
           unsigned char n=1; 
           while(n)
           {
             monobus_0;
             //delay_us(2);                          //拉低總線1-3us,通知從機準備收發數據
          _delay_us(4);
             if(data&n) monobus_1; else monobus_0;   //向總線寫數據的某一位(1或者0)
             //delay_us(75);                         //等待90us,保證從機有足夠的時間進行采樣(24-210us)
          _delay_us(150);
             monobus_1;                              //釋放總線    
             //delay_us(2);                          //釋放總線時間要大于1us  
          _delay_us(3);
             n<<=1;
           }
         
        unsigned char read_monobus(void)             //讀單總線的從機數據(先傳輸低位后傳輸高位,與SPI相反)
        {
           unsigned char data_18b20=0;  
           unsigned char n=1;
           while(n)
           {
             monobus_0;
             //delay_us(2);                            //拉低總線1-3us,通知從機準備收發數據
          _delay_us(3);
             monobus_1;                               //釋放總線
             //delay_us(5);                            //從機在1-25us內會向總線輸出數據的某一位(1或者0)
          _delay_us(10);
             if(monobus_in)
           data_18b20+=n;              //讀取總線數據
             //delay_us(55);                           //等待從機釋放總線
          _delay_us(110);
             n<<=1;           //挪夠8位則等于清零
           } 
           return data_18b20;
        }
         
        int gettemperature(void)
        {
         unsigned char data_L,data_H;
         int  data_T;
         float data_D;
          monobus_init();                 //單總線復位
          write_monobus(0xCC);            //跳過ID碼匹配,適用于一個DS18B20     
            write_monobus(0x44);            //啟動溫度轉換
                 
          _delay_ms(500);                 //等待轉換
         _delay_ms(500);
         
            monobus_init();                 //單總線復位
            write_monobus(0xCC);            //跳過ID碼匹配
           write_monobus(0xBE);            //通知DS18B20,準備讀數據
         
           data_L=read_monobus();          //讀取第一個數據(溫度低字節)
           data_H=read_monobus();          //讀取第二個數據(溫度高字節)
                           //可以繼續讀取第三個到第九個RAM數據
            //data_T=data_H*256+data_L;       //合并后得到原始溫度數據
           
         if(data_H>15) negative=1;     //data_H的4到7位為正負符,例如溫度為負時是1111 1xxx,為正是0000 0xxx
                    //data_L的8位和data_H的前3位共同表達溫度,可以表達-55 ~ 125,
         if(!negative)        //為正溫度   //負數用補碼表達, 反回來
         {
          data_T=data_H*256+data_L;
          data_T/=16;
         } else {
          data_T=~data_H;
          data_T<<=8;
          data_T=data_T|~data_L;
          data_T=data_T+1;
          data_D=data_T*0.0625;
          data_T=data_D*10+0.5;
         }
         integer=data_T;
         
         return data_T;        //沒要求則返回整數部分
        }
         
         
         
        =================分割線==================
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮