AVR单片机及其开发环境
內容包括AVRStudio及WinAVR介紹,軟件下載地址,編譯環境設置,IAR for AVR的使用,AVR單片機的介紹。紫色文字是超鏈接,點擊自動跳轉至相關博文。持續更新,原創不易!
目錄:
一、AVRStudio及WinAVR簡介
1、使用AVR GCC做為編譯器
2、選擇仿真調試平臺
3、選擇Device,設置Frequency,代碼優化選項Optimization,輸出hex文件
4、設置包含文件(頭文件)路徑
5、設置庫文件路徑
6、設置工具鏈路徑(不使用AVR Toolchain)
二、Avr Studio和Winavr最新版下載地址
三、Avr Studio和Winavr編譯環境設置
四、IAR for AVR的使用(CC2530開發套件zigbee開發板)
1、出現“IAR AVR unknown or ambiguous symbol.main”?
2、處于調試狀態,但是不能在C語言上單步運行,也不能設置斷點
3、IAR For AVR軟件的精確延時
4、IAR中加入編譯所需庫的頭文件
五、AVR JTAG ICE MKII仿真器
六、AVR寄存器定義
七、AVR移位算法詳細解釋(1<<X)
------------------------------------------------------------------------------------------------------
一、AVRStudio及WinAVR簡介
AVRStudio 是ATMEL 官方針對AVR 系列單片機推出的集成開發環境,它集開發調試于一體,有很好的用戶界面,很好的穩定性。AVRSdudio 是免費的。AVRStudio 本身可以開發匯編程序,如果希望使用C語言開發,則需要安裝C編譯器(WinAVR 等)。
WinAVR 是GNU 組織推出的AVR 單片機的gcc 編譯器,該編譯器的編譯效率極高。gcc 編譯器是開源的,是免費的。使用gcc 編譯器,可以掌握標準c 的語法等,為學習Linux 等奠定基礎。
------------------------------------------------------------------------------------------------------
二、Avr Studio和Winavr最新版下載地址
AVRStudio 最新版本的官方下載地址:Smart | Connected | Secure | Microchip Technology?
WinAVR 最新版本的官方下載地址:WinAVR - Browse Files at SourceForge.net
------------------------------------------------------------------------------------------------------
三、Avr Studio和Winavr編譯環境設置
1、使用AVR GCC做為編譯器---------------------------------------
2、選擇仿真調試平臺?---------------------------------------
3、選擇Device,設置Frequency,代碼優化選項Optimization,輸出hex文件?---------------------------------------
4、設置包含文件(頭文件)路徑?---------------------------------------
5、設置庫文件路徑?---------------------------------------
6、設置工具鏈路徑(不使用AVR Toolchain)? 如此便可使用winavr作為c編譯器,不會出現avr-objcopy: '****.elf': No such file的錯誤。 ------------------------------------------------------------------------------------------------------ 四、IAR for AVR的使用(CC2530開發套件zigbee開發板)1、出現“IAR AVR unknown or ambiguous symbol.main”?
project==>options==>linker,format設置成debug。?
IAR下必須進入DEBUG模式才能進行調試,如果不連接開發工具的話,斷點也是不行的
---------------------------------------
2、處于調試狀態,但是不能在C語言上單步運行,也不能設置斷點
project==>options==>C/C++Compiler,將Generate debug information打上勾。
---------------------------------------
3、IAR For AVR軟件的精確延時
不浪費中斷的情況下的精確延時當然是軟件自帶的單周期的空操作,比如_nop_();
在IAR for AVR中的庫函數#include"intrinsics.h"里面有個單周期的延時函數__delay_cycles();(相當于_nop_();),
如果__delay_cycles(100)就是100個mclk的周期延時。
然后就是下面的操作了:
#ifndef __delay_h
#define __delay_h
#include"intrinsics.h"
#define xtal??8???????//這里就是你要使用的晶振的頻率(單位NHZ)
#define delay_us(x) __delay_cycles((unsigned??long)(x*xtal))
#define delay_ms(x) __delay_cycles((unsigned??long)(x*xtal*1000))
#define delay_s(x)??__delay_cycles((unsigned??long)(x*xtal*1000000))
#endif
3)就是在你用到延時的函數里面調用#include"Delay.h"(這里是不區分大小寫的,哈,不用擔心這個)
這就在不浪費中斷情況下的軟件延時,當然你要非得精確,那非得定時計數器不可了
補充一下:
我用的是IAR for AVR,別的軟件什么的似乎也有延時函數,如果沒有可以用下面的這個延時(聽說也是相當準的,在8MHZ晶振下,不管是外接還是內部晶振,哈都一樣):
//------------------------------------------------------------------------------
//延時函數
void??delay_ms(uint k)
{
??uint??i,j;
??for(i=0;i
????for(j=0;j<1140;j++);
}
還有一個:差點忘記(這個不知道是那個哥們想到的,也可以改變晶振的~~~都貼出來,反正沒事干):
//------------------------------------------------------------------------------
//延時1ms的函數,沒有參數傳遞
void??delay_1ms()
{
??uint i;
??for(i=1;i<(uint)(xtal*143-2);i++)
????;
}
//------------------------------------------------------------------------------
//延時nms的函數,有參數傳遞
void??delay_nms(uint n)
{
??uint i=0;
??while(i
??{
????delay_1ms();
????i++;
??}
}
---------------------------------------
4、IAR中加入編譯所需庫的頭文件
工程名右擊->options->C/C++?compiler->Preprocessor中填入頭文件所在的目錄即可,$PROJ_DIR$表示工程所在目錄,\..\工程所在目錄的上一層目錄。設置后詳見圖片。
------------------------------------------------------------------------------------------------------
五、AVR JTAG ICE MKII仿真器
注意:此處的VTref需要接VCC。
------------------------------------------------------------------------------------------------------
六、AVR寄存器定義
#include "iom16v.h"
#include "macros.h"
void initialize()
{
? ? // DDRx端口方向寄存器,PORTx數據寄存器,PINx輸入引腳寄存器
? ? // DDRxn相應位為1,引腳為輸出否則為輸入
? ? // PORTxn為1時,上拉電阻使能
? ? DDRA = 0x00;
}
void init_adc()
{
? ? // ADMUX
? ? // -----------------------------------------------------------------
? ? // | REFS1 | REFS0 | ADLAR |??MUX4 |??MUX3 |??MUX2 |??MUX1 |??MUX0 |
? ? // -----------------------------------------------------------------
? ? // REFS1 REFS0: 00,使用AREF,內部參考電壓關閉
? ? //? ?? ?? ?? ???01,AVCC、AREF引腳外加濾波電容
? ? //? ?? ?? ?? ?? ???10,保留
? ? //? ?? ?? ?? ?? ???11,2.56V片內基準電壓,AREF引腳外加濾波電容
? ? // ADLAR: ADC轉換結果左對齊
? ? //??MUX4 ~??MUX0? ?單端輸入??正差分輸入? ?負差分輸入? ?增益
? ? // 00000 ~ 00111??ADC0~ADC7
? ? //? ?01000? ?? ?? ?? ?? ?? ? ADC0? ?? ?? ?ADC0? ?? ?? ?10x
? ? //? ?01001? ?? ?? ?? ?? ?? ? ADC1? ?? ?? ?ADC0? ?? ?? ?10x
? ? //? ?01010? ?? ?? ?? ?? ?? ? ADC0? ?? ?? ?ADC0? ?? ???200x? ?? ?? ?? ?? ?? ?
? ? //? ?01011? ?? ?? ?? ?? ?? ? ADC1? ?? ?? ?ADC0? ?? ???200x
? ? //? ?01100? ?? ?? ?? ?? ?? ? ADC2? ?? ?? ?ADC2? ?? ?? ?10x
? ? //? ?01101? ?? ?? ?? ?? ?? ? ADC3? ?? ?? ?ADC2? ?? ?? ?10x
? ? //? ?01110? ?? ?? ?? ?? ?? ? ADC2? ?? ?? ?ADC2? ?? ???200x
? ? //? ?01111? ?? ?? ?? ?? ?? ? ADC3? ?? ?? ?ADC2? ?? ???200x
? ? //? ?10000? ?? ?? ?? ?? ?? ? ADC0? ?? ?? ?ADC1? ?? ?? ? 1x
? ? //? ?10001? ?? ?? ?? ?? ?? ? ADC1? ?? ?? ?ADC1? ?? ?? ? 1x
? ? //? ?10010? ?? ?? ?? ?? ?? ? ADC2? ?? ?? ?ADC1? ?? ?? ? 1x
? ? //? ?10011? ?? ?? ?? ?? ?? ? ADC3? ?? ?? ?ADC1? ?? ?? ? 1x
? ? //? ?10100? ?? ?? ?? ?? ?? ? ADC4? ?? ?? ?ADC1? ?? ?? ? 1x
? ? //? ?10101? ?? ?? ?? ?? ?? ? ADC5? ?? ?? ?ADC1? ?? ?? ? 1x
? ? //? ?10110? ?? ?? ?? ?? ?? ? ADC6? ?? ?? ?ADC1? ?? ?? ? 1x
? ? //? ?10111? ?? ?? ?? ?? ?? ? ADC7? ?? ?? ?ADC1? ?? ?? ? 1x
? ? //? ?11000? ?? ?? ?? ?? ?? ? ADC0? ?? ?? ?ADC2? ?? ?? ? 1x
? ? //? ?11001? ?? ?? ?? ?? ?? ? ADC1? ?? ?? ?ADC2? ?? ?? ? 1x
? ? //? ?11010? ?? ?? ?? ?? ?? ? ADC2? ?? ?? ?ADC2? ?? ?? ? 1x
? ? //? ?11011? ?? ?? ?? ?? ?? ? ADC3? ?? ?? ?ADC2? ?? ?? ? 1x
? ? //? ?11100? ?? ?? ?? ?? ?? ? ADC4? ?? ?? ?ADC2? ?? ?? ? 1x
? ? //? ?11101? ?? ?? ?? ?? ?? ? ADC5? ?? ?? ?ADC2? ?? ?? ? 1x
? ? //? ?11110? ?? ? 1.23V(VBG)
? ? //? ?11111? ?? ???0V(GND)? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?
? ???ADMUX = 0;
? ? // ADCSRA
? ? // -----------------------------------------------------------------
? ? // |??ADEN |??ADSC |??ADFR |??ADIF |??ADIE | ADPS2 | ADPS1 | ADPS0 |
? ? // -----------------------------------------------------------------
? ? // ADEN:ADC使能,轉換過程中禁止ADC則立即中止轉換。
? ? // ADSC:ADC開始轉換。在轉換過程中ADSC為1直到轉換結束。
? ? // ADFR:是否工作在連續模式,該位寫0,停止連續轉換模式。
? ? // ADIF:ADC中斷標志。中斷服務硬件清零。
? ? // ADIE:ADC中斷使能
? ? // ADSP2 ~ ADSP0:ADC預分頻選擇??000:2分頻,001到111為2到128分頻
? ? //? ?? ?? ?? ?? ?ADC在50~200KHz時鐘時能獲得最大精度
? ? ADCSRA = 0;
? ? // ADCC & ADCH
? ? // ADC轉換結果寄存器,差分通道結果以2的補碼形式表示,ADC數據必須讀過
? ? // ADCH后才可進行數據更新。對于精度小于8位的左對齊數據可只讀ADCH。
? ? // 數據右對齊(ADLAR = 0)
? ? // ADCH-------------------------------------------------------------
? ? // |? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|??ADC9 |??ADC8 |
? ? // -----------------------------------------------------------------
? ? // ADCL-------------------------------------------------------------
? ? // |??ADC7 |??ADC6 |??ADC5 |??ADC4 |??ADC3 |??ADC2 |??ADC1 |??ADC0 |
? ? // -----------------------------------------------------------------
? ? //
}
void init_timer()
{
? ? //SFIOR
? ? // -----------------------------------------------------------------
? ? // |??TSM??|? ?-? ?|? ?-? ?|? ?-? ?|??ACME |??PUD??|??PSR0 | PSR321|
? ? // -----------------------------------------------------------------
? ? // TSM: T/C同步模式。置位時,PSR0和PSR321保持其數據直到被更新或TSM被清零
? ? // PSR0:T/C0預分頻器復位,置位時使預頻器復位,直到為0時表示復位完成
? ? // PSR321: T/C3、2、1預分頻繁器復位,此位讀總為0
? ? // ACME: 模擬比較器使能
? ? // PUD:所有端口上拉電阻禁止,置1為禁止
? ? SFIOR = 0;
}
void init_timer0()
{
? ? //TCCR0 T/C0控制寄存器
? ? // -----------------------------------------------------------------
? ? // |??FOC0 | WGM00 | COM01 | COM00 | WGM01 |??CS02 |??CS01 |??CS00 |
? ? // -----------------------------------------------------------------
? ? // FOC0:強制輸出比較啟動
? ? // WGM01, WGM00: 工作模式選擇
? ? //? ?? ?? ?? ???00:普通模式,01:PWM相位修正,
? ? //? ?? ?? ?? ???10:比較匹配時清除計數器模式(CTC模式),11:快速PWM
? ? // COM01, COM00:比較匹配時的輸出模式
? ? //? ?? ?? ? WGMxx為普通模式或CTC模式時
? ? //? ?? ?? ?? ???00:OC0未連接,
? ? //? ?? ?? ?? ???01:OC0取反,
? ? //? ?? ?? ?? ???10:OC0清零,
? ? //? ?? ?? ?? ???11:OC0置位
? ? //? ?? ?? ? WGMxx為相位修正PWM模式
? ? //? ?? ?? ?? ???00:OC0未連接,
? ? //? ?? ?? ?? ???01:保留,
? ? //? ?? ?? ?? ???10:升序匹配時清零OC0;降序匹配時置位OC0,
? ? //? ?? ?? ?? ???11:升序匹配時置位OC0;降序匹配時清零OC0
? ? //? ?? ?? ? WGMxx為快速PWM模式
? ? //? ?? ?? ?? ???00:OC0未連接
? ? //? ?? ?? ?? ???01:保留
? ? //? ?? ?? ?? ???10:匹配時OC0清零;計數到TOP時OC0置位
? ? //? ?? ?? ?? ???11:匹配時OC0置位;計數到TOP時OC0清零
? ? // CS02,CS01,CS00:T/C0時鐘預分頻選擇
? ? //? ?? ?? ?? ???000:無時鐘,T/C不工作? ???001:1/1
? ? //? ?? ?? ?? ???010:1/8? ???011:1/32? ???100:1/64
? ? //? ?? ?? ?? ???101:1/128? ?110:1/256? ? 111:1/1024
? ? TCCR0 = 0;
? ? //TCNT0 T/C0計數寄存器,8位
? ? //OCR0 輸出比較寄存器,8位
? ? //TIMSK T/C中斷屏蔽寄存器
? ? // -----------------------------------------------------------------
? ? // | OCIE2 | TOIE2 | TICIE1| OCIE1A| OCIE1B| TOIE1 | OCIE0 | TOIE0 |
? ? // -----------------------------------------------------------------
? ? // OCIE2:T/C2輸出比較匹配中斷使能
? ? // TOIE2:T/C2溢出中斷使能
? ? // TICIE1:T/C1輸入捕捉中斷使能
? ? // OCIE1A:T/C1輸出比較A匹配中斷使能
? ? // OCIE1B:T/C1輸出比較B匹配中斷使能
? ? // TOIE1:T/C1溢出中斷使能
? ? // OCIE0:T/C0輸出比較匹配中斷使能
? ? // TOIE0:T/C0溢出中斷使能
? ? TIMSK = 0;
? ? //ETIMSK T/C擴展中斷屏蔽寄存器
? ? // -----------------------------------------------------------------
? ? // |? ?-? ?|? ?-? ?| TICIE3| OCIE3A| OCIE3B| TOIE3 | OCIE3C| OCIE1C|
? ? // -----------------------------------------------------------------
? ? // TICIE3:T/C3輸入捕捉中斷使能
? ? // OCIE3A:T/C3輸出比較A匹配中斷使能
? ? // OCIE3B:T/C3輸出比較B匹配中斷使能
? ? // TOIE3:T/C3溢出中斷使能
? ? // OCIE3C:T/C3輸出比較C匹配中斷使能
? ? // OCIE1C:T/C1輸出比較C匹配中斷使能
? ? ETIMSK = 0;
? ?
? ? //TIFR T/C中斷標志寄存器
? ? // -----------------------------------------------------------------
? ? // |??OCF2 |??TOV2 |??ICF1 | OCF1A | OCF1B |??TOV1 |??OCF0 |??TOV0 |
? ? // -----------------------------------------------------------------
? ? // OCF2:T/C2輸出比較匹配標志
? ? // TOV2:T/C2溢出標志
? ? // ICF1:T/C1輸入捕捉標志位
? ? // OCF1A:T/C1輸出比較A匹配標志位
? ? // OCF1B:T/C1輸出比較B匹配標志位
? ? // TOV1:T/C1溢出標志
? ? // OCF0:T/C0輸出比較匹配標志
? ? // TOV0:T/C0溢出標志
? ? //ETIFR 擴展的T/C中斷標志寄存器
? ? // -----------------------------------------------------------------
? ? // |? ?-? ?|? ?-? ?|??ICF3 | OCF3A | OCF3B |??TOV3 | OCF3C | OCF1C |
? ? // -----------------------------------------------------------------
? ? // ICF3:T/C3輸入捕捉匹配標志位
? ? // OCF3A:T/C3輸出比較A匹配標志位
? ? // OCF3B:T/C3輸出比較B匹配標志位
? ? // TOV3:T/C3溢出標志位
? ? // OCF3C:T/C3輸出比較C匹配標志位
? ? // OCF1C:T/C1輸出比較C匹配標志位
? ? //ASSR T/C0異步狀態寄存器
? ? // -----------------------------------------------------------------
? ? // |? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|??AS0??| TCN0UB| OCR0UB| TCR0UB|
? ? // -----------------------------------------------------------------
? ? // AS0:T/C0使用外部時鐘
? ? // TCN0UB:TCNT0更新中,寫TCNT0時將置位,為0時表明TCNT0可以寫入新值
? ? // OCR0UB:OCR0更新中,寫OCR0時將置位,為0表明OCR0可以寫入新值
? ? // TCR0UB:TCCR0更新中,寫TCCR0時將置位,為0表明TCCR0可以寫入新值
? ? ASSR = 0;
}
void init_timer2()
{? ?
? ? //TCCR2 T/C2控制寄存器
? ? // -----------------------------------------------------------------
? ? // |??FOC2 | WGM20 | COM21 | COM20 | WGM21 |??CS22 |??CS21 |??CS20 |
? ? // -----------------------------------------------------------------
? ? // FOC2:強制輸出比較啟動
? ? // WGM21, WGM20: 工作模式選擇
? ? //? ?? ?? ?? ???00:普通模式,01:PWM相位修正,
? ? //? ?? ?? ?? ???10:比較匹配時清除計數器模式(CTC模式),11:快速PWM
? ? // COM21, COM20:比較匹配時的輸出模式
? ? //? ?? ?? ? WGMxx為普通模式或CTC模式時
? ? //? ?? ?? ?? ???00:OC0未連接,
? ? //? ?? ?? ?? ???01:OC0取反,
? ? //? ?? ?? ?? ???10:OC0清零,
? ? //? ?? ?? ?? ???11:OC0置位
? ? //? ?? ?? ? WGMxx為相位修正PWM模式
? ? //? ?? ?? ?? ???00:OC0未連接,
? ? //? ?? ?? ?? ???01:保留,
? ? //? ?? ?? ?? ???10:升序匹配時清零OC0;降序匹配時置位OC0,
? ? //? ?? ?? ?? ???11:升序匹配時置位OC0;降序匹配時清零OC0
? ? //? ?? ?? ? WGMxx為快速PWM模式
? ? //? ?? ?? ?? ???00:OC0未連接
? ? //? ?? ?? ?? ???01:保留
? ? //? ?? ?? ?? ???10:匹配時OC0清零;計數到TOP時OC0置位
? ? //? ?? ?? ?? ???11:匹配時OC0置位;計數到TOP時OC0清零
? ? // CS22,CS21,CS20:T/C0時鐘預分頻選擇
? ? //? ?? ?? ?? ???000:無時鐘,T/C不工作? ???001:1/1
? ? //? ?? ?? ?? ???010:1/8? ???011:1/32? ???100:1/64
? ? //? ?? ?? ?? ???101:1/128? ?110:1/256? ? 111:1/1024
? ? TCCR2 = 0;
? ? //TCNT2 T/C2計數寄存器,8位
? ? //OCR2 T/C2比較寄存器,8位
}
void init_timer1()
{
? ? //TCCR1A T/C1控制寄存器A
? ? // -----------------------------------------------------------------
? ? // | COM1A1| COM1A0| COM1B1| COM1B0| COM1C1| COM1C0| WGM11 | WGM10 |
? ? // -----------------------------------------------------------------
? ? //TCCR1B T/C1控制寄存器B
? ? // -----------------------------------------------------------------
? ? // | ICNC1 | ICES1 |? ?-? ?| WGM13 | WGM12 |??CS12 |??CS11 |??CS10 |
? ? // -----------------------------------------------------------------
? ? //TCCR1C T/C1控制寄存器C
? ? // -----------------------------------------------------------------
? ? // | FOC1A | FOC1B | FOC1C |? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|
? ? // -----------------------------------------------------------------
? ? // COM1A1,COM1A0:通道A的比較輸出模式
? ? // COM1B1,COM1B0:通道B的比較輸出模式
? ? // COM1C1,COM1C0:通道C的比較輸出模式
? ? // WGM13,WGM12,WGM11,WGM10:波型發生模式:
? ? //? ?? ?? ?? ???比較輸出模式(CTC模式),非PWM
? ? //? ?? ?? ?? ?? ?? ?00??普通端口操作,OC1A/OC1B/OC1C未連接
? ? //? ?? ?? ?? ?? ?? ?01??比較匹配時OC1A/OC1B/OC1C電平取反
? ? //? ?? ?? ?? ?? ?? ?10??比較匹配時清零OC1A/OC1B/OC1C(輸出低電平)
? ? //? ?? ?? ?? ?? ?? ?11??比較匹配時置位OC1A/OC1B/OC1C(輸出高電平)
? ? //? ?? ?? ?? ???比較輸出模式(CTC模式),快速PWM
? ? //? ?? ?? ?? ?? ?? ?00??普通端口操作,OC1A/OC1B/OC1C未連接
? ? //? ?? ?? ?? ?? ?? ?01??WGM13為0時同上,為1時比較匹配時 OC1A電平取反,OC1B/OC1C保留
? ? //? ?? ?? ?? ?? ?? ?10??比較匹配時OC1A/OC1B/OC1C清零,在TOP時OC1A/OC1B/OC1C置位
? ? //? ?? ?? ?? ?? ?? ?11??比較匹配時OC1A/OC1B/OC1C置位,在TOP時OC1A/OC1B/OC1C清零
? ? //? ?? ?? ?? ???比較輸出模式(CTC模式),相位修正及相頻修正PWM
? ? //? ?? ?? ?? ?? ?? ?00??普通端口操作,OC1A/OC1B/OC1C未連接
? ? //? ?? ?? ?? ?? ?? ?01??WGM13為0:同上,為1時比較匹配時 OC1A電平取反,OC1B/OC1C保留
? ? //? ?? ?? ?? ?? ?? ?10??升序計數匹配時將OC1A/OC1B/OC1C清零,降序計數匹配時將OC1A/OC1B/OC1C置位
? ? //? ?? ?? ?? ?? ?? ?11??升序計數匹配時將OC1A/OC1B/OC1C置位,降序計數匹配時將OC1A/OC1B/OC1C清零
? ? //
? ? //? ?模式 WGM1x? ?工作模式說明? ???TOP? ?OCR1x更新時刻??TOVn置位時刻
? ? //? ???0? ?0000? ?? ? 普通模式? ? 0xFFFF? ?? ???立即? ?? ?? ?? ?MAX
? ? //? ???1? ?0001? ?8位相位修正PWM??0x00FF? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ???2? ?0010? ?9位相位修正PWM??0x01FF? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ???3? ?0011??10位相位修正PWM??0x03FF? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ???4? ?0100? ?? ?? ?? ???CTC? ?OCRnA? ?? ???立即? ?? ?? ?? ?MAX
? ? //? ???5? ?0101? ?? ? 8位快速PWM??0x00FF? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? //? ???6? ?0110? ?? ? 9位快速PWM??0x01FF? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? //? ???7? ?0111? ?? ?10位快速PWM??0x03FF? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? //? ???8? ?1000??相位頻率修正PWM? ? ICRn? ?? ?BOTTOM? ?? ?? ?BOTTOM
? ? //? ???9? ?1001??相位頻率修正PWM? ?OCRnA? ?? ?BOTTOM? ?? ?? ?BOTTOM
? ? //? ? 10? ?1010? ?? ?相位修正PWM? ? ICRn? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ? 11? ?1011? ?? ?相位修正PWM? ?OCRnA? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ? 12? ?1100? ?? ?? ?? ???CTC? ? ICRn? ?? ???立即? ?? ?? ?? ?MAX
? ? //? ? 13? ?1101? ?? ?? ?? ? 保留? ?? ?-? ?? ?? ? -? ?? ?? ?? ?? ?-
? ? //? ? 14? ?1110? ?? ?? ? 快速PWM? ? ICRn? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? //? ? 15? ?1111? ?? ?? ? 快速PWM? ?OCRnA? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? // ICNC1:使能/禁止輸入捕捉噪聲抑制器
? ? // ICES1:輸入捕獲觸發沿選擇,0為下降沿觸發,1為上升沿觸發
? ? // CS12,CS11,CS10:T/C0時鐘預分頻選擇
? ? //? ?? ?? ?? ???000:無時鐘,T/C不工作? ???001:1/1
? ? //? ?? ?? ?? ???010:1/8? ???011:1/64? ???100:1/256
? ? //? ?? ?? ?? ???101:1/1024??110:外部T1腳下降沿驅動? ? 111:外部T1腳上升沿驅動
? ? // FOC1A,FOC1B,FOC1C:強制輸出比較通道A,B,C
? ? TCCR1A = TCCR1B = TCCR1C = 0;
? ? //TCNT1H,TCNT1L 定時/計數器1
? ? //OCR1AH,OCR1AL 輸出比較寄存器1A
? ? //OCR1BH,OCR1BL 輸出比較寄存器1B
? ? //OCR1CH,OCR1CL 輸出比較寄存器1C
? ? //ICR1H,ICR1L 輸入捕捉寄存器1
}
void init_timer3()
{
? ? //TCCR3A T/C3控制寄存器A
? ? // -----------------------------------------------------------------
? ? // | COM3A1| COM3A0| COM3B1| COM3B0| COM3C1| COM3C0| WGM31 | WGM30 |
? ? // -----------------------------------------------------------------
? ? //TCCR3B T/C3控制寄存器B
? ? // -----------------------------------------------------------------
? ? // | ICNC3 | ICES3 |? ?-? ?| WGM33 | WGM32 |??CS32 |??CS31 |??CS30 |
? ? // -----------------------------------------------------------------
? ? //TCCR3C T/C3控制寄存器C
? ? // -----------------------------------------------------------------
? ? // | FOC3A | FOC3B | FOC3C |? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|
? ? // -----------------------------------------------------------------
? ? // COM3A1,COM3A0:通道A的比較輸出模式
? ? // COM3B1,COM3B0:通道B的比較輸出模式
? ? // COM3C1,COM3C0:通道C的比較輸出模式
? ? // WGM33,WGM32,WGM31,WGM30:波型發生模式:
? ? //? ?? ?? ?? ???比較輸出模式(CTC模式),非PWM
? ? //? ?? ?? ?? ?? ?? ?00??普通端口操作,OC3A/OC3B/OC3C未連接
? ? //? ?? ?? ?? ?? ?? ?01??比較匹配時OC3A/OC3B/OC3C電平取反
? ? //? ?? ?? ?? ?? ?? ?10??比較匹配時清零OC3A/OC3B/OC3C(輸出低電平)
? ? //? ?? ?? ?? ?? ?? ?11??比較匹配時置位OC3A/OC3B/OC3C(輸出高電平)
? ? //? ?? ?? ?? ???比較輸出模式(CTC模式),快速PWM
? ? //? ?? ?? ?? ?? ?? ?00??普通端口操作,OC3A/OC3B/OC3C未連接
? ? //? ?? ?? ?? ?? ?? ?01??WGM13為0時同上,為1時比較匹配時 OC3A電平取反,OC3B/OC3C保留
? ? //? ?? ?? ?? ?? ?? ?10??比較匹配時OC3A/OC3B/OC3C清零,在TOP時OC3A/OC3B/OC3C置位
? ? //? ?? ?? ?? ?? ?? ?11??比較匹配時OC3A/OC3B/OC3C置位,在TOP時OC3A/OC3B/OC3C清零
? ? //? ?? ?? ?? ???比較輸出模式(CTC模式),相位修正及相頻修正PWM
? ? //? ?? ?? ?? ?? ?? ?00??普通端口操作,OC3A/OC3B/OC3C未連接
? ? //? ?? ?? ?? ?? ?? ?01??WGM13為0:同上,為1時比較匹配時 OC3A電平取反,OC3B/OC3C保留
? ? //? ?? ?? ?? ?? ?? ?10??升序計數匹配時將OC3A/OC3B/OC3C清零,降序計數匹配時將OC3A/OC3B/OC3C置位
? ? //? ?? ?? ?? ?? ?? ?11??升序計數匹配時將OC3A/OC3B/OC3C置位,降序計數匹配時將OC3A/OC3B/OC3C清零
? ? //
? ? //? ?模式 WGM3x? ?工作模式說明? ???TOP? ?OCR1x更新時刻??TOVn置位時刻
? ? //? ???0? ?0000? ?? ? 普通模式? ? 0xFFFF? ?? ???立即? ?? ?? ?? ?MAX
? ? //? ???1? ?0001? ?8位相位修正PWM??0x00FF? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ???2? ?0010? ?9位相位修正PWM??0x01FF? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ???3? ?0011??10位相位修正PWM??0x03FF? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ???4? ?0100? ?? ?? ?? ???CTC? ?OCRnA? ?? ???立即? ?? ?? ?? ?MAX
? ? //? ???5? ?0101? ?? ? 8位快速PWM??0x00FF? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? //? ???6? ?0110? ?? ? 9位快速PWM??0x01FF? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? //? ???7? ?0111? ?? ?10位快速PWM??0x03FF? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? //? ???8? ?1000??相位頻率修正PWM? ? ICRn? ?? ?BOTTOM? ?? ?? ?BOTTOM
? ? //? ???9? ?1001??相位頻率修正PWM? ?OCRnA? ?? ?BOTTOM? ?? ?? ?BOTTOM
? ? //? ? 10? ?1010? ?? ?相位修正PWM? ? ICRn? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ? 11? ?1011? ?? ?相位修正PWM? ?OCRnA? ?? ?? ?TOP? ?? ?? ?BOTTOM
? ? //? ? 12? ?1100? ?? ?? ?? ???CTC? ? ICRn? ?? ???立即? ?? ?? ?? ?MAX
? ? //? ? 13? ?1101? ?? ?? ?? ? 保留? ?? ?-? ?? ?? ? -? ?? ?? ?? ?? ?-
? ? //? ? 14? ?1110? ?? ?? ? 快速PWM? ? ICRn? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? //? ? 15? ?1111? ?? ?? ? 快速PWM? ?OCRnA? ?? ?? ?TOP? ?? ?? ?? ?TOP
? ? // ICNC3:使能/禁止輸入捕捉噪聲抑制器
? ? // ICES3:輸入捕獲觸發沿選擇,0為下降沿觸發,1為上升沿觸發
? ? // CS32,CS31,CS30:T/C0時鐘預分頻選擇
? ? //? ?? ?? ?? ???000:無時鐘,T/C不工作? ???001:1/1
? ? //? ?? ?? ?? ???010:1/8? ???011:1/64? ???100:1/256
? ? //? ?? ?? ?? ???101:1/1024??110:外部T1腳下降沿驅動? ? 111:外部T1腳上升沿驅動
? ? // FOC3A,FOC3B,FOC3C:強制輸出比較通道A,B,C
? ? TCCR3A = TCCR3B = TCCR3C = 0;
? ? //TCNT3H,TCNT3L 定時/計數器3
? ? //OCR3AH,OCR3AL 輸出比較寄存器3A
? ? //OCR3BH,OCR3BL 輸出比較寄存器3B
? ? //OCR3CH,OCR3CL 輸出比較寄存器3C
? ? //ICR3H,ICR3L 輸入捕捉寄存器3
}
void init_uart(void)
{
? ? //UDRn USART I/O數據寄存器, 不可用讀修改寫命令操作, 否則會改變FIFO狀態
? ? //UCSRnA USART控制和狀態寄存器A
? ? // -----------------------------------------------------------------
? ? // |??RXCn |??TXCn | UDREn |??FEn??|??DORn |??UPEn |??U2Xn | MPCMn |
? ? // -----------------------------------------------------------------
? ? // RXCn:USART接收結束標志
? ? // TXCn:USART發送結束標志,寫1可清除
? ? // UDREn:USART數據寄存器為空標志,只有該標志為1才數據才可寫入UDR0
? ? // FEn:幀錯誤,未正確收到停止位
? ? // DORn:數據過速
? ? // UPEn:奇偶效驗錯誤
? ? // U2Xn:倍速發送,僅對異步操作有影響
? ? // MPCMn:多處理器通訊模式
? ? //UCSRnB USART控制和狀態寄存器B
? ? // -----------------------------------------------------------------
? ? // | RXCIEn| TXCIEn| UDRIEn| RXENn | TXENn | UCSZn2| RXB8n | TXB8n |
? ? // -----------------------------------------------------------------
? ? // RXCIEn:接收結束中斷使能
? ? // TXCIEn:發送結束中斷使能
? ? // UDRIEn:USART數據寄存器空中使能
? ? // RXENn:接收使能
? ? // TXENn:發送使能
? ? // UCSZn2:字符長度,具體見下面
? ? // RXB8n:接收數據位8
? ? // TXB8n:發送數據位8
? ? //UCSRxC USART控制和狀態寄存器C
? ? // -----------------------------------------------------------------
? ? // |? ?-? ?| UMSELn| UPMn1 | UPMn0 | USBSn | UCSZn1| UCXZn0| UCPOLn|
? ? // -----------------------------------------------------------------
? ? // UMSELn:模式選擇,0為異步操作,1為同步操作
? ? // UPMn1,UPMn0:奇偶效驗模式,00禁止,01保留,10偶效驗,11奇校驗
? ? // USBSn:停止位選擇,0為1位停止位,1為2位停止位
? ? // UCSZn2,UCSZn0:字符長度,000為5位, 001為 6位,010為7位, 011為8位
? ? //? ?? ?? ?? ?? ?? ?? ?? ? 100為保留,101為保留,110為保留,111為9位
? ? // UCPOLn:時鐘極性,(異步模式應清零)
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?UCPOL0? ?發送數據位置? ?接收數據位置
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???0? ?? ???XCK0上升沿? ? XCK0下降沿
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???1? ?? ???XCK0下降沿? ? XCK0上升沿
? ? //UBRRnL和UBRRnH USART波特率寄存器, UBRRnH15:12為保留位:
? ? // -----------------------------------------------------------------
? ? // |? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?| BIT11 | BIT10 | BIT09 | BIT08 |
? ? // -----------------------------------------------------------------
? ? // -----------------------------------------------------------------
? ? // | BIT07 | BIT06 | BIT05 | BIT04 | BIT03 | BIT02 | BIT01 | BIT00 |
? ? // -----------------------------------------------------------------
}? ?
void init_spi(void)
{
? ? //SPCR SPI控制寄存器
? ? // -----------------------------------------------------------------
? ? // |??SPIE |??SPE??|??DORD |??MSTR |??CPOL |??CPHA |??SPR1 | SPR0??|
? ? // -----------------------------------------------------------------
? ? // SPIE:SPI中斷使能
? ? // SPE:SPI使能
? ? // DORD:數據次序,為1時LSB先發送
? ? // MSTR:是否主機模式,若為主機模式,SS引腳配置為輸入,但被拉低則MSTR被清零
? ? // SPSR的SPIF位置位。用戶必須重新設置MSTR位進入主機模式。
? ? // CPOL:時鐘極性,為1時表示空閑時SCK為高電平,否則為低電平。
? ? // CPHA:時鐘相位,為0時為時鐘的起始沿采樣數據,否則為終止沿采樣數據
? ? // SPR1,SPR0:SPI時鐘速率選擇:00??1/4, 01??1/16, 10??1/64, 11??1/128
? ? //SPSR SPI狀態寄存器
? ? // -----------------------------------------------------------------
? ? // |??SPIF |??WCOL |? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?| SPI2X |
? ? // -----------------------------------------------------------------
? ? // SPIF:SPI中斷標志,串行發送結束后此位置位,對于查詢方式,可先讀SPSR,緊著
? ? //? ?? ? 訪問SPDR來對SPIF位清零。
? ? // WCOL:寫沖突標志,可通過先讀SPSR,緊接著訪問SPDR來清零。
? ? // SPI2X:SPI倍速,若為主機,SCK最高頻率可達CPU頻率一半,從機則只能保證為1/4
? ?
? ? //SPDR SPI數據寄存器
? ? // -----------------------------------------------------------------
? ? // |??MSB??|? ?? ? |? ?? ? |? ?? ? |? ?? ? |? ?? ? |? ?? ? |??LSB??|
? ? // -----------------------------------------------------------------
? ? // SPDR為可讀寫寄存器,寫則將啟動數據傳輸,讀則讀取接收緩沖器
}? ?
void init_twi(void)
{
? ? //TWBR TWI比特率寄存器
? ? // -----------------------------------------------------------------
? ? // |??BIT7 |??BIT6 |??BIT5 |??BIT4 |??BIT3 |??BIT2 |??BIT1 |??BIT0 |
? ? // -----------------------------------------------------------------
? ? // SCL頻率 = CUP時鐘頻率/(16 + 2 * TWBR * 4 ^ TWPS)
? ? // TWBR值應該不小于10, TWPS為預分頻值
? ? //TWCR TWI控制寄存器
? ? // -----------------------------------------------------------------
? ? // | TWINT |??TWEA | TWSTA | TWSTO |??TWWC |??TWEN |? ?-? ?|??TWIE |
? ? // -----------------------------------------------------------------
? ? // TWINT:TWI中斷標志,TWINT標志必須由軟件寫1清除, 即使在中斷服務程序中硬件也不會自動清除
? ? //? ?? ???在清除TWI標志前一定要首先完成對TWAR TWSR TWDR的訪問, 此位清零后TWI立即開始工作。
? ? // TWEA:使能TWI應答,此位控制應答脈沖的產生。
? ? // TWSTA:START狀態位,自己想成為主機時置此位,發送START后軟件必須清零TWSTA。
? ? // TWSTO:STOP狀態位。主模式下,置此位將在總線上產生STOP狀態,后TWSTO自動清零;從機模式下
? ? //? ?? ???置此位可使接口從錯誤狀態恢復到未被尋址的狀態,此時總線上不會產生STOP狀態。
? ? // TWWC:TWI寫沖突標志。每次寫TWDR時都將更新此標志。
? ? // TWEN:TWI使能位。置1時TWI引腳將從IO引腳切換到SCL和SDA引腳。
? ? // TWIE:TWI中斷使能。
? ?
? ? //TWSR TWI狀態寄存器
? ? // -----------------------------------------------------------------
? ? // |??TWS7 |??TWS6 |??TWS5 |??TWS4 |??TWS3 |? ?-? ?| TWPS1 | TWPS0 |
? ? // -----------------------------------------------------------------
? ? // TWS7~TWS3:TWI狀態
? ? // TWPS1~TWPS0:TWI預分頻值。00:1; 01:1/4; 10:1/16; 11:1/64。
? ?
? ? //TWDR TWI數據寄存器
? ? // -----------------------------------------------------------------
? ? // |??BIT7 |??BIT6 |??BIT5 |??BIT4 |??BIT3 |??BIT2 |??BIT1 |??BIT0 |
? ? // -----------------------------------------------------------------
? ? // 發送模式,TWDR中包含了要發送的字節,接收模式TWDR包含了接收到的數據。
? ? // 只要TWINT置位,TWDR的數據就是穩定的。
? ? //TWAR TWI從機地址寄存器
? ? // -----------------------------------------------------------------
? ? // |??TWA6 |??TWA5 |??TWA4 |??TWA3 |??TWA2 |??TWA1 |??TWA0 | TWGCE |
? ? // -----------------------------------------------------------------
? ? // TWA6~TWA0:TWI從機地址寄存器
? ? // TWGCE:使能TWI廣播識別
}
? ? //GICR 通用中斷控制寄存器
? ? // -----------------------------------------------------------------
? ? // |??INT1 |??INT0 |??INT2 |? ?-? ?|? ?-? ?|? ?-? ?| IVSEL |??IVCE |
? ? // -----------------------------------------------------------------
? ? // INT1:使能外部中斷1請求
? ? // INT0:使能外部中斷0請求
? ? // INT2:使能外部中斷2請求
? ? // IVSEL:中斷向量選擇,為0時中斷向量位于FLASH起始地址,為1時位于BOOT區起始地址
? ? // IVCE:中斷向量修改使能。改變IVSEL時IVCE必須置位。
? ? //MCUCR MCU控制寄存器
? ? // -----------------------------------------------------------------
? ? // |??SM2??|? ?SE??|??SM1??|??SM0??| ISC11 | ISC10 | ISC01 | ISC00 |
? ? // -----------------------------------------------------------------
? ? // SM2, SM1, SM0:000:空閑模式??
? ? //? ?? ?? ?? ?? ? 001:ADC噪聲抑制模式
? ? //? ?? ?? ?? ?? ? 010:掉電模式
? ? //? ?? ?? ?? ?? ? 011:省電模式
? ? //? ?? ?? ?? ?? ? 100:保留
? ? //? ?? ?? ?? ?? ? 101:保留
? ? //? ?? ?? ?? ?? ? 110:Standby模式
? ? //? ?? ?? ?? ?? ? 111:擴展Standby模式
? ? //SE:休眠使能
? ? //ISC11, ISC10: 00:INT1為低電平時產生中斷請求
? ? //? ?? ?? ?? ?? ?01:INT1引腳上任意的邏輯電平變化都將引發中斷
? ? //? ?? ?? ?? ?? ?10:INT1的下降沿產生異步中斷請求
? ? //? ?? ?? ?? ?? ?11:INT1的上升沿產生異步中斷請求
? ? //ISC01, ISC00:??00:INT0為低電平時產生中斷請求
? ? //? ?? ?? ?? ?? ?01:INT0引腳上任意的邏輯電平變化都將引發中斷
? ? //? ?? ?? ?? ?? ?10:INT0的下降沿產生異步中斷請求
? ? //? ?? ?? ?? ?? ?11:INT0的上升沿產生異步中斷請求
? ? //MCUCSR MCU控制和狀態寄存器
? ? // -----------------------------------------------------------------
? ? // |??JTD??|? ?-? ?|? ?-? ?|??JTRF |??WDRF |??BORF | FXTRF |??PORF |
? ? // -----------------------------------------------------------------
? ? // JTD:
? ? // JTRF:JTAG復位標志
? ? // WDRF:看門狗復位標志
? ? // BORF:掉電檢測復位標志
? ? // EXTRF:外部復位標志
? ? // PORF:上電復位標志
? ? //WDTCR 看門狗定時器控制寄存器
? ? // -----------------------------------------------------------------
? ? // |? ?-? ?|? ?-? ?|? ?-? ?|??WDCE |??WDE??|??WDP2 |??WDP1 |??WDP0 |
? ? // -----------------------------------------------------------------
? ? // WDCE:看門狗修改使能,清零WDE位時必須先置位WDCE位,否則不能禁止看門狗
? ? // WDE:看門狗使能,只有WDCE為1時WDE才能清零
? ? // WDP2~WDP0:看門狗定時器預分頻值? ?WDT振蕩周期??VCC=3V時溢出時間??VCC=5V時溢出時間
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ? 000:? ???16K? ?? ?? ?? ?14.8ms? ?? ?? ?? ?14.0ms
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ? 001:? ???32K? ?? ?? ?? ?29.6ms? ?? ?? ?? ?28.1ms
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ? 010:? ???64K? ?? ?? ?? ?59.1ms? ?? ?? ?? ?56.2ms
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ? 011:? ? 128K? ?? ?? ?? ? 0.12s? ?? ?? ?? ? 0.11s
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ? 100:? ? 256K? ?? ?? ?? ? 0.24s? ?? ?? ?? ? 0.22s
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ? 101:? ? 512K? ?? ?? ?? ? 0.47s? ?? ?? ?? ? 0.45s
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ? 110:? ?1024K? ?? ?? ?? ? 0.95s? ?? ?? ?? ? 0.9s
? ? //? ?? ?? ?? ?? ?? ?? ?? ?? ? 111:? ?2048K? ?? ?? ?? ? 1.9s? ?? ?? ?? ???1.8s
? ? //EEARH/EEARL EEPROM地址寄存器
? ? //EEARH
? ? // -----------------------------------------------------------------
? ? // |? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?| EEAR11| EEAR10| EEAR9 | EEAR8 |
? ? // -----------------------------------------------------------------
? ? //EEARL
? ? // -----------------------------------------------------------------
? ? // | EEAR7 | EEAR6 | EEAR5 | EEAR4 | EEAR3 | EEAR2 | EEAR1 | EEAR0 |
? ? // -----------------------------------------------------------------
? ? //EEPROM地址,在訪問EEPROM前必須為其賦予正確的數據
? ? //EEDR EEPROM數據寄存器? ?
? ? // -----------------------------------------------------------------
? ? // |??MSB??|??...??|??...??|??...??|??...??|??...??|??...??|??LSB??|
? ? // -----------------------------------------------------------------
? ?
? ? //EECR EEPROM控制寄存器
? ? // -----------------------------------------------------------------
? ? // |? ?-? ?|? ?-? ?|? ?-? ?|? ?-? ?| EERIE | EEMWE |??EEWE |??EERE |
? ? // -----------------------------------------------------------------
? ? //EERIE:EEPROM就緒中斷使能
? ? //EEMWE:EEPROM主機寫使能,當此位為1時,在4個時鐘內EEWE置位,數據將寫入EEPROM
? ? //? ?? ?? ? EEMWE置位4個時鐘后硬件將其清零
? ? //EEWE:EEPROM寫使能
? ? //EERE:EEPROM讀使能。當EEPROM地址設置好后,需置位EERE以便將數據讀入EEAR
? ? //EEPROM寫時序:
? ? //a等待EEWE位為0
? ? //b等待SPMCSR的SPMEN位為0,此步只在軟件包含引導程序,且允許CPU對Flash編程時才有用
? ? //c將新的EEPROM地址寫入EEAR
? ? //d將新的EEPROM數據寫入EEDR
? ? //e對EECR的EEMWE位寫1,同時清零EEWE位
? ? //f在置位EEMWE位的4個周期內置位EEWE位
------------------------------------------------------------------------------------------------------
七、AVR移位算法詳細解釋(1<<X)
很多初學者都會被移位算法迷惑,移位算法形如(1<<X)這樣的形式,高手寫程序時,習慣用移位算法來寫出各個寄存器的使用。比如下面一段是AVR 的USART 的初始化代碼。
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
UCSR0B = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);?// RXCIE=1;TXCIE=1;UDREIE=0;RXEN=1;TXEN=1
這樣的寫法對高手是福,這些代碼里面說明了操作了寄存器的哪些位,能夠看出它的操作的意義;對新手確是禍害,因為新手看不懂這樣的程序。
回到開始的地方,解釋一下,什么是移位算法:
如:A = (1<<2),1寫成二進制就是0000 0001,這個一左移2位就是0000 0100,所以得到的數A為0000 0100,即0x04。
再如:B = (2<<4),2寫成二進制就是0000 0010,這個一左移4位就是0010 0000,所以得到的數B為0010 0000,即0x20。
上面兩個移位算法都是正確的,第一種寫法,表示第三位為1其余都是0的數,數的時候是從0數起的,再比如(1<<0)表示的是0000 0001,(1<<7)表示的是1000 0000,但是第二種寫法沒有沒有這種意義,移位也用于乘除法,左移一位乘以2,右移移位除以2,上面的第二種寫法2左移四位得到的數是2×2×2×2×2=32,也就是上面的0x20。
我們再來看上面的這句話:UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
UCSRC是一個和串口通訊有關的一個八位寄存器,他的每一位都有特殊的定義,我們通過查數據手冊可以看到,如下的內容。
我們在程序中包含的頭文件iom16v.h類似的文件會有#define URSEL 7 這樣的定義,1<<URSEL即是位7,1<<UCSZ1選擇位2,1<<UCSZ0選擇位1,整句話UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);的效果就是讓UCSRC的位七,位二,位一為高,其他都為低,然后在數據手冊里面你可以看到各個位的作用。UCSRC = (1<<7)|(1<<2)|(1<<1) 即UCSRC = 1000 0110。
------------------------------------------------------------------------------------------------------
總結
以上是生活随笔為你收集整理的AVR单片机及其开发环境的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RabbitMQ部署安装
- 下一篇: 技术总结一