AVR1000XMEGA的C语言代码编写入门Word下载.docx
《AVR1000XMEGA的C语言代码编写入门Word下载.docx》由会员分享,可在线阅读,更多相关《AVR1000XMEGA的C语言代码编写入门Word下载.docx(22页珍藏版)》请在冰豆网上搜索。
C-代码名
-Bitandgroupmasks
位与组掩码
-Groupconfigurationmasks
组配置掩码
•Methodsforaccessingregisters
访问寄存器的方法
•Methodsforwritingreusablemodulefunctions
可多次使用模块功能的写入方法
1Introduction
引言
Shortdevelopmenttimesandhighqualityrequirementsonelectronicproductshasmadehigh-levelprogramminglanguagesarequirement.ThemainreasonisthatHighlevellanguagesmakeiteasiertomaintainandreusecodeduetobetterportabilityandreadability.
由于电子产品的开发时间短,质量要求高,因此需要高层次的编程语言。
最主要的原因是,高级语言具有更好的可移植性和可读性,使其更易于维护和重复使用代码。
Thechoiceofprogramminglanguagealonedoesnotensurehighreadabilityandreusability;
goodcodingstyledoes.ThereforetheXMEGA™peripherals,headerfilesanddriversaredesignedwiththisinmind.
编程语言的选择本身并非是能确保具有较高的可读性和可重复使用性的唯一条件,还必须有良好的编码风格。
因此XMEGA™的外围设备,头文件和驱动程序的设计都是基于这方面考虑的。
Themostwidelyusedhigh-levellanguageforAVR®
microcontrollersisC,andthisapplicationnotethereforefocusesonCprogramming.TosupportmostoftheAVRCcompilersthatareavailable,thecodeexamplesareasfaraspossiblewritteninANSIC.AfewexamplesarespecifictoIAREmbeddedWorkbench®
buttheideasandmethodscanbeusedforothercompilerswithminorchanges.IARspecificexamplesareclearlymarked.
AVR®
微控制器使用的最广泛的高级语言就是C语言,因此本应用注释的重点是C语言编程。
为了支持大多数可用的AVRC语言编译器,我们尽可能把代码示例编写在ANSIC语言的规范中。
有些例子是IAREmbeddedWorkbench®
专用的,但其思路和方法可用于与其他变化不大的编译器。
IAR专用的示例都有清晰的标示。
2XMEGAModules
XMEGA模块
AnAVRXMEGAiscomposedofseveralbuildingblocks:
AnAVRCPUcore,SRAM,Flash,EEPROMandanumberofperipheralmodules.Thesebuildingblocksarecalled“moduletypes”.AnXMEGAcanhaveoneormoreinstancesofagivenmoduletype.Allinstancesofamoduletypehavethesamefeaturesandfunctions.
一个AVRXMEGA由数个结构块组成:
一个AVRCPU芯片,一个SRAM,一个闪存,一个EEPROM以及若干外设模块。
这些结构块被称为“模块类型”。
XMEGA可以有一个或多个给定模块类型的实例。
一个模块类型的所有实例都具有相同的特性和功能。
Somemoduletypescanbeasubsetofothermoduletypes.Theseinheritasubsetofthefeatures(andregisters)ofthesupertype,allinheritedfeaturesarefullycompatible.Thisappliestoe.g.timersandIOports.Thesubsetofamoduletypecanforatimermeanthatithasfewercompareandcapturechannelsthanafulltimermodule.Similarly,anIOportmayhavelessthaneightpins.
有些模块类型可以是其他模块类型的子集。
这些(模块类型)继承了特大模块类型的某个子集的特征(和寄存器),其继承的所有特征都完全兼容。
这适用于比如计时器和IO端口。
用于计时器的模块类型的子集可能意味着它所能得到的比较和捕获通道比完整的计时器模块的要少。
同样,一个IO端口的管脚可能不足八个。
Amoduletypecanbea“USART”,whilethemoduleinstanceise.g.“USARTC0”,wherethe“C0”suffixindicatestheinstanceis“USARTnumber0onportC”.Forsimplicity,amoduleinstancewillbereferredtoasamodulethroughoutthisdocument,unlessthereisaneedtodifferentiate.
一个模块类型可以是“USART”的,如果这个模块实例比如是“USARTC0”,其中的“C0”后缀表示这个实例是“端口C上的USART编号为0”。
为了简单起见,一个模块实例将被称为这整个文件中的一个模块,除非是有必要另作区分。
Eachmodulehasanumberofregistersthatcontaincontrolorstatusbits.Allmodulesofagiventypecontainthesameset(orsubset)ofregisters,andalltheseregisterscontainthesameset(orsubset)ofcontrolandstatusbits.
每个模块都有若干寄存器,这些寄存器都包含控制位或状态位。
一个给定类型的所有模块都包含相同的寄存器集合(或子集),并且所有这些寄存器包含相同的控制位和状态位的集合(或子集)。
Figure2-1.Moduletypes,instances,registersandbits.
图2-1.模块类型,实例,寄存器和位
EachmodulehasafixedbaseaddressintheIOmemorymapandallregisterscontainedinthemodulehavefixedoffsetaddressesrelativetothemodulebaseaddress.ThiswayeachregisterwillnotonlyhaveanabsoluteaddressintheIOmemoryspace,butalsoarelativeaddressdefinedbyitsoffset.Theregisteroffsetaddressesareequalforallinstancesofamoduletype,simplifyingthetaskofwritingdriversthatcanbeusedforallmodulesofaspecifictype.
在IO内存图里,每个模块都有一个固定的基础地址,并且该模块中的所有寄存器都有固定的偏移地址(这是相对于模块的基地址而言)。
如此这样,每个寄存器不仅会在IO内存空间有一个绝对地址,而且还有一个根据其偏移量定义的相对地址。
一个模块类型的所有实例中的寄存器偏移地址都是平等的,这样就简化了编写能够适用于某个特定类型的所有模块的驱动程序的任务。
2.1RegisterNamingConvention
2.1.寄存器命名约定
Registerareroughlyspeakingdividedintocontrol,statusanddataregistersandthenamingofregistersreflectthis.Ageneral-purposecontrolregisterofthemoduleisnamedCTRL.Ifmultiplegeneral-purposecontrolregistersexistsinamoduletheyhaveasuffixcharacter.InthiscasethecontrolregisterswouldbenamedCTRLA,CTRLB,CTRLCandsoon.ThisalsoappliestoSTATUSregisters.
大致说来,寄存器有控制寄存器、状态寄存器和数据寄存器之分,这从寄存器的命名就可看出。
模块的一个通用的控制寄存器被命名为CTRL。
如果在一个模块中存在多个通用控制寄存器,他们都有一个后缀字符。
在这种情况下,控制寄存器将被命名为CTRLA、CTRLB、CTRLC等。
这方法也适用于状态寄存器。
Forregistersthathaveaspecificfunctionthenamereflectsthisfunctionality.Forexample,acontrolregisterthatcontrolstheinterruptlevelofamoduleisnamedINTCTRL.
对于具有特定功能的的寄存器,它们的命名会反映其功能性。
例如,一个控制寄存器,控制一个模块的中断级别,它就被命名为INTCTRL。
SincetheAVRdatabuswidthis8bit,largerregistersareimplementedusingseveral8-bitregisters.Fora16-bitregister,thehighandlowbytesareaccessedbyappending“H”and“L”respectivelytotheregistername.Forexample,the16-bitTimer/CountercountregisterisnamedCNT.ThetwobytesarenamedCNTLandCNTH.
由于AVR的数据总线宽度为8位,较大的寄存器得使用几个8位寄存器才能生效。
对于一个16位寄存器,要访问其高8位元组和低8位元组,得在这个寄存器的命名上分别附加“H”和“L”。
例如,16位计时器/计数器的计数寄存器被命名为CNT,其两个8位元组就被命名为CNTL和CNTH。
Foraregisterlargerthan16bit,thebytesarenumberedfromtheleastsignificantbyte.Forexample,the32-bitADCcalibrationregisterisnamedCAL.ThefourbytesarenamedCAL0,CAL1,CAL2andCAL3(fromleasttomostsignificantbyte).
对于大于16位的寄存器,其8位元组的编号是从最低有效的8位元组开始。
例如,32位的ADC校准寄存器被命名为CAL,其四个8位元组(从最低到最高有效8位元组)就被分别命名为CAL0,CAL1,CAL2和CAL3。
MostCcompilersofferautomatichandlingofaccesstomulti-byteregisters.InthatcasethenameCNT,without“H”or“L”suffix,couldbeusedtoperforma16-bitaccesstotheTimer/Countercountregister.Thisisalsothecasefor32-bitregisters.
大多数C语言编译器都提供了自动处理多8位元组寄存器的访问。
在这种情况下,CNT的命名没有加“H”或“L”后缀的,可以用来执行16位的计时器/计数器的计数寄存器的访问。
这方法也同样使用于32位寄存器。
2.2BitNamingConvention
2.2位命名约定
Registerbitscanhaveanindividualfunctionorbepartofabitgroupthathaveajointfunction:
Anindividualbitcouldbeabitthatenablesamodule,e.g.theUSARTENABLEbit.Abitgroupcanconsistoftwoofmorebitsthatjointlyselectaspecificconfigurationofthemodulethattheybelongto.Abitgroupoffersupto2nselections,wherenisthenumberofbitsinthebitgroup.ThetwobitsthatcontroltheUSARTReceiveCompleteinterruptlevel,RXINTLVL[1:
0],isanexampleofabitgroup.Thesetwobitsofferthefollowingselections:
寄存器位可以有一个单独的函数,或是一个位组的一部分,有一个共同的功能:
一个单独的位可以是启用一个模块的位,如USARTENABLE位。
一个位组可以由两个或两个以上的位组成,这些位共同选择了它们所属的模块的特殊配置。
一个位组提供多达2n个选项,其中的n是位组中位的数量。
这两个位控制的USART接收结束中断级别,RXINTLVL[1:
0],是一个位组的一个例子。
这两个位提供以下选项:
Table2-1.RXINTLVLbitsandcorrespondinginterruptlevelselection.
表2-1.RXINTLVL位和相应的中断级别选项
RXINTLVL1
RXINTLVL0
Interruptlevelselection中断级别选项
InterruptOff中断关闭
1
Lowlevelinterrupt低级中断
1
Mediumlevelinterrupt中级中断
Highlevelinterrupt高级中断
Bitsthatarepartofagroupwillalwayshaveanumbersuffix.Bitsthatarenotpartofabitgroupwillneverhaveanumbersuffix.ATimer/CountercontrolregisterDhastwobitgroups,EVACTandEVSEL.Thebitsinthesegroupshaveanumbersuffix,whiletheEVDLYbit,whichisnotpartofabitgrouphasnonumbersuffix.
作为一个组的一部分的位,将始终有一个数字后缀。
不是一个位组的一部分的位,永远不会有一个数字后缀。
计时器/计数器控制寄存器D有两个位组:
EVACT和EVSEL。
在这些组中的位都有一个数字后缀,而EVDLY位不是一个位组的一部分,因此它没有数字后缀。
Table2-2.BitsgroupsandbitnamesforbitsinTimer/CounterControlregisterD–CTRLD.
表2-2.适用于计时器/计数器控制寄存器D-CTRLD中的位的位组和位名称
BitGroup
位组
EVACT
-
EVSEL
Bitname
位名
EVACT2
EVACT1
EVACT0
EVDLY
EVSEL3
EVSEL2
EVSEL1
EVSEL0
Bitnumber
位编号
7
6
5
4
3
2
3WritingC-codeforXMEGA
编写XMEGA的C语言代码
ThefollowingsectionsfocusonhowtowriteC-codefortheXMEGA.TheexamplesshowhowtomakethecodehighlyreadableandportablebetweendifferentXMEGAdevices.Theexamplescanalsobeusedasaguidelinetowritecodethatiseasytoverifyandmaintain.
以下各节重点放在如何编写XMEGA的C语言代码。
示例显示了如何使代码具有很强的可读性,并能在不同的XMEGA器件之间移植。
这些例子也可以作为指导编写代码的准则,使其易于验证和维护。
XMEGAmodulesarelocatedindedicatedandcontinuousblocksinthememoryspaceandcanbeseenasencapsulatedunits.ThisreflectsonthewaythatthemodulesareaccessedwhencodingC:
modulesareencapsulatedusingCstructs,inwhichallmoduleregistersarecontained.Figure3-1showsanillustrationofthis.
XMEGA的模块位于内存空间的专用的连续的块区域中,我们可以把这些模块看作是被封装的单元。
这反映了编写C语言代码时访问模块的路径:
模块是用C语言结构封装的,其中包容了所有的模块寄存器。
图3-1给出了这个图解。
Notethatsomeregistershavenodirectmoduleassociation.Thesearenotencapsulatedinstructs,asthestructisusedtoassociateregisterswithamodule.
请注意,某些寄存器没有直接的模块相联,这些寄存器都不是封装在结构里的,因为该结构是用来使寄存器与某个模块相关联的。
Forlargercodeprojectsthemodulestructsprovideadvantages,notonlytoreadability,butalsobecausethecompilerscanreusethemoduledriversandtherebymakethecodeverycompact.Thisisdescribedinmoredetailslater.
模块结构为较大的代码项目提供的优势不仅具有可读性,而且还因为编译器可以重复使用模块驱动程序,从而使代码非常紧凑。
这在后面会作更详细的描述。
ThisdocumentintroducesanamingconventionandregisteraccessmethodsthataredifferentfromwhatAVRprogrammingveteransareusedto,butoneshouldbeawarethatthe“classic”waytoaccessregistersisstillsupportedbytheheaderfiles.Thisalsoappliesonthebitlevel.
本文档介绍的命名约定和寄存器访问的方法,不同于AVR编程老手过去常用的方法,但是有一点应该知道:
访问寄存器的“经典”方法仍然是要得到头文件的支持。
这方法也同样适用于对位级别的访问。
Figure3-1.ModulesplacedindedicatedblocksinIOmemoryspace.
图3-1.放置在IO内存空间里的专用块区的模块。
3.1XMEGAHeaderFi