新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STC89C52單片機UART AD DA測試實驗

        STC89C52單片機UART AD DA測試實驗

        作者: 時間:2016-11-21 來源:網絡 收藏
        ///////////////////////////////////////////////////////////////////////////

        實現功能: 調節實驗板上的標號為AD0的電位器改變電壓,通過PCF8591的采集,把
        數據傳輸給單片機,單片機通過處理把采集到的電壓值,顯示在數碼管
        上,同時把通過AD0采集到的數據重新寫入PCF8591,讓其轉換成模擬信
        號,改變開發板上D11的亮暗程度,而且把采集到的數據通過串口發送到
        電腦上。注意所采用的通道為第0通道,也就
        是說調節的是AD0電位器
        實驗板型號:KBL-XYD-C52
        實驗名稱:UART AD DA測試實驗
        編寫人:謝應東
        編寫日期: 2012-4-30
        ///////////////////////////////////////////////////////////////////////////
        #include //包含52單片機頭文件
        #include //包含標準輸入輸出文件

        本文引用地址:http://www.104case.com/article/201611/319238.htm

        #define uchar unsigned char//宏定義這個誰都知道的
        #define uint unsigned int

        uchar code table[]={
        0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共陰數碼管1至F數字編碼

        sbit duan=P2^6; //573鎖存器段鎖存端
        sbit wei=P2^7; //位鎖存端

        sbit sda=P2^0; //定義模擬IIC總線的數據線
        sbit scl=P2^1; //定義模擬IIC總線的時鐘線

        float fValue;

        #define FOSC 11059200L
        #define TIMS (65535-FOSC/12/1000) //在12T模式下定時器中斷1毫秒的計算方法

        uint cCount,cFlag=0;
        ///////////////////////////////////////////////////////////////////////////
        函數名稱:毫秒延時函數
        函數功能:實現毫秒級的延時
        參數介紹:Delay_MS: 定義需要延時的毫秒的數值
        iNumber: 記錄Delay_MS的數值,以for語句實現所要求的延時
        iValue: 要延時毫秒所要進行的循環數值,本數值為實際測得
        返回值:
        注意事項:本實驗是在所用晶振為12M的前提下實現的毫秒延時,本函數是通過循環的形
        式完成,所以如果改變了晶振的頻率,請做相應的改變
        ///////////////////////////////////////////////////////////////////////////

        void DelayMs(uint Delay_MS)
        {
        uint iNumber,iValue;
        for(iNumber=0;iNumber{
        iValue=107;
        while(iValue--);
        }
        }
        ///////////////////////////////////////////////////////////////////////////
        函數名稱:DelayUs
        函數功能:延時幾個微秒(us),用來IIC總線延時
        參數介紹:無
        返回值:
        注意事項:無
        ///////////////////////////////////////////////////////////////////////////

        void DelayUs()
        {;;}
        ///////////////////////////////////////////////////////////////////////////
        函數名稱:Display_V
        函數功能:把通過PCF8591采集到的數據,在單片機處理完之后,顯示在數碼管上
        參數介紹:cBai:要顯示在第一個數碼管上的數字
        cShi:要顯示在第二個數碼管上的數字
        cGe:要顯示在第三個數碼管上的數字
        返回值:
        注意事項:注意實驗板上所要用到底的數碼管為共陰極的數碼管
        ///////////////////////////////////////////////////////////////////////////
        void Display_V(uchar cBai,uchar cShi,uchar cGe)
        {
        duan=1; //打開數碼管的段選
        P0=table[cBai]|0x80;//送入相應的段選0x80是為了點亮數碼管小數點(dp端)
        duan=0;//關閉數碼管的段選
        P0=0xff;
        wei=1;//打開數碼管的位選
        P0=0xfe; //給要點亮數碼管的公共極低電平
        wei=0;//關閉數碼管的位選
        DelayMs(5);//穩定時序

        duan=1;//打開數碼管的段選
        P0=table[cShi];//送入相應的段選
        duan=0;//關閉數碼管的段選
        P0=0xff;
        wei=1; //打開數碼管的位選
        P0=0xfd; //給要點亮數碼管的公共極低電平
        wei=0; //打開數碼管的位選
        DelayMs(5); //穩定時序

        duan=1; //打開數碼管的段選
        P0=table[cGe]; //送入相應的段選
        duan=0; //關閉數碼管的段選
        P0=0xff;
        wei=1; //打開數碼管的位選
        P0=0xfb; //給要點亮數碼管的公共極低電平
        wei=0; //打開數碼管的位選
        DelayMs(5); //穩定時序
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:Init_IIC
        函數功能:完成對IIC總線數據線時鐘線初始化
        參數介紹:無
        返回值:
        注意事項:無
        ///////////////////////////////////////////////////////////////////////////
        void Init_IIC()
        {
        sda=1;
        scl=1;
        }
        ///////////////////////////////////////////////////////////////////////////
        函數名稱:Start_IIC
        函數功能:IIC總線的開始條件
        參數介紹:無
        返回值:
        注意事項:具體請參考相關的文檔
        ///////////////////////////////////////////////////////////////////////////
        void Start_IIC()//開始條件
        {
        sda=1;
        DelayUs();
        scl=1;
        DelayUs();
        sda=0;
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:Stop_IIC
        函數功能:IIC總線的終止條件
        參數介紹:無
        返回值:
        注意事項:具體請參考相關的文檔
        ///////////////////////////////////////////////////////////////////////////

        void Stop_IIC()
        {
        sda=0;
        DelayUs();
        scl=1;
        DelayUs();
        sda=1;
        DelayUs();
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:Response_IIC
        函數功能:IIC總線的應答條件
        參數介紹:cNumber: 定義一個延時的變量
        返回值:
        注意事項:具體請參考相關的文檔
        ///////////////////////////////////////////////////////////////////////////
        void Response_IIC()//
        {
        uchar cNumber=0;
        scl=1;
        DelayUs();
        while((sda==1)&&(cNumber<255))
        cNumber++; //加一個等待時間防止程序一直處在檢測狀態
        scl=0;//這個是應答和非應答綜合的應答條件
        DelayUs();
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:Write_byte
        函數功能:通過IIC總線向PCF8591寫入一個字節
        參數介紹:cData:要寫入的字節的值
        cNumber: 定義for語句中用到的變量,因為IIC總線是一位一位寫入的,所
        以需要循環8次
        cTempValue: 臨時的一個變量
        返回值:
        注意事項:具體請參考相關IIC文檔
        ///////////////////////////////////////////////////////////////////////////
        void Write_byte(uchar cData)
        {
        uchar cNumber,cTempValue;
        cTempValue=cData;
        for(cNumber=0;cNumber<8;cNumber++) //循環8次,完成一個字節的寫入
        {
        cTempValue=cTempValue<<1; //CY=cTempValue^7;
        scl=0;
        DelayUs();
        sda=CY; //CY 進位標志位
        DelayUs();
        scl=1;
        DelayUs();
        }
        scl=0;
        DelayUs();
        sda=1;
        DelayUs();
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:Read_byte
        函數功能:通過IIC總線,從器件里讀取一個字節,因為必須是一位一位讀,所以需要
        循環8次
        參數介紹:cNumber:for句用到的循環變量
        返回值: cValue:返回讀取到的字節
        注意事項:請參考相應的文檔
        ///////////////////////////////////////////////////////////////////////////

        uchar Read_byte()
        {
        uchar cNumber=0,cValue=0;
        scl=0;
        DelayUs();
        sda=1;
        DelayUs();
        for(cNumber=0;cNumber<8;cNumber++) //完成對一個字節的讀取
        {
        scl=1;
        DelayUs();
        cValue=(cValue<<1)|sda; //通過循環得到一個字節
        scl=0;
        DelayUs();
        }
        return cValue; //返回讀取到的字節
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:Read_channel
        函數功能:選取PCF8591的AD輸入通道,然后再讀出采集到數值,即電壓值
        參數介紹:無
        返回值: cValue:返回采集到的數據
        注意事項:無
        ///////////////////////////////////////////////////////////////////////////
        uchar Read_channel(uchar cChannel)//PCF通道選擇函數
        {
        uchar cValue; //從這個通道讀出數據是大多數學習者
        Start_IIC(); //比較模糊的地方
        Write_byte(0x90); //這個時序請按照AT24C02的任意讀時序圖進行操作
        Response_IIC();
        Write_byte(0x40|cChannel);
        Response_IIC();
        Start_IIC();
        Write_byte(0x91); //給IIC器件寫入相應的命令
        Response_IIC();
        cValue=Read_byte(); //讀取采集到的數據
        Stop_IIC();

        return cValue; //返回采集到的數據
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:Write_Data
        函數功能:把要寫入的數據寫入PCF8591,讓其開始轉換,然后輸出相應的模擬值
        參數介紹:cData:要寫入PCF8591的數據
        返回值:
        注意事項:無
        ///////////////////////////////////////////////////////////////////////////
        void Write_Data(uchar cData)
        {
        Start_IIC();//以下嚴格按照PCF8591寫時序圖
        Write_byte(0x90);//進行操作
        Response_IIC();
        Write_byte(0x40);
        Response_IIC();
        Write_byte(cData);
        Response_IIC();
        Stop_IIC();
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:Init_UART
        函數功能:設定UART的波特率,配置定時器0每一毫秒鐘中斷一次,打開相應的中斷
        定時器1產生波特率,讓定時器0開始中斷計時
        參數介紹:無
        返回值:
        注意事項:無
        ///////////////////////////////////////////////////////////////////////////
        void Init_UART()
        {
        TMOD=0x21;//定時器1工作方式2,8位自動充裝
        TH1=0xfd; //通信波特率定為9600bps
        TL1=0xfd; //晶振為11.0592M的

        TL0=TIMS;
        TH0=TIMS>>8; //定時1秒所要裝的初值
        SM0=0; //選擇串行口工作方式1
        SM1=1;

        EA=1; //打開全局中斷
        ET0=1; //打開定時器0中斷
        TR0=1; //讓定時器0開始工作
        TR1=1; //波特率的產生依靠是定時器1的溢出率
        }
        ///////////////////////////////////////////////////////////////////////////

        函數名稱:main
        函數功能:完成對采集到的電壓值的處理,然后顯示到前三個數碼管上,把采集到的
        數據同時寫入PCF8591里,讓其轉換成模擬信號,改變發光二極管D11的亮
        暗程度
        參數介紹:cBai:因為把數分離,才能顯示到數碼管上,作為分離后顯示在第一個數
        碼管上的數
        cShi:顯示在第二個數碼管上的數
        cGe:顯示在第三個數碼管上的數
        iTempValue:臨時變量,賦予從PCF8591通道0讀出來的數值
        返回值:
        注意事項:無
        ///////////////////////////////////////////////////////////////////////////

        void main()
        {
        uchar cBai,cShi,cGe;
        int iTempValue;
        DelayMs(50);//穩定系統
        Init_UART();//初始化串口
        Init_IIC();//IIC總線初始化
        while(1) //大循環是用來不停地掃描PCF8591的數據變換
        {
        iTempValue=Read_channel(0);//從PCF8591通道0讀出來的數值
        fValue=(float)iTempValue/51; //要把num強制轉換為float型進行計算
        cBai=iTempValue/51;//下面這三個分離是把從通道讀取到的數值轉換為電壓
        cShi=iTempValueQ*10/51; //想一下5V為255那么1v是不是代表51
        cGe=iTempValueQ*10Q*10/51;//1.8v是不是數值92
        Display_V(cBai,cShi,cGe);//把電壓值顯示到數碼管上
        Write_Data(iTempValue);//把采集到數據寫到PCF8591,讓其轉換成模擬信號
        if(cFlag==1)
        {
        cFlag=0;//對標志位清零,以便下次再發送
        TI=1; //這一點至關重要
        printf("The Volatage is %f Vn",fValue); //頭文件stdio.h的標準函數
        printf("The Num is %d nn",iTempValue);
        while(!TI);//判斷是否發送完畢
        TI=0;//發送完成后記住要清零,為了下次發送
        }
        }
        }

        void Timer0_Routine() interrupt 1
        {
        TL0=TIMS;
        TH0=TIMS>>8; //定時1毫秒所要裝的初值
        cCount++;
        if(cCount==1000)
        {
        cCount=0;
        cFlag=1;
        }
        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 汝南县| 嘉定区| 潞城市| 阜阳市| 塘沽区| 景谷| 阿勒泰市| 红安县| 韶山市| 汨罗市| 连城县| 江津市| 沙河市| 酒泉市| 泾川县| 剑阁县| 林州市| 长宁区| 连南| 邻水| 商丘市| 科技| 西林县| 乌兰浩特市| 安达市| 昌都县| 金坛市| 石渠县| 巴林右旗| 怀安县| 获嘉县| 和田市| 辽阳市| 枣庄市| 乐业县| 资源县| 连州市| 漯河市| 南宁市| 永兴县| 桂平市|