久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標(biāo)題: 單片機原理及應(yīng)用 實驗報告 [打印本頁]

作者: Trauma    時間: 2018-4-21 13:40
標(biāo)題: 單片機原理及應(yīng)用 實驗報告
單片機原理及應(yīng)用實驗報告


引言
單片機是一種控制芯片,一個微型的計算機,而加上晶振,存儲器,地址鎖存器,邏輯門,七段譯碼器(顯示器),按鈕(類似鍵盤),擴展芯片,接口等那是單片機系統(tǒng)。80C51單片機有40個引腳大致可分為4類:電源、時鐘、控制和I/O引腳。1. 電源:⑴ VCC-芯片電源,接+5V;⑵ VSS-接地端;⒉ 時鐘:XTAL1、XTAL2-晶體振蕩電路反相輸入端和輸出端。⒊ 控制線:控制線共有4根,⑴ ALE/PROG:地址鎖存允許/片內(nèi)EPROM編程脈沖 ① ALE功能:用來鎖存P0口送出的低8位地址 ② PROG功能:片內(nèi)有EPROM的芯片,在EPROM編程期間,此引腳輸入編程脈沖。⑵ PSEN:外ROM讀選通信號。⑶ RST/VPD:復(fù)位/備用電源。① RST(Reset)功能:復(fù)位信號輸入端。② VPD功能:在Vcc掉電情況下,接備用電源。 ⑷ EA/Vpp:內(nèi)外ROM選擇/片內(nèi)EPROM編程電源。① EA功能:內(nèi)外ROM選擇端。② Vpp功能:片內(nèi)有EPROM的芯片,在EPROM編程期間,施加編程電源Vpp。⒋ I/O線80C51共有4個8位并行I/O端口:P0、P1、P2、P3口,共32個引腳。P3口還具有第二功能,用于特殊信號輸入輸出和控制信號(屬控制總線)。80C51的存儲器組織結(jié)構(gòu)可以分為三個不同的存儲空間,分別是:⑴ 64KB程序存儲器(ROM),包括片內(nèi)ROM和片外ROM;⑵ 64KB外部數(shù)據(jù)存儲器(外RAM);⑶ 256B內(nèi)部數(shù)據(jù)存儲器(內(nèi)RAM)(包括特殊功能寄存器)。


目錄
一、 KEIL 和PROTEUS 聯(lián)調(diào)實驗        1
二、 中斷與定時實驗        5
三、 輸入輸出實驗        13
四、 ADC/DAC        21
五、通信實驗        35
實驗總結(jié)與感想        54


一、 KEIL 和PROTEUS 聯(lián)調(diào)實驗
1.1 實驗要求
1. 采用延時方法,實現(xiàn)2kHz的方波輸出,觀察LED的現(xiàn)象。
2. 采用軟件延時方法實現(xiàn)頻率2Hz方波輸出,實現(xiàn)LED的閃爍顯示。
3. 采用LED的閃爍顯示的方法,實現(xiàn)檢測內(nèi)存單元20H中高電平“1”的個數(shù),閃爍1次表示1,閃爍2次表示2….,結(jié)束關(guān)顯示2秒。循環(huán)進行。
4. 采用LED1的閃爍顯示的表示“1”,LED2的閃爍表示“0”的方法,實現(xiàn)檢測內(nèi)存單元20H中的數(shù)據(jù)大小,從高位開始,結(jié)束關(guān)顯示2秒。循環(huán)進行。
5. P2口驅(qū)動8個LED,設(shè)計流水燈程序,實現(xiàn)每0.5s移位顯示。
1.2程序?qū)崿F(xiàn)
1)
圖1.1
在圖1.1中,經(jīng)過一定的時鐘周期(晶振為12MHZ),根據(jù)一個機器周期為1us來計算延遲時間,達到延時時間信號取反,在Proteus中仿真得到如下波形:
2)  
圖1.2
在圖1.2中,經(jīng)過一定的時鐘周期(晶振為12MHZ),根據(jù)一個機器周期為1us來計算延遲時間,達到延時時間信號取反,在Proteus中仿真得到如下波形:
3)  
每個單元存儲的數(shù)據(jù)為8位,將數(shù)據(jù)0FEH存入A后進行移位操作,通過一定的時間間隔,實現(xiàn)8個LED依次循環(huán)點亮,從而實現(xiàn)流水燈的設(shè)計;仿真結(jié)果如下:
1.3實驗總結(jié)
51單片機是基礎(chǔ)的開發(fā)工具,這節(jié)課我們主要實現(xiàn)了兩個軟件的聯(lián)調(diào)以及匯編語言的編寫,匯編是基礎(chǔ)的機器語言一開始的編程不是很順利一遍一遍的試,尤其的延遲程序雖然有單字節(jié)指令、多字節(jié)指令,根據(jù)機器周期一個一個進行計算確定延遲時間,總是有那么一點誤差。軟件的聯(lián)調(diào)也在實驗過程中實現(xiàn)了,查找自己代碼上的錯誤以及指導(dǎo)計算機是如何運行我們所編寫的程序,讓我的編程能力得到了一定提升,也更加了解熟悉計算機,要繼續(xù)努力不斷深入下去,加油。

二、 中斷與定時實驗
2.1 實驗要求
1. 第1次按鍵LED亮,第2次按鍵燈滅,用中斷方式實現(xiàn);
2. P2.0輸出2kHz的方波,用中斷方式實現(xiàn);
3. P2.0輸出1kHz占空比25%的方波,用中斷方式實現(xiàn);
4. 按鍵中斷交替實現(xiàn),P2.0輸出2kHz與500Hz的方波,用中斷方式實現(xiàn);
5. 在1-2s時間內(nèi)按鍵1次P2.0發(fā)出1kHz方波,在1-2s時間內(nèi)按鍵連2次,P2.0發(fā)出2kHz的方波。在1-2s內(nèi)連擊按鍵3次,P2.0發(fā)出500Hz        的占空比25%的方波。
2.2 程序?qū)崿F(xiàn)
1)
圖2.1
在圖2.1中,設(shè)定一個外部中斷0,實時監(jiān)聽P2.0口,一旦檢測到按鍵按下,參數(shù)A取反,對應(yīng)輸出相應(yīng)的高低電平。一開始燈不亮,當(dāng)按鍵按下時燈亮,再按一下燈又熄滅。。。。。。如此反復(fù)。在Proteus上仿真得到如下情況:
圖2.2
2)
圖2.3
在圖2.3中,根據(jù)一定的時鐘周期(晶振為12MHZ),利用定時器1來進行定時,定時器1每間隔0.25ms對P2_0取反一次,如此循環(huán)得到頻率為2kHz的方波,在Proteus上仿真得到如下情況:
圖2.4
3)
圖2.5
在圖2.5中,要獲得一個1kHz、占空比為25%的方波,只要在0.25ms時電平置低,之后再經(jīng)過0.75ms,電平再拉高,由此實現(xiàn)1kHz、占空比25%方波的輸出,在Proteus上仿真得到如下情況:
4)
圖2.7
在圖2.7中,設(shè)定一個外部中斷0,實時監(jiān)聽INT0口,一旦檢測到按鍵按下,參數(shù)A取反。對于參數(shù)A的不同取值,通過定時器1分別輸出2kHz與500Hz。在Proteus上仿真得到如下情況:
圖2.8
5)
圖2.9
在圖2.9中,通過中斷函數(shù)ext0(),在一定時間內(nèi)按鍵按下幾次,參數(shù)A取相應(yīng)的值。再通過定時器1,通過判斷參數(shù)A的取值,P2.0口輸出相應(yīng)的方波。當(dāng)按鍵次數(shù)A=1時實現(xiàn)P2.0口輸出1kHz方波,當(dāng)按鍵次數(shù)A=2時實現(xiàn)P2.0口輸出2kHz方波,當(dāng)按鍵次數(shù)A=3時實現(xiàn)P2.0口輸出500Hz占空比25%的方波。編譯無誤后進行Proteus仿真:
圖2.10 P2.0口輸出1kHz方波
圖2.11 P2.0口輸出2kHz方波
圖2.12 P2.0口輸出500Hz占空比25%的方波
在圖2.10、2.11、2.12中,通過按鍵次數(shù)的增加,實現(xiàn)實驗所需要求的功能,順利完成實驗。
2.3實驗總結(jié)
在做實驗之前,我復(fù)習(xí)了中斷的概念,包括外部中斷、定時器中斷,了解到51單片機內(nèi)部資源豐富,能實現(xiàn)現(xiàn)階段很多想要實現(xiàn)的功能。感覺學(xué)了這次實驗的內(nèi)容,我可以動手做很多跟時間有關(guān)的小作品,在實驗課上,我對代碼進行優(yōu)化,因為一開始對定時器所給的初值與我們所需要方波的延遲周期有一定的誤差,需要不斷調(diào)試來產(chǎn)生的方波更加優(yōu)美。
三、 輸入輸出實驗
3.1實驗要求
1) 設(shè)計電路圖
由P2口控制顯示器位碼,P1口控制顯示器段碼,設(shè)計6位的LED顯示器,采用動態(tài)顯示。也可以采用靜態(tài)顯示。
用P1或P3口設(shè)計一鍵盤,可以是16個按鍵的行列按鍵,也可以是8個獨立按鍵。
2) 程序設(shè)計
1. 實現(xiàn)顯示123456
2. 時間顯示,顯示格式  XXXX.XX  (s)
3. 實現(xiàn)秒表功能,按一鍵啟動秒表,再按一次該按鍵停止計時,顯示格式 MM.SS.XX.
4. 實現(xiàn)倒計時功能,按鍵設(shè)定計時的時間,啟動按鍵計時,中間可以按鍵暫停計時,時間到后閃爍顯示屏,顯示格式 MM.SS.XX.
5. 實現(xiàn)時鐘功能,可按鍵修改初始時間,顯示格式 HH.MM.SS
要求采用按功能鍵實現(xiàn)功能2~5的切換。
3.2程序?qū)崿F(xiàn)
1) 實現(xiàn)顯示123456。
圖3.1
在圖3.1中,采用動態(tài)掃描的方式,通過函數(shù)DigDisplay()實現(xiàn)數(shù)碼管位選與段選數(shù)據(jù)對應(yīng)輸出,經(jīng)過掃描和人眼視覺殘留實現(xiàn)6個數(shù)碼管顯示123456。在Proteus中仿真得到如下顯示:
2) 按功能鍵實現(xiàn)功能2~5的切換,綜合程序。
#include<reg51.h>
#define GPIO_DIG   P1        //段選
#define GPIO_PLACE P2        //位選
#define uchar unsigned char
#define uint  unsigned int
sbit key=P3^0;
sbit t3=P3^5;
sbit t2=P3^6;
sbit t1=P3^7;
uint disnum1=0,disnum2=0,disnum3=0,K,T=0,power=0;
unsigned char code DIG_PLACE[6] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf};         //位碼
unsigned char code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段碼0~9
void display(uint liu,uint wu,uint si,uint san,uint er,uint yi);
void timing();
void delay(uint a)
{
        unsigned int i,j;
        for(j=a;j>0;j--)
                for(i=0;i<500;i++);
}
void main()
{      
    TMOD = 0X01;
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
    EA = 1;         
    ET0 = 1;      
    TR0 = 1;
        IT0=1;
        EX0=1;
        IT1=1;
        EX1=1;
        while(1)
        {
                timing();
          display(disnum3/10,disnum3%10,disnum2/10,disnum2%10,disnum1/10,disnum1%10);
        }
}
void time1() interrupt 1
{
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        if(power==0)                          //功能2
        {
                disnum1++;
                if(disnum1==100)
                {
                        disnum1=0;
                        disnum2++;
                        if(disnum2==60)
                        {
                                disnum2=0;
                                disnum3++;
                                if(disnum3==60)
                                {
                                        disnum3=0;
                                }
                        }
                }                           
        }
        if(power==1)                          //功能3
        {
                if(K!=0)
                {
                        disnum1++;
                        if(disnum1==100)
                        {
                                disnum1=0;
                                disnum2++;
                                if(disnum2==60)
                                {
                                        disnum2=0;
                                        disnum3++;
                                        if(disnum3==60)
                                        {
                                                disnum3=0;
                                        }
                                }
                        }         
                 }
         }
        if(power==2)                          //功能4
        {
                if(K!=0)
                {
                        if(disnum1==0&&(disnum3!=0||disnum2!=0))
                        {
                                disnum1=100;
                                if(disnum2==0&&disnum3!=0)
                                {
                                        disnum2=60;
                                        disnum3--;               
                                }
                                disnum2--;                       
                        }
                        else
                                if(disnum1!=0||disnum3!=0||disnum2!=0)      
                                        disnum1--;                       
                }        
        }
        if(power==3)                          //功能5
        {
                T++;
                if(T==100)
                {
                        T=0;
                    if(K!=0)
                        {
                                disnum1++;
                                if(disnum1==60)
                                {
                                        disnum1=0;
                                        disnum2++;
                                        if(disnum2==60)
                                        {
                                                disnum2=0;
                                                disnum3++;
                                                if(disnum3==60)
                                                {
                                                        disnum3=0;
                                                }
                                        }
                                }         
                        }
                }
        }
}
void  int0(void) interrupt 0   //啟動/暫停鍵
{
   K = ~K;      
}
void  int1(void) interrupt 2   //功能選擇鍵
{
    power++;
    if(power==4)
    {
                power=0;
    }      
        disnum1=0;disnum2=0;disnum3=0;K=0;T=0;
}
void display(uint liu,uint wu,uint si,uint san,uint er,uint yi)
{         
        GPIO_PLACE=~DIG_PLACE[0];
        GPIO_DIG=table[liu];
        delay(1);
        GPIO_PLACE=~DIG_PLACE[1];
        GPIO_DIG=table[wu]+0X80;
        delay(1);
        GPIO_PLACE=~DIG_PLACE[2];
        GPIO_DIG=table[si];
        delay(1);
        GPIO_PLACE=~DIG_PLACE[3];
        GPIO_DIG=table[san]+0X80;
        delay(1);
        GPIO_PLACE=~DIG_PLACE[4];
        GPIO_DIG=table[er];
        delay(1);
        GPIO_PLACE=~DIG_PLACE[5];
        GPIO_DIG=table[yi];
        delay(1);
}
void timing()
{
    if(t3==0)
        {      
                delay(40);
                if(t3==0)
                {
                        disnum3++;
                        if(disnum3==60)
                                disnum3=0;
                }
        }
    if(t2==0)
        {      
                delay(40);
                if(t2==0)
                {
                        disnum2++;
                        if(disnum2==60)
                                disnum2=0;
                }
        }
    if(t1==0)
        {      
                delay(40);
                if(t1==0)
                {
                        disnum1++;
                        if(disnum1==100)
                                disnum3=0;
                }
        }
}
根據(jù)Proteus中所設(shè)計的的電路圖,功能實現(xiàn)為:
        將8個按鍵從上到下依次命名為key1~key8.key4為功能切換鍵,每按下一次切換一個功能;key3為啟動/暫停鍵,用于秒表的啟動/暫停控制;key6、key7、key8為時間調(diào)整鍵,每按一次加一。
        功能2:通過定時器計時,每隔10ms,disnum1加一;當(dāng)disnum1加到100時,disnum1置零,disnum2加一;當(dāng)disnum2加到60時,disnum2置零,disnum3加一。運用動態(tài)掃描的方式在數(shù)碼管上依次顯示disnum3、disnum2、disnum1。
        功能3:與功能2類似,增加了K取值零與非零的判斷。通過判斷K的取值實現(xiàn)秒表的啟動/暫停功能。
        功能4:首先設(shè)定MM.SS.XX的時間,通過啟動/暫停鍵控制啟動。設(shè)定剛好與秒表功能相反。通過定時器計時,每隔10ms,disnum1減一;當(dāng)disnum1減到0時,disnum1置100,disnum2減一;當(dāng)disnum2減到0時,disnum2置60,disnum3減一。運用動態(tài)掃描的方式在數(shù)碼管上依次顯示disnum3、disnum2、disnum1。
        功能5:與秒表的功能實現(xiàn)方式相同,只是在時間上做了調(diào)整。
3.3實驗總結(jié)
此次實驗在上次中斷實驗基礎(chǔ)上進行,實現(xiàn)時鐘、秒表、倒計時等功能的實現(xiàn),在實驗的過程中遇到了一個麻煩就是實現(xiàn)倒計時時,每位之間借位時,出現(xiàn)了顯示錯誤,通過在課堂上的測試與調(diào)整,成功克服了這一問題。此次實驗學(xué)到了很多新知識,過程挺開心的,同時實驗也取得了成功。

四、 ADC/DAC
4.1實驗要求
1. 編制ADC轉(zhuǎn)換程序,將轉(zhuǎn)換的數(shù)字直接顯示在顯示器上;
2. 編制DAC轉(zhuǎn)換三角波程序,輸出頻率在10-200Hz;
3. 可按鍵設(shè)定ADC轉(zhuǎn)換程序,量程最大值限制在50-99之間,前面兩位為提示符;
4. 編制電位器調(diào)節(jié)量程程序,實現(xiàn)2路調(diào)節(jié)電位器最小到-最大,顯示25-99,前面兩位為提示符;
5. 編制程序用電位器控制三角波的輸出幅度及頻率。一路控制幅度在25-99,另一路頻率在25-99Hz。
4.2程序?qū)崿F(xiàn)
1)
#include "reg52.h"                       
#include<intrins.h>
typedef unsigned int uint;         
typedef unsigned char uchar;
sbit LSA=P2^0;
sbit LSB=P2^1;
sbit LSC=P2^2;
sbit CLK=P1^4;   
sbit ST=P1^2;  
sbit EOC=P1^1;  
sbit OE=P1^3;  
sbit ALE=P1^0;
sbit ADDA=P1^5;
uchar code table[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//顯示0~F的值
uchar ADdisplayflag=0;
uint adcount=0;
uint dpcount=0;
uint dd=0;
uchar zhuanhuanflag=0;      
void CLKInit(void)
{
        ET0 = 1;
        TR0 = 1;
        TH0 = (65536-25)/256;
        TL0 = (65536-25)%256;
}
void ScanInit(void)
{
        ET1 = 1;
        TR1 = 1;
        TH1 = 0x06;
        TL1 = 0x06;
}
void delay(uint i)
{
        while(i--);      
}
void ADdisplay()
{
        switch(ADdisplayflag)
        {
                case 0:
                {
                        P0 = 0x00;
                        LSA=1;LSB=1;LSC=0;
                }break;
                case 1:
                {
                        P0 = 0x00;
                        P0 = table[dd/100];
                        LSA=0;LSB=1;LSC=0;
                }break;
                case 2:
                {
                        P0 = 0x00;
                        P0 = table[dd%100/10];
                        LSA=1;LSB=0;LSC=0;
                }break;
                case 3:
                {
                        P0 = 0x00;
                        P0 = table[dd%10];
                        LSA=0;LSB=0;LSC=0;
                }break;
                default : break;
        }
        ADdisplayflag++;
        if(ADdisplayflag == 4)
        {
                ADdisplayflag = 0;
        }
}
void main()
{
        ADDA=0;
        EA = 1;
        TMOD = 0x21;
        ScanInit();
        CLKInit();
        while(1);
}
void CLK50us(void) interrupt 1
{
        TH0 = (65536-25)/256;
        TL0 = (65536-25)%256;
        CLK=!CLK;
}
void ScanLed(void) interrupt 3
{
        dpcount++;
        if(dpcount==4)
        {
                dpcount=0;
                ADdisplay();
        }
        adcount++;
        if(adcount==40)
        {
                adcount = 0;
                ALE=1;
                ST=1;
                ALE=0;
                ST=0;
                _nop_();
                _nop_();
                zhuanhuanflag=1;
        }
        if(zhuanhuanflag==1)
        {
                if(EOC==1)
                {               
                        OE=1;
                        dd=P3;               
                        OE=0;
                        zhuanhuanflag=0;
                }
        }
}
在程序中,題目要求需要將電壓信號轉(zhuǎn)換成數(shù)字并用數(shù)碼管顯示出來,用八位進行采集,采集到的信號轉(zhuǎn)換成數(shù)字后的范圍為0~255,之后需要用數(shù)碼管顯示,這里還是采用動態(tài)掃描顯示,顯示方式與上一次實驗一致,仿真結(jié)果如下:
2)
#include <reg52.h>
void delay(int i)
{
        while(i--);
}
void main()
{
        P0 = 0;
        while(1)
        {
                while(1)
                {
                        if(P0!=0xFF)
                        {
                                P0++;
                                delay(1);
                        }
                        else
                                break;
                }
                while(1)
                {
                        if(P0!=0x00)
                        {
                                P0--;
                                delay(1);
                        }
                        else
                                break;
                }
        }
}
P0從0依次加到255,再從255依次減到0,如此循環(huán)反復(fù)實現(xiàn)了三角波的輸出,其中三角波的頻率由延時函數(shù)delay()來控制,用protuse進行仿真得到如下的仿真波形:
3)  
#include "reg52.h"                         //此文件中定義了單片機的一些特殊功能寄存器
#include<intrins.h>
typedef unsigned int uint;          //對數(shù)據(jù)類型進行聲明定義
typedef unsigned char uchar;
sbit LSA=P2^0;
sbit LSB=P2^1;
sbit LSC=P2^2;
sbit CLK=P1^4;   
sbit ST=P1^2;  
sbit EOC=P1^1;  
sbit OE=P1^3;  
sbit ALE=P1^0;
sbit k1 = P2^3;
sbit k2 = P2^4;
sbit k3 = P2^5;
sbit k4 = P2^6;
sbit k5 = P2^7;
uchar code table[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//顯示0~F的值
uint adcount=0,dpcount=0,dd=0,ddcopy=0,dchange=0,dchangecopy=0,shanshuoflag=0;
uchar ADdisplayflag=0,zhuanhuanflag=0,k4flag=0,moduleFlag=0,lc=0,rc=0,ledchoose=0,max=0,min=0,weishu=0;               
void CLKInit(void)
{
        ET0 = 1;
        TR0 = 1;
        TH0 = 0xF0;
        TL0 = 0xF0;
}      
void ScanInit(void)
{
        ET1 = 1;
        TR1 = 1;
        TH1 = 0x06;
        TL1 = 0x06;
}      
void delay(uint i)
{
        while(i--);      
}
void ADdisplaya(uchar ledmie)
{
        switch(ADdisplayflag)
        {
                case 0:
                {
                        P0 = 0x00;
                        if(ledmie==1)
                        {
                                P0 = 0x00;
                        }
                        else P0 = table[10];
                        LSA=1;LSB=1;LSC=0;
                }break;
                case 1:
                {
                        P0 = 0x00;
                        if(ledmie==2)
                        {
                                P0 = 0x00;
                        }
                        else P0 = table[13];
                        LSA=0;LSB=1;LSC=0;
                }break;
                case 2:
                {
                        P0 = 0x00;
                        if(ledmie==3)
                        {
                                P0 = 0x00;
                        }
                        else P0 = table[dchange/10];
                        LSA=1;LSB=0;LSC=0;
                }break;
                case 3:
                {
                        P0 = 0x00;
                        if(ledmie==4)
                        {
                                P0 = 0x00;
                        }
                        else P0 = table[dchange%10];
                        LSA=0;LSB=0;LSC=0;
                }break;
                default : break;
        }
        ADdisplayflag++;
        if(ADdisplayflag == 4)
        {
                ADdisplayflag = 0;
        }
}
void ADdisplayb(uchar ledmie)
{
        switch(ADdisplayflag)
        {
                case 0:
                {
                        P0 = 0x00;
                        if(ledmie==1)
                        {
                                P0 = 0x00;
                        }
                        else P0 = table[10];
                        LSA=1;LSB=1;LSC=0;
                }break;
                case 1:
                {
                        P0 = 0x00;
                        if(ledmie==2)
                        {
                                P0 = 0x00;
                        }
                        else P0 = table[13];
                        LSA=0;LSB=1;LSC=0;
                }break;
                case 2:
                {
                        P0 = 0x00;
                        if(ledmie==3)
                        {
                                P0 = 0x00;
                        }
                        else P0 = table[dchangecopy/10];
                        LSA=1;LSB=0;LSC=0;
                }break;
                case 3:
                {
                        P0 = 0x00;
                        if(ledmie==4)
                        {
                                P0 = 0x00;
                        }
                        else P0 = table[dchangecopy%10];
                        LSA=0;LSB=0;LSC=0;
                }break;
                default : break;
        }
        ADdisplayflag++;
        if(ADdisplayflag == 4)
        {
                ADdisplayflag = 0;
        }
}      
void adc0809()
{
        ALE=1;
        ST=1;
        ALE=0;
        ST=0;
        _nop_();
        _nop_();
        while(EOC==0);
        OE=1;
        dd=P3;
        OE=0;
}
void keypress(void)
{
        if(k4==0)
        {
                delay(1000);
                if(k4==0)
                {                       
                        k4flag=~k4flag;
                        k4flag&=0x01;
                        if(k4flag==0)
                        {
                                moduleFlag = 0;
                                weishu=3;
                        }
                        else if(k4flag==1)
                        {
                                moduleFlag = 1;
                                if(dchange<50||dchange>99)
                                {
                                        dchangecopy=50;
                                }
                                else dchangecopy=dchange;
                        }
                        while(!k4);
                }
        }
        if(moduleFlag == 1)
        {
                if(k1==0)
                {
                        delay(1000);
                        if(k1==0)
                        {
                                if(ledchoose%2)
                                {
                                        weishu=3;
                                }
                                else
                                {
                                        weishu=4;
                                }
                                ledchoose++;
                        }
                        while(!k1);
                }
                if(k2==0)
                {
                        delay(1000);
                        if(k2==0)
                        {
                                if(ledchoose%2)
                                {
                                        if(dchangecopy>=50&&dchangecopy<99)
                                        {
                                                dchangecopy=dchangecopy+1;
                                        }
                                }else
                                {
                                        if(dchangecopy>=50&&dchangecopy<90)
                                        {
                                        dchangecopy=dchangecopy+10;
                                        }
                                       
                                }
                        }
                        while(!k2);
                }
                if(k3==0)
                {
                        delay(1000);
                        if(k3==0)
                        {
                                if(ledchoose%2)
                                {
                                        if(dchangecopy>50&&dchangecopy<=99)
                                        {
                                                dchangecopy=dchangecopy-1;
                                        }
                                }else
                                {
                                        if(dchangecopy>=60&&dchangecopy<=99)
                                        {
                                        dchangecopy=dchangecopy-10;
                                        }
                                       
                                }
                        }
                        while(!k3);
                }
                if(k5==0)
                {
                        delay(1000);
                        if(k5==0)
                        {
                                max=dchangecopy;
                                moduleFlag=0;
                                k4flag=0;
                        }
                        while(!k5);
                }
               
        }
}
void main()
{
        EA = 1;
        TMOD = 0x22;
        ScanInit();
        CLKInit();
        max=99;
        min=0;
        weishu=3;
        while(1)
        {
                keypress();
        }
}
void CLK500us(void) interrupt 1
{
        CLK=~CLK;
}
void ScanLed(void) interrupt 3
{
        dpcount++;
        adcount++;
        shanshuoflag++;
        if(moduleFlag==0)
        {
                if(dpcount==4)
                {
                        dpcount=0;
                        ADdisplaya(0);
                }
        }else if(moduleFlag==1)
        {
                if(dpcount>4||shanshuoflag>3000)
                {
                        dpcount=0;
                        shanshuoflag=0;
                }
                if(dpcount==4)
                {
                        dpcount = 0;
                        if(shanshuoflag<1000)
                        ADdisplayb(0);
                        else if(shanshuoflag>=1000&&shanshuoflag<=3000)
                        {
                                ADdisplayb(weishu);
                                if(shanshuoflag==3000)
                                        shanshuoflag=0;
                        }
                }
        }
        if(adcount==40)
        {
                adcount = 0;
                ALE=1;
                ST=1;
                ALE=0;
                ST=0;
                _nop_();
                _nop_();
                zhuanhuanflag=1;
        }
        if(zhuanhuanflag==1)
        {
        if(EOC==1)
                {               
                        OE=1;
                        dd=P3;
                        OE=0;
                        dchange=min+((max-min)*(dd+1))/256;
                       
                        zhuanhuanflag=0;
                }
        }
}//全局時鐘變量計時
采集到的信號轉(zhuǎn)換成數(shù)字后的范圍為0~255,現(xiàn)如今要將其用(0~50)~(0~99)來表示,故在此需要將所采集的數(shù)據(jù)進行轉(zhuǎn)換,這里只需要用到簡單的數(shù)學(xué)公式就可以完成。轉(zhuǎn)換好之后需要用數(shù)碼管顯示,這里還是采用動態(tài)顯示。仿真結(jié)果如下:
4) 在程序3)的基礎(chǔ)上,增加模擬電壓輸入端的數(shù)據(jù)選擇即可,按鍵只運用一個數(shù)據(jù)選擇切換鍵。仿真結(jié)果如下:
4.3實驗總結(jié)
對于本次實驗,個人挺難的,課下花費了好長時間才勉強完成。數(shù)碼管顯示數(shù)據(jù)已經(jīng)在之前實驗中做過了,數(shù)據(jù)的采集與轉(zhuǎn)換是本次實驗的難點,經(jīng)過多次測試才克服這一難題。在本次實驗中收獲頗多。

五、通信實驗
5.1實驗要求
1) 設(shè)計電路圖
  要求采用2個單片機,左邊單片機控制2路模擬電壓的采集和1個18B20溫度傳感器的采集,右邊的單片機控制4位LED數(shù)碼管的顯示,6位按鍵控制,DAC輸出,2個單片機通過串口通信。
2) 實現(xiàn)功能
1、 按鍵F1,實現(xiàn)數(shù)字時鐘功能。可以設(shè)定起始時間,顯示格式 時:分 (HH.MM)
2、 按鍵F2,實現(xiàn)顯示溫度值,顯示格式    t XX.X
3、 按鍵F3, 實現(xiàn)顯示第1路ADC     顯示格式 F XXX, 實現(xiàn)顯示第2路ADC     顯示格式 L xxx
4、 按鍵F4, 實現(xiàn)時鐘與溫度交替顯示 ,交替間隔10秒。切換時閃爍2秒。
5、 由2路ADC控制DAC輸出三角波
5.2程序?qū)崿F(xiàn)
1) 數(shù)字時鐘功能
#include<reg51.h>
#define GPIO_DIG   P1        //段選
#define GPIO_PLACE P2        //位選
#define uchar unsigned char
#define uint  unsigned int
sbit key=P3^0;
uint disnum1=0,disnum2=0,disnum3=0,K;
unsigned char code DIG_PLACE[6] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
unsigned char code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void display(uint si,uint san,uint er,uint yi);
void delay(uint a)
{
        unsigned int i,j;
        for(j=a;j>0;j--)
                for(i=0;i<500;i++);
}
void main()
{      
    TMOD = 0X01;
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
    EA = 1;         
    ET0 = 1;      
    TR0 = 1;
        IT0=1;
        EX0=1;
        while(1)
        {
                   display(disnum3/10,disnum3%10,disnum2/10,disnum2%10);
        }
}
void time1() interrupt 1
{
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
                   if(K!=0){
                        disnum1++;
                        if(disnum1==100)
                        {
                                disnum1=0;
                                disnum2++;
                                if(disnum2==60)
                                {
                                        disnum2=0;
                                        disnum3++;
                                        if(disnum3==60)
                                        {
                                                disnum3=0;
                                        }
                                }
                        }         
                         }
}
void  int0(void) interrupt 0
{
   K = ~K;      
}
void display(uint si,uint san,uint er,uint yi)
{         
        GPIO_PLACE=~DIG_PLACE[2];
        GPIO_DIG=table[si];
        delay(1);
        GPIO_PLACE=~DIG_PLACE[3];
        GPIO_DIG=table[san]+0X80;
        delay(1);
        GPIO_PLACE=~DIG_PLACE[4];
        GPIO_DIG=table[er];
        delay(1);
        GPIO_PLACE=~DIG_PLACE[5];
        GPIO_DIG=table[yi];
        delay(1);
}
通過定時器計時,每隔10ms,disnum1加一;當(dāng)disnum1加到100時,disnum1置零,disnum2加一;當(dāng)disnum2加到60時,disnum2置零,disnum3加一。運用動態(tài)掃描的方式在數(shù)碼管上依次顯示disnum3、disnum2。仿真結(jié)果如下:
2) 溫度采集顯示
a) 溫度采集與數(shù)據(jù)發(fā)送程序
#include<reg51.h>   
#include<intrins.h>  
#include <absacc.h>
#include <math.h>
typedef unsigned int uint;         
typedef unsigned char uchar;
sbit CLK=P1^4;   
sbit ST=P1^2;  
sbit EOC=P1^1;  
sbit OE=P1^3;  
sbit ALE=P1^0;
sbit DQ=P1^0;
     unsigned char TL;     
     unsigned char TH;   
     unsigned char TN;      
     unsigned int TD;
unsigned char time_DS18B20;
uint adcount=0;
uint dpcount=0;
uint dd=0;
uchar zhuanhuanflag=0;      
void UsartConfiguration();
unsigned char ReadOneChar();
void WriteOneChar(unsigned char dat);
void ReadyReadTemp(void);
bit Init_DS18B20(void);
void CLKInit(void)
{
        ET0 = 1;
        TR0 = 1;
        TH0 = (65536-25)/256;
        TL0 = (65536-25)%256;
}
void CLK50us(void) interrupt 1
{
        TH0 = (65536-25)/256;
        TL0 = (65536-25)%256;
        CLK=!CLK;
}
void ScanLed(void) interrupt 2
{
        adcount++;
        if(adcount==40)
        {
                adcount = 0;
                ALE=1;
                ST=1;
                ALE=0;
                ST=0;
                _nop_();
                _nop_();
                zhuanhuanflag=1;
        }
        if(zhuanhuanflag==1)
        {
                if(EOC==1)
                {               
                        OE=1;
                        dd=P2;               
                        OE=0;
                        zhuanhuanflag=0;
                }
        }
}
void UsartConfiguration()
{
        SCON=0X40;                        //設(shè)置為工作方式1
        TMOD=0X20;                        //設(shè)置計數(shù)器工作方式2
        PCON=0X00;                        //波特率不加倍
        TL1=0XE8;                    //計數(shù)器初始值設(shè)置,注意波特率是2400的
        TH1=0XE8;
        ET1=1;
        TR1=1;                                            //打開計數(shù)器
        EA=1;                                                //打開總中斷
        ES=1;                                                //打開接收中斷
}
void ReadyReadTemp(void)
{
      Init_DS18B20();     
      WriteOneChar(0xCC);
      WriteOneChar(0x44);
      for(time_DS18B20=0;time_DS18B20<100;time_DS18B20++);         
      Init_DS18B20();     
      WriteOneChar(0xCC);
      WriteOneChar(0xBE);
}
bit Init_DS18B20(void)
{
bit flag_DS18B20;         
DQ = 1;         
for(time_DS18B20=0;time_DS18B20<2;time_DS18B20++);
DQ = 0;           
for(time_DS18B20=0;time_DS18B20<200;time_DS18B20++);         
DQ = 1;         
  for(time_DS18B20=0;time_DS18B20<10;time_DS18B20++);  
flag_DS18B20=DQ;         
for(time_DS18B20=0;time_DS18B20<200;time_DS18B20++);
return (flag_DS18B20);   
}
unsigned char ReadOneChar(  )
{
                unsigned char i=0;
                unsigned char dat;  
                for (i=0;i<8;i++)
                 {
                   DQ =1;      
                   _nop_();           
                   DQ = 0;      
                          dat>>=1;
                   _nop_();     
                   DQ = 1;     
                   for(time_DS18B20=0;time_DS18B20<3;time_DS18B20++);   
                   if(DQ==1)
                      dat|=0x80;
                        else
                                dat|=0x00;
                   for(time_DS18B20=0;time_DS18B20<8;time_DS18B20++)
                              ;            
            }
         return(dat);   
}
void WriteOneChar(unsigned char dat)
{
        unsigned char i=0;
        for (i=0; i<8; i++)
                 {
                  DQ =1;        
                  _nop_();           
                  DQ=0;         
                  DQ=dat&0x01;   
                 for(time_DS18B20=0;time_DS18B20<10;time_DS18B20++);
                  DQ=1;         
                  for(time_DS18B20=0;time_DS18B20<1;time_DS18B20++);
                  dat>>=1;      
                 }
          for(time_DS18B20=0;time_DS18B20<4;time_DS18B20++);
}
void main(void)
{
    UsartConfiguration();
        CLKInit();
        while(1)               
    {
                ReadyReadTemp();     
            TL=ReadOneChar();   
            TH=ReadOneChar();   
            if(TH>=8)
            {
                    TH=~TH;
                TL=~TL;
                TL=TL+1;
                if(TL==0)
                        TH+=1;                              
                TN=TH*16+TL/16;
                TD=(TL%16)*63;
                dd=TN*10+TD;
             }
             else
            {
                     TN=TH*16+TL/16;      
                TD=(TL%16)*62;
                       dd=TN*10+TD;
             }
                 TI=0;
                SBUF=dd;
                while(!TI);
          }
}
b) 數(shù)據(jù)接收與數(shù)碼管顯示程序
#include "reg52.h"                       
#include<intrins.h>
typedef unsigned int uint;         
typedef unsigned char uchar;
sbit LSA=P2^0;
sbit LSB=P2^1;
sbit LSC=P2^2;
uint dd=0;
uchar code table[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//顯示0~F的值
uchar ADdisplayflag=0;
uint CLK=0;
void ADdisplay();
void CLKInit(void);
void UsartConfiguration();
void main()
{
        UsartConfiguration();
        CLKInit();
        while(1)
        {      
                RI=0;
                dd=SBUF;
                while(!RI)
                ADdisplay();
        }
}                                       
void CLKInit(void)
{
        ET0 = 1;
        TR0 = 1;
        TH0 = (65536-25)/256;
        TL0 = (65536-25)%256;
}
void ADdisplay()
{
        switch(ADdisplayflag)
        {
                case 0:
                {
                        P0 = 0x00;
                        LSA=1;LSB=1;LSC=0;
                }break;
                case 1:
                {
                        P0 = 0x00;
                        P0 = table[dd/100];
                        LSA=0;LSB=1;LSC=0;
                }break;
                case 2:
                {
                        P0 = 0x00;
                        P0 = table[dd%100/10]+0x80;
                        LSA=1;LSB=0;LSC=0;
                }break;
                case 3:
                {
                        P0 = 0x00;
                        P0 = table[dd%10];
                        LSA=0;LSB=0;LSC=0;
                }break;
                default : break;
        }
        ADdisplayflag++;
        if(ADdisplayflag == 4)
        {
                ADdisplayflag = 0;
        }
}
void CLK50us(void) interrupt 1
{
        TH0 = (65536-25)/256;
        TL0 = (65536-25)%256;
        CLK=!CLK;
}
void UsartConfiguration()
{
        SCON=0X50;                        //設(shè)置為工作方式1
        TMOD=0X20;                        //設(shè)置計數(shù)器工作方式2
        PCON=0X00;                        //波特率不加倍
        TL1=0XE8;                    //計數(shù)器初始值設(shè)置,注意波特率是2400的
        TH1=0XE8;
        TR1=1;                                            //打開計數(shù)器
        EA=1;                                                //打開總中斷
        ES=1;                                                //打開接收中斷
}
        左邊的單片機通過P1.0口對溫度傳感器DS18B20進行溫度數(shù)據(jù)采集,然后通過串口通信原理將采集到的數(shù)據(jù)發(fā)送到右端單片機;右端單片機接收到數(shù)據(jù)后,將數(shù)據(jù)進行一定的數(shù)學(xué)處理,然后通過數(shù)碼管動態(tài)掃描的原理將數(shù)據(jù)顯示在數(shù)碼管上。仿真結(jié)果如下:
5.3實驗總結(jié)
本次實驗較為困難,在課前已經(jīng)花了很長時間去理解串口通信,等到了實驗課上的時候,依然比較模糊。之后經(jīng)過和同學(xué)的討論,把串口通信弄明白了。但是又卡在了溫度傳感器DS18B20上,經(jīng)過上網(wǎng)查找資料,最終才勉強做出溫度的采集顯示。
實驗總結(jié)與感想
首先,我對本次實驗課的成功倍感珍惜。在實驗中,我很深刻的了解到了理論和實踐的不同之處,在書本中學(xué)到、理解的知識內(nèi)容并不會很容易的運用在實際當(dāng)中。有很多沒有遇到過的實際問題會出現(xiàn),這時就需要我們?nèi)ド钊胩骄浚瑥亩鴮栴}一點點的解決,最后問題才能迎刃而解。在這次實驗中80C51單片機的編程有了更深入的了解,對單片機制作小作品方面的知識也更加的豐富。
同時也花了較多的時間對以前所學(xué)的東西進行了溫故,在以前的學(xué)習(xí)中沒有具體掌握的知識,又進行了學(xué)習(xí),鞏固。如硬件設(shè)計是很重要的,硬件設(shè)計的方式方法很多,并不是一塵不變的,它反映了你的邏輯思維和創(chuàng)新能力,所以我覺得它才是一個設(shè)計的靈魂所在。   
在實驗過程中,我碰到了很多問題,在同學(xué)、老師的幫助下,才能及時順利地解決,讓我感受到集體、友誼的力量。  
通過這學(xué)期的實驗不但讓我了解了更多電子方面的知識,同時也提高了自己的編程的能力。可以說這學(xué)期的實驗不僅體現(xiàn)掌握的知識,而且是學(xué)習(xí)更多知識的機會,提高自己各方面的知識。可以在今后的學(xué)習(xí)中,充分發(fā)揮自己所學(xué)的知識。本次實驗中,我學(xué)會什么叫堅持不懈、努力奮斗,在今后的學(xué)習(xí)、工作中一定要將在這次設(shè)計學(xué)到的品質(zhì)堅持下去。同時,對給過我?guī)椭睦蠋熀屯瑢W(xué)再次表示由衷的感謝!






歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 综合中文字幕 | 日韩精品一区二区三区视频播放 | 日本手机在线 | 久久影院一区 | 男女啪啪高潮无遮挡免费动态 | 日本偷偷操 | 污视频在线免费观看 | 欧美日韩电影一区二区 | 国产精品久久久久久久久久东京 | 波多野结衣一二三区 | 久久久这里都是精品 | 欧美三区 | 久久国产精品-国产精品 | 亚洲一区二区在线播放 | av在线播放网站 | 国产精品一区二区三区久久 | 一级片视频免费 | 北条麻妃国产九九九精品小说 | 国产视频精品在线 | 又爽又黄axxx片免费观看 | 欧美成人免费 | 国产精品久久久久一区二区三区 | 不卡在线一区 | 国产欧美一区二区三区久久 | 一本色道精品久久一区二区三区 | 欧美精品在线播放 | 伊人精品在线视频 | 国产成人免费视频网站高清观看视频 | 黄色免费观看 | 超碰人人人 | 欧美精品网 | 精品一区二区久久久久久久网站 | 欧美一级在线视频 | 欧洲一区二区三区 | 激情一区二区三区 | 久久国产精品无码网站 | 国产免费一区 | 啪啪精品 | 99精品国产在热久久 | 成人三级在线观看 | 99精品在线观看 |