新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > AVR I/O口使用方法

        AVR I/O口使用方法

        作者: 時間:2013-12-10 來源:網絡 收藏

        主控電路原理圖(點擊圖片放大,不需要放大鏡! )

        LED控制電路原理圖(點擊圖片放大,不需要放大鏡! )
        軟件設計

        下面部分從TXT拷出,拷到網頁,代碼部分缺省了很多空格,比較凌亂,請諒解!

        //目標系統(tǒng): 基于單片機
        //應用軟件: ICC
        /*01010101010101010101010101010101010101010101010101010101010101010101
        ----------------------------------------------------------------------
        實 驗內容:
        點燈,讓燈左閃右閃,拼命閃。
        ----------------------------------------------------------------------
        硬 件連接:
        將PD口的LED指示燈使能開關切換到"ON"狀態(tài)。
        ----------------------------------------------------------------------
        注 意事項:
        (1)若有加載庫程序,請將光盤根目錄下的“庫程序”下的“ICC_H”文件夾拷到D盤
        (2)請詳細閱讀:光盤根目錄下的“產品資料開 發(fā)板實驗板SMK系列SMK1632說明資料”
        ----------------------------------------------------------------------
        10101010101010101010101010101010101010101010101010101010101010101010*/

        #include iom16v.h>
        #include "D:ICC_HCmmICC.H"
        #define LED_DDR DDRD
        #define LED_PORT PORTD
        /*--------------------------------------------------------------------
        程 序名稱:
        程序功能:
        注意事項:
        提示說明:
        輸 入:
        返 回:
        --------------------------------------------------------------------*/
        void main(void)
        {
        uint8 i,j;
        LED_DDR=0XFF;
        while(1)
        {
        for(i=0;i4;i++)
        {
        LED_PORT^=0xFF; //我閃!拚命閃!
        delay50ms(10);
        }
        j=0x01;
        for(i=0;i8;i++)
        {
        j=1;
        LED_PORT=j; //我左閃!
        delay50ms(10);
        }
        j=0x80;
        for(i=0;i8;i++)
        {
        j>>=1;
        LED_PORT=j; //我右閃!
        delay50ms(10);
        }
        }
        }

        系統(tǒng)調試
        本節(jié)的目的在于學習AVR的IO輸出功能,對于AVR來說,它和傳統(tǒng)的51單片機不 同,需要設置IO引腳方向。
        作如下調試:
        (1)改變IO方向,即將“LED_DDR=0XFF;”改為“0X00”,觀察現(xiàn)象。
        (2) 將語句:delay50ms(10);改為語句:delay50ms(1);可以看到LED閃的更快,眼都花了!

        東西在于靈活運用,下面是用LED做的手表,內部是用AVR,ATmega48做的,請思考實現(xiàn)如何下 面的功能。

        AVR 單片機的是標準的雙向端口,首先要設置的狀態(tài),即:輸入還是輸出

        DDRx就是AVR單片機的端口方向,通過設置DDRx可以設置x端口的狀態(tài)。
        DDRx 端口方向相應位設置為1則對應的x端口相應位為輸出狀態(tài),DDRx端口方向寄存器相應位設置為0則對應的x端口相應位為輸入狀態(tài)。
        例如:
        DDRA = 0xFF; //設置端口A所有口為輸出狀態(tài),因為0xFF對應的二進制為11111111b

        DDRA = 0x0F //設置端口A高4位為輸入狀態(tài),低4位為輸出狀態(tài),因為0x0F對應的二進制為00001111b


        PORTx寄存器是AVR單片機的輸出寄存器,端口輸出狀態(tài)設定好后通過設置PORTx可以使 端口x的相應位輸入高電平或低電平來控制外部設備。
        例如:
        PORTA = 0xFF; //端口A所有口線輸出高電平

        PORTA = 0x0F; //端口A高4位輸出低電平,低4位輸出高電平

        小貼士:
        利用位邏輯運算符對特定的端口進行設定。

        PORTA = 13; //端口A第4位置為高電平,其它為低電平,應為00000001左移3位后是00001000
        PORTA = 17; //同理,第8位置高電平

        有時候我們期望端口某一位設置成高電平,但是其它位的高低電平要保持不變,如何做呢?C語言是很強大 的,有辦法!如下:

        PORTA |=13; //實現(xiàn)端口A第4位置為高電平,其它位的高低電平不受影響
        上面的語句是簡化的寫法,分解一下就是:
        PORTA = PORTA | (13); //數(shù)字1左移3位后與端口A進行按位或,結果就是端口A第4位置為高電平,其它位的高低電平不受影響

        那么大家就會問了,如何實現(xiàn)設置某一位為低電平,其它位的高低電平不變呢?建議大家思考1分鐘再看下面 的內容。
        PORTA =~(13); //解釋一下,首先將1左移3位變成00001000b,然后再按位取反變成11110111b,然后再與端口A做按位與運算,這樣就實現(xiàn)了設置端口A第 4位為低電平,其它位的高低電平不變。
        分解后的語句為:
        PORTA = PORTA (~(13)); //結果是一樣的

        將某端口相應位的高低電平翻轉,即原來高電平變?yōu)榈碗娖?,低電平變?yōu)楦唠娖?,呵呵!好簡單呦?/FONT>

        PORTA = ~PORTA; //將PORTA按位取反后再賦值給PORTA

        按位邏輯運算還有一個異或,這個也非常有意思,它能實現(xiàn)電平翻轉,有興趣大家看看書,算是給大家留個想 頭吧!

        再出個小題目!
        大家都知道已知a,b兩個變量,再編程中要交換兩個變量常用的方法是定義一個中 間變量c,然后:

        c=a;
        a=b;
        b=c;

        通過中間變量c完成a、b變量內容的交換!
        不過大家想一想使用C語言能不能不用中間變量來完成 a、b變量的交換呢?答案肯定是能,因為C語言很強大!
        不過還是希望大家先想一想再看答案,看完答案后再認真分析一下,體會編程的巧妙之處!
        答 案:
        使用到了C語言的按位異或邏輯操作,由于沒有中間變量,同時邏輯運算的速度很快,整個交換過程比常規(guī)方法要快不少!

        a ^= b;
        b ^= a;
        a ^= b;

        過程就是a異或b,b異或a,然后a再異或b就完成了!

        異或的邏輯表
        1 ^ 1 0
        0 ^ 1 1
        1 ^ 0 1
        0 ^ 0 0

        adm 真厲害,這個你都知道,看來是編程的行家。

        交換變量這樣的問題,如果你沒看過相關的資料,初學者很難自己想出來的。

        int a,b;

        a=3;

        b=5;

        a=a+b //a=8 b=5

        b=a-b //a=8 b=3

        a=a-b //a=5 a=3

        這樣僅僅是算法技巧的問題,現(xiàn)在很難遇到內存不夠 的情況了。

        交換變量這樣的問題,如果你沒看過相關的資料,初學者很難自己想出來的。

        int a,b;
        a=3;
        b=5;

        a=a+b //a=8 b=5
        b=a-b //a=8 b=3
        a=a-b //a......


        又學一招,確實也很巧妙!有異曲同工之處。
        我這些是看資料從別人那學來的,不過邏輯運 算要比算術運算快一倍以上,寫了個程序在AVR Studio 中軟件仿真了一下!
        程序如下:
        #include iom16v.h>

        void main (void)
        {
        int a=10,b=20;
        unsigned char x=30,y=40;

        a = a + b;
        b = a - b;
        a = a - b;

        x ^= y;
        y ^= x;
        x ^= y;
        while (1);
        }
        首先僅僅運算,算術運算用了8個時鐘單位,邏輯運算用了3個時鐘單位,因為算術運算牽扯到了負數(shù)。
        那變量賦值 呢,int 賦值用了4個時鐘單位,unsigned char賦值用了2個時鐘單位。
        綜合一下,算術運算用時12個單位,邏輯運算用時5個單位,效率要高 2.4倍! 項目編譯完后會生成一個.cof的調試文件(我是用ICC,CV應該也有),用AVR Studio打開這個.cof文件,選好處理器型號(M16)就會進入軟件仿真,按Alt+O快捷鍵設置處理器的頻率,這樣可以看運行的時間,否則只能看 運行時鐘,時間就不準了。再下來就是按F11單步執(zhí)行,F(xiàn)10是一下執(zhí)行完一個過程,如:循環(huán)、函數(shù)等。時鐘和運行時間可以在任意時間用鼠標右鍵清零,這 樣數(shù)字比較直觀,不用再加減。

        c語言相關文章:c語言教程



        上一頁 1 2 下一頁

        關鍵詞: AVR IO口 寄存器

        評論


        相關推薦

        技術專區(qū)

        關閉
        主站蜘蛛池模板: 喀喇沁旗| 沭阳县| 建始县| 泗水县| 蒲城县| 建平县| 垣曲县| 都安| 龙陵县| 阳山县| 龙口市| 襄城县| 永春县| 石景山区| 曲阳县| 亚东县| 翼城县| 尖扎县| 东宁县| 平塘县| 延庆县| 新余市| 揭东县| 兴隆县| 宁国市| 龙州县| 伊宁县| 河北省| 玉环县| 合山市| 丘北县| 稻城县| 林芝县| 惠来县| 城固县| 津市市| 宝应县| 土默特右旗| 梁山县| 怀仁县| 台北市|