<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          AVR I/O口使用方法

          作者: 時間:2013-12-10 來源:網(wǎng)絡(luò) 收藏

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

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

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

          //目標系統(tǒng): 基于單片機
          //應(yīng)用軟件: ICC
          /*01010101010101010101010101010101010101010101010101010101010101010101
          ----------------------------------------------------------------------
          實 驗內(nèi)容:
          點燈,讓燈左閃右閃,拼命閃。
          ----------------------------------------------------------------------
          硬 件連接:
          將PD口的LED指示燈使能開關(guān)切換到"ON"狀態(tài)。
          ----------------------------------------------------------------------
          注 意事項:
          (1)若有加載庫程序,請將光盤根目錄下的“庫程序”下的“ICC_H”文件夾拷到D盤
          (2)請詳細閱讀:光盤根目錄下的“產(chǎn)品資料開 發(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)調(diào)試
          本節(jié)的目的在于學(xué)習(xí)AVR的IO輸出功能,對于AVR來說,它和傳統(tǒng)的51單片機不 同,需要設(shè)置IO引腳方向。
          作如下調(diào)試:
          (1)改變IO方向,即將“LED_DDR=0XFF;”改為“0X00”,觀察現(xiàn)象。
          (2) 將語句:delay50ms(10);改為語句:delay50ms(1);可以看到LED閃的更快,眼都花了!

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

          通過中間變量c完成a、b變量內(nèi)容的交換!
          不過大家想一想使用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 真厲害,這個你都知道,看來是編程的行家。

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

          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)在很難遇到內(nèi)存不夠 的情況了。

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

          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......


          又學(xué)一招,確實也很巧妙!有異曲同工之處。
          我這些是看資料從別人那學(xué)來的,不過邏輯運 算要比算術(shù)運算快一倍以上,寫了個程序在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);
          }
          首先僅僅運算,算術(shù)運算用了8個時鐘單位,邏輯運算用了3個時鐘單位,因為算術(shù)運算牽扯到了負數(shù)。
          那變量賦值 呢,int 賦值用了4個時鐘單位,unsigned char賦值用了2個時鐘單位。
          綜合一下,算術(shù)運算用時12個單位,邏輯運算用時5個單位,效率要高 2.4倍! 項目編譯完后會生成一個.cof的調(diào)試文件(我是用ICC,CV應(yīng)該也有),用AVR Studio打開這個.cof文件,選好處理器型號(M16)就會進入軟件仿真,按Alt+O快捷鍵設(shè)置處理器的頻率,這樣可以看運行的時間,否則只能看 運行時鐘,時間就不準了。再下來就是按F11單步執(zhí)行,F(xiàn)10是一下執(zhí)行完一個過程,如:循環(huán)、函數(shù)等。時鐘和運行時間可以在任意時間用鼠標右鍵清零,這 樣數(shù)字比較直觀,不用再加減。

          c語言相關(guān)文章:c語言教程



          上一頁 1 2 下一頁

          關(guān)鍵詞: AVR IO口 寄存器

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();