精品国产一区在线_av无码中文字幕无码王_天海翼三点刺激高潮不停_好硬好大好爽视频_欧美高清一区三区在线专区_香蕉黄色片

  • 回復
  • 收藏
  • 點贊
  • 分享
  • 發新帖

花一個星期搞定C語言到51,PIC單片機基礎程序,分享下自己寫的1602LCD驅動以及18B20的驅動程序

花了1周時間從零基礎搞定C語言基礎,再通過51單片機程序仿真--PIC開發板實物操作,以下是本人學習過程中編寫的一個源程序

以下源程序是基于MPLAB IDE 8.73開發平臺,編譯器是PICC。

其它編譯器大同小異,

這是一個1602LCD的驅動顯示程序和DS18B20的驅動,此源程序實用性不大,只是給初學者一個參考,

溫度顯示范圍從-55度-+125度,精確到0.1度。單片機為PIC16F877A,晶振16MHZ

RK000102

RK000111

RK000112

RK000108

對于初學者來說,自己學會編寫一個驅動程序,也是一件快樂的事情。

********************************************************************************************************

#include               //調用PIC16F87XA單片機的頭文件

__CONFIG(HS&WDTDIS&LVPDIS);


//////////////////////////////////////////////////////////////

/****************LCD1602液晶顯示相關函數*********************/

//////////////////////////////////////////////////////////////

//1602液晶相關I/O設置

#define E RB3                   //1602液晶的E腳接在RB3口上

#define RW RB4                //1602液晶的RW腳接在RB4口上

#define RS RB5                 //1602液晶的RS腳接在RB5口上

//////////////////////////////////////////////////////////////

/****************DS18B20溫度檢測相關函數*********************/

//////////////////////////////////////////////////////////////

unsigned char temp1=0;         //正負溫度判斷變量,temp1為1時表示負溫,為0時標識正溫

float temp=125.0;                 //溫度變量,默認125度

/***********************短延時函數***************************/

/*16MHZ晶振下,FOSE/4分頻,單個周期是0.25US*/

/*延時時間為:(10個固定周期2.5US)+(次數*【1.5US(5+1個周期)】=總延時時間)*/

void Delay(unsigned char t)            //跳入這個循環需要3個指令周期

{                                                //跳出這個循環需要3個指令周期

     while(t>0)                              //while第一次判斷語句要消耗3個指令周期,之后需要5個

         t--;                                     //t=t-1,消耗1個指令周期

}                                                //也就是說t=0時需要10個指令周期

/***********************長延時函數***************************/

/*a=6,c=72時是1MS延時*/

void Time(unsigned int a)              //跳入這個循環需要3個指令周期

{                                               //跳出這個循環需要3個指令周期

     unsigned int b,c;                    //定義int型變量需要2個周期,這里有2個所以需要4個周期

     asm("NOP");

     asm("NOP");

     for(b=0;a>b;b++)                  //第一次需要10個指令周期,之后需要11個指令周期

                                                //定義int型變量需要2個指令周期,判斷需要9個指令周期,++操作需要1個指令周期

     for(c=72;c>0;c--) ;                //定義int需要2個指令周期,判斷需要7個指令周期,--操作需要1個指令周期(C=85,a=1是200US)

}                                              //--循環體內部需要2+8*N+N個指令周期,也就是0.5US+(2US*N)+(0.25US*N)+NPLL(0.25US)

//////////////////////////////////////////////////////////////

/****************LCD1602液晶顯示相關函數*********************/

//////////////////////////////////////////////////////////////

/*******************LCD1602忙檢測函數************************/

void LCD1602_busy(void)

{

     TRISD7=1;                                     //將RD7口設置為輸入口,為讀做準備

     RS=0;                                            //RS=0、RW=1、E=1時,忙信號輸出到DB7,由RD7讀入

     RW=1;                                           //RS=0、RW=1、E=1時,忙信號輸出到DB7,由RD7讀入

     E=1;                                              //RS=0、RW=1、E=1時,忙信號輸出到DB7,由RD7讀入

     while(RD7==1);                              //由RD7讀入1,表示1602液晶忙,需要等待

     E=0;                                             //讀完以后,恢復E的電平

     TRISD7=0;                                    //將RD7口設置為輸出口

}

/************LCD1602寫指令函數(不帶忙檢測)*****************/

void LCD1602_Write_com(unsigned char combuf)

{

    RS=0;                                               //選擇指令寄存器

    RW=0;                                              //選擇寫狀態

    PORTD=combuf;                                //將命令字通過RD口送至DB

    E=1;                                                //E高電平將命令字寫入1602液晶

    Delay(0);                                          //添加一個空操作,使高電平至少維持1us

    E=0;                                                //寫完以后,恢復E的電平

}

/*************LCD1602寫指令函數(帶忙檢測)******************/

void LCD1602_Write_com_busy(unsigned char combuf)

{

    LCD1602_busy();                             //調用忙檢測函數

    LCD1602_Write_com(combuf);          //調用忙檢測函數

}

/*************LCD1602寫數據函數(帶忙檢測)******************/

void LCD1602_Write_data_busy(unsigned char databuf)

{      

    LCD1602_busy();                           //調用忙檢測函數     

    RS=1;                                          //選擇數據寄存器     

    RW=0;                                        //選擇寫狀態     

    PORTD=databuf;                          //將命令字通過RD口送至DB     

    E=1;                                          //E高電平將命令字寫入1602液晶     

    Delay(0);                                    //添加一個空操作,使高電平至少維持1us     

    E=0;                                          //寫完以后,恢復E的電平

/*****************LCD1602操作指定地址函數********************/

void LCD1602_Write_address(unsigned char x,unsigned char y)

     x&=0x0f;                                                             //列地址限制在0-15間

     y&=0x01;                                                            //行地址限制在0-1間

     if(y==0)                                                              //如果是第一行

         LCD1602_Write_com_busy(x|0x80);                   //將列地址寫入

     else                                                                    //如果是第二行

         LCD1602_Write_com_busy((x+0x40)|0x80);        //將列地址寫入

}

 /**********************LCD1602初始化*************************/

void LCD1602_init(void)

{

      Time(6);                                              //延時1MS

      LCD1602_Write_com(0x38);                   //8位數據總線,兩行顯示模式,5*7點陣顯示

     Time(1);                                               //延時約167US

     LCD1602_Write_com(0x38);                    //8位數據總線,兩行顯示模式,5*7點陣顯示

     Time(1);                                               //延時約167US

     LCD1602_Write_com(0x38);                   //8位數據總線,兩行顯示模式,5*7點陣顯示

     LCD1602_Write_com_busy(0x38);           //8位數據總線,兩行顯示模式,5*7點陣顯示

     LCD1602_Write_com_busy(0x08);           //顯示功能關,無光標 

     LCD1602_Write_com_busy(0x01);           //清屏

     LCD1602_Write_com_busy(0x06);           //寫入新的數據后,光標右移,顯示屏不移動

     LCD1602_Write_com_busy(0x0C);           //顯示功能開,無光標

}

 /***************LCD1602顯示指定地址內容函數******************/

void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)

{

      LCD1602_Write_address(x,y);               //先將地址信息寫入

      LCD1602_Write_data_busy(buf);           //再寫入要顯示的數據

}

/*********************LCD固定內容顯示函數********************/

void Fixed_display(void)

{

    LCD1602_Disp(2,0,'D');

    LCD1602_Disp(3,0,'S');

    LCD1602_Disp(4,0,'1');

    LCD1602_Disp(5,0,'8');

    LCD1602_Disp(6,0,'B');

    LCD1602_Disp(7,0,'2');

    LCD1602_Disp(8,0,'0');

    LCD1602_Disp(2,1,'T');

    LCD1602_Disp(3,1,'e');

    LCD1602_Disp(4,1,'m');

    LCD1602_Disp(5,1,'p');

    LCD1602_Disp(6,1,':');

    LCD1602_Disp(11,1,'.');

    LCD1602_Disp(13,1,0xdf);

    LCD1602_Disp(14,1,'C');              //0x43

}

/*********************LCD動態內容顯示函數********************/

void Dynamic_Display(void)

{

     unsigned char a=0,b=0,c=0,d=0;

     if(temp1==1)                                     //限制負溫溫度不低于零下55度

     {

           if(temp>55.0) temp=55.0;

     }

     else if(temp>125.0) temp=125.0;        //限制正溫溫度不高于125度

     d=(unsigned char)temp/100;               //提取溫度百位數值

     c=(unsigned char)temp%100/10;         //提取溫度十位數值

     b=(unsigned char)temp%10;               //提取溫度個位數值

     a=(unsigned char)(temp*10)%10;       //提取溫度小數數值

     if(d==0)                                           //判斷百位顯示是否為0

     {

           if(temp1==1)                             //如果溫度為零下攝氏度時

           {

                 if(c==0)                              //又如果溫度不低于零下十度時

                 {

                     c='-'-0x30;                      //十位顯示“-”負號

                     d='_';                             //百位顯示“_”空格

                 }

                else d='-'-0x30;                     //百位顯示“-”負號

           }

           else                                         //否則溫度為正常攝氏度

           {

                d='_';                                 //百位顯示“_”空格

                if(c==0)  c='_';                    //又如果十位為零時,十位顯示“_”空格

           }

     }

     if(a>9) a=9;

     LCD1602_Disp(8,1,d+0x30);               //顯示溫度百位數值

     LCD1602_Disp(9,1,c+0x30);               //顯示溫度十位數值

     LCD1602_Disp(10,1,b+0x30);             //顯示溫度個位數值

     LCD1602_Disp(12,1,a+0x30);             //顯示溫度小數數值

}

//////////////////////////////////////////////////////////////

/****************DS18B20溫度檢測相關函數*********************/

//////////////////////////////////////////////////////////////

/******************DS18B20上電復位函數***********************/

unsigned char Reset(void)

{

   unsigned char i;

   TRISA4=0;                                      //設置RA4位輸出口

   RA4=0;                                           //拉低DQ總線開始復位

   Delay(200);                                     //設定602.5US,DS18B20規定RESET復位時間不低于480US,不大于960US

                                                        //定時180-240之間

   TRISA4=1;                                      //設置RA4為輸入口,以釋放總線等電阻拉高總線

   Delay(20);                                       //設定62.5US,DS18B20規定等待間隔時間為60-240US

                                                        //定時20-60之間

   if(RA4==0)                                     //讀出數據并保存

   i=0;

   else i=1;

   Delay(200);                                    //維持約449.5US,符合總讀時隙不低于480US的要求

   return i;                                         //k=0為復位成功,k=1為復位失敗

}

/*******************DS18B20寫字節函數************************/

void WriteByte(unsigned char dat)

{

    unsigned char i;

    for(i=0;i<8;i++)

    {

        TRISA4=0;                                //設置RA4位輸出口

        if(dat&0x01)                              //如果寫1

        {

            RA4=0;                                  //拉低總線電平

            Delay(1);                                //維持約4US,符合大于1US小于15US的規范

            TRISA4=1;                             //設置RA4為輸入口,以釋放總線等電阻拉高總線

            Delay(39);                              //維持約61US,符合不低于60US的要求

        }

        else                                          //如果寫0

        {

             TRISA4=0;                           //設置RA4位輸出口

              RA4=0;                               //拉低

              Delay(39);                           //維持約61US,符合不低于60US的要求

              TRISA4=1;                          //設置RA4為輸入口,以釋放總線等電阻拉高總線

              Delay(0);                            //維持約2.5US,符合大于1US規范

         }

        dat=dat>>1;                            //寫入字節右移1位

    }

}

/*******************DS18B20讀字節函數************************/

unsigned char ReadByte(void)

{

    unsigned char i,buf=0;

    for(i=1;i<=8;i++)                          //接收8次還原一個字節數據

    {

        buf=buf>>1;                           //接收前,先將接收緩沖區右移

        TRISA4=0;                              //設置RA4位輸出口

        RA4=0;                                   //拉低

        Delay(2);                                 //維持7US,符合大于1US小于15US的規范

        TRISA4=1;                              //設置RA4為輸入口,以釋放總線等電阻拉高總線 準備讀

        Delay(2);                                 //維持約7US,符合大于1US小于15US的規范

        if(RA4==1) buf|=0x80;             //讀出1位數據保存于buf中最高位

        Delay(33);                               //維持約52US,符合總讀時隙不低于60US的要求

    }

    return buf;                                  //退出的同時將接收緩沖區參數返回

}

/******************DS18B20啟動轉換函數***********************/

unsigned char Convert(void)

 {

     if(Reset()==0)                             //如果復位成功

     {  Time(3); //延時0.5MS

         WriteByte(0xcc);                     // 跳過多器件識別

         WriteByte(0x44);                     // 啟動溫度轉換

         return 1;

     }

     else

     {

        return 0;

     }

}

 /******************DS18B20讀溫度函數*************************/

void ReadFlash(void) 

{

    unsigned int i;

    unsigned char Lsb,Msb;

    if(Reset()==0)

     { 

         Time(3);                                  //延時0.5MS

         WriteByte(0xcc);                       // 跳過多器件識別

         WriteByte(0xbe);                      // 讀暫存器

         Lsb=ReadByte();                       // 低字節

         Msb=ReadByte();                      // 高字節

         i=Msb;

         i<<=8;

         i=i|Lsb;

         if(Msb>0x07)                            //如果判斷溫度為零下攝氏度時

         {

             temp1=1;                            //把零下標識符temp1置1

             i=(~i)+1;                             //讀取溫度取反加1

             temp=(float)i*0.0625;           //轉換為真實溫度并把結果轉換成浮點數

         }

         else

        {

            temp1=0;

            temp=(float)i*0.0625;           //轉換為真實溫度并把結果轉換成浮點數

        }

    }

    else                                            //那么沒有采集到溫度就把初始溫度設置為125度

    {

        temp=125.0;

    }

}

 /*************************主函數*****************************/

void main(void)

{

    TRISA=0xff;                                 //初始化RA5-RA0的輸入輸出方向

    PORTA=0x00;                              //初始化RA5-RA0數值

    TRISB=0xc7;                                //初始化對RB口的初始方向進行設置 設置為輸出

    TRISD=0x00;                               //初始化RD口的初始方向進行設置,設置為輸出

    PORTB=0x00;                              //初始化RB口的數值

    PORTD=0x00;                              //初始化RD口的數值

    Time(6);                                     //延時1MS秒,做內容切換顯示

    LCD1602_init();                            //初始化

    LCD1602Fixed_display();                //LCD固定內容顯示

/**************************死循環****************************/

    while(1)                                       //死循環,單片機初始化后,將一直運行這個死循環

    {

        if(Convert()==1)                      //啟動轉換

        {

              ReadFlash();                      //讀取溫度

              Dynamic_Display();             //讀取內容顯示

        }

    }

}

********************************************************************************************************





全部回復(8)
正序查看
倒序查看
2014-04-14 13:56

好帖子,應該分享給更多人!

0
回復
2014-04-14 14:19
@電源網-娜娜姐
好帖子,應該分享給更多人!
其實可以在詳細點,這樣有助于新人學習!
0
回復
shenx123
LV.10
4
2014-04-24 14:07

羨慕那些搞出實驗的人啊

給點意見 吧    http://www.cubesun.cn/bbs/1484642.html

0
回復
eason
LV.4
5
2014-04-24 14:53
@yueyunno1
其實可以在詳細點,這樣有助于新人學習!
同意,希望樓主能繼續,最近學習的帖子比較多,感謝這些大咔們。
0
回復
qinzhuai
LV.3
6
2014-04-25 13:31
請教下,怎樣能很快的看懂程序?
0
回復
345295362
LV.6
7
2014-04-25 19:05
@qinzhuai
請教下,怎樣能很快的看懂程序?
看懂C語言,再去了解PIC單片機指令。
0
回復
2014-04-27 00:09
@345295362
看懂C語言,再去了解PIC單片機指令。
1周時間從零基礎搞定C語言基礎,再通過51單片機程序仿真--PIC開發板實物操作。。速度算是很快了
0
回復
2014-04-27 20:33
@山東大漢
1周時間從零基礎搞定C語言基礎,再通過51單片機程序仿真--PIC開發板實物操作。。速度算是很快了

走馬看花估計可以,細節的地方得好好看看!

0
回復
主站蜘蛛池模板: 超黄视频免费看 | 国产精品边做奶水狂喷无码 | 国产中老年妇女精品 | jojo的奇妙冒险星尘斗士埃及篇免费观看 | 精品国产一区二区三区久久久狼 | 国产精选网站 | 成人小视频网 | 香蕉久久夜色精品国产尤物 | 新狠狠干 | 亚洲成人午夜影院 | 欧美一及黄色片 | 2021国产精品无码专区 | 九色蝌蚪少妇 | 日韩欧美五区 | 欧美成人做爰高潮片免费观看8850 | 中文字幕乱码亚洲无线码三区 | 久久久99日产 | 国产成人精品自产拍在线观看 | 娇妻被别人玩弄至高潮视频 | 国产一级免费在线视频 | 亚洲观看在线 | 九九久久影视 | 文豪野犬第四季在线观看樱花动漫 | 青青久热 | 99精品在线免费 | 99精品中文字幕 | 黄色A级国产免费大片 | 久草最新网址 | 中文字幕一综合88久久 | 中文字幕人妻无码视频 | 日本XXXX色视频在线播放 | 免费看污污的视频 | 4399午夜理伦免费播放大全 | 日韩精品亚洲Aⅴ在线影院 天天看片视频免费观看 | 国产一区二区影院 | 四川老熟妇乱子XX性BBW | 国内精品女同女同一区二区三区 | 三级小视频在线观看 | 国产欧美日韩精品丝袜高跟鞋 | 色欲AV综合AV无码AⅤ | 137肉体裸交XXXXX摄影 |