8-bit 8位
Microcontrollers 微处理器
Application Note 应用注释
AVR1000: Getting Started Writing C-code for XMEGA
AVR1000 :XMEGA的C语言代码编写入门
Features
特点:
• Naming conventions
命名约定
- Register names
寄存器名
-
Bit names
位名
• C-code names
C-代码名
- Bit and group masks
位与组掩码
- Group configuration masks
组配置掩码
• Methods for accessing registers
访问寄存器的方法
• Methods for writing reusable module functions
可多次使用模块功能的写入方法
1 Introduction
引言
Short development times and high quality requirements on electronic products has made high-level programming languages a requirement. The main reason is that High level languages make it easier to maintain and reuse code due to better portability and readability.
由于电子产品的开发时间短,质量要求高,因此需要高层次的编程语言。最主要的原因是,高级语言具有更好的可移植性和可读性,使其更易于维护和重复使用代码。
The choice of programming language alone does not ensure high readability and reusability; good coding style does. Therefore the XMEGA™ peripherals, header files and drivers are designed with this in mind.
编程语言的选择本身并非是能确保具有较高的可读性和可重复使用性的唯一条件,还必须有良好的编码风格。因此XMEGA ™的外围设备,头文件和驱动程序的设计都是基于这方面考虑的。
The most widely used high-level language for AVR® microcontrollers is C, and this application note therefore focuses on C programming. To support most of the AVR C compilers that are available, the code examples are as far as possible written in ANSI C. A few examples are specific to IAR Embedded Workbench®, but the ideas and methods can be used for other compilers with minor changes. IAR specific examples are clearly marked.
AVR ®微控制器使用的最广泛的高级语言就是C 语言,因此本应用注释的重点是C 语言编程。为了支持大多数可用的AVR C 语言编译器,我们尽可能把代码示例编写在ANSI C 语言的规范中。有些例子是IAR Embedded Workbench®专用的,但其思路和方法可用于与其他变化不大的编译器。IAR 专用的示例都有清晰的标示。
2 XMEGA Modules
XMEGA 模块
An AVR XMEGA is composed of several building blocks: An AVR CPU core, SRAM, Flash, EEPROM and a number of peripheral modules. These building blocks are called “module types”. An XMEGA can have one or more instances of a given module type. All instances of a module type have the same features and functions.
一个AVR XMEGA 由数个结构块组成:一个AVR CPU 芯片,一个SRAM,一个闪存,一个EEPROM 以及若干外设模块。这些结构块被称为“模块类型”。XMEGA可以有一个或多个给定模块类型的实例。一个模块类型的所有实例都具有相同的特性和功能。
Some module types can be a subset of other module types. These inherit a subset of the features (and registers) of the super type, all inherited features are fully compatible. This applies timers and IO ports. The subset of a module type can for a timer mean that it has fewer compare and capture channels than a full timer module. Similarly, an IO port may have less than eight pins.
有些模块类型可以是其他模块类型的子集。这些(模块类型)继承了特大模块类型的某个子集的特征(和寄存器),其继承的所有特征都完全兼容。这适用于比如计时器和IO端口。用于计时器的模块类型的子集可能意味着它所能得到的比较和捕获通道比完整的计时器模块的要少。同样,一个IO 端口的管脚可能不足八个。
A module type can be a “USART”, while the module instance “USARTC0”, where the “C0” suffix indicates the in stance is “USART number 0 on port C”. For simplicity, a module instance will be referred to as a module throughout this document, unless there is a need to differentiate.
一个模块类型可以是“USART”的,如果这个模块实例比如是“USARTC0”,其中的“C0”后缀表示这个实例
是“端口C 上的USART 编号为0”。为了简单起见,一个模块实例将被称为这整个文件中的一个模块,除非是有必要另作区分。
Each module has a number of registers that contain control or status bits. All modules of a given type contain the same set (or subset) of registers, and all these registers contain the same set (or subset) of control and status bits.
每个模块都有若干寄存器,这些寄存器都包含控制位或状态位。一个给定类型的所有模块都包含相同的寄存器集合(或子集),并且所有这些寄存器包含相同的控制位和状态位的集合(或子集)。
Figure 2-1. Module types, instances, registers and bits.
图2-1. 模块类型,实例,寄存器和位
Each module has a fixed base address in the IO memory map and all registers contained in the module have fixed offset addresses relative to the module base address. This way each register will not only have an absolute address in the IO memory space, but also a relative address defined by its offset. The register offset addresses are equal for all instances of a module type, simplifying the task of writing drivers that can be used for all modules of a specific type.
在IO 内存图里,每个模块都有一个固定的基础地址,并且该模块中的所有寄存器都有固定的偏移地址(这是相对于模块的基地址而言)。如此这样,每个寄存器不仅会在IO 内存空间有一个绝对地址,而且还有一个根据其偏移量定义的相对地址。一个模块类型的所有实例中的寄存器偏移地址都是平等的,这样就简化了编写能够适用于某个特定类型的所有模块的驱动程序的任务。
2.1 Register Naming Convention
2.1. 寄存器命名约定
Register are roughly speaking divided into control, status and data registers and the naming of registers reflect this. A general-purpose control register of the module is named CTRL. If multiple general-purpose control registers exists in a module they have a suffix character. In this case the control registers would be named CTRLA, CTRLB, CTRLC and so on. This also applies to STATUS re
gisters.
大致说来,寄存器有控制寄存器、状态寄存器和数据寄存器之分,这从寄存器的命名就可看出。模块的一个通用的控制寄存器被命名为CTRL。如果在一个模块中存在多个通用控制寄存器,他们都有一个后缀字符。在这种情况下,控制寄存器将被命名为CTRLA 、CTRLB 、CTRLC等。这方法也适用于状态寄存器。
For registers that have a specific function the name reflects this functionality. For example, a control register that controls the interrupt level of a module is named INTCTRL.
对于具有特定功能的的寄存器,它们的命名会反映其功能性。例如,一个控制寄存器,控制一个模块的中断级别,它就被命名为INTCTRL 。
c语言编译器的功能Since the AVR data bus width is 8 bit, larger registers are implemented using several 8-bit registers. For a 16-bit register, the high and low bytes are accessed by appending “H” and “L” respectively to the register name. For example, the 16-bit Timer/Counter count register is named CNT. The two bytes are named CNTL and CNTH.
由于AVR 的数据总线宽度为8 位,较大的寄存器得使用几个8 位寄存器才能生效。对于一个16位寄存器,
要访问其高8位元组和低8位元组,得在这个寄存器的命名上分别附加“H”和“L”。例如,16位计时器/计数器的计数寄存器被命名为CNT ,其两个8位元组就被命名为CNTL和CNTH 。
For a register larger than 16 bit, the bytes are numbered from the least significant byte. For example, the 32-bit ADC calibration register is named CAL. The four bytes are named CAL0, CAL1, CAL2 and CAL3 (from least to most significant byte).
对于大于16位的寄存器,其8位元组的编号是从最低有效的8位元组开始。例如,32位的ADC 校准寄存器被命名为CAL,其四个8位元组(从最低到最高有效8位元组)就被分别命名为CAL0 ,CAL1 ,CAL2 和CAL3 。
Most C compilers offer automatic handling of access to multi-byte registers. In that case the name CNT, without “H” or “L” suffix, could be used to perform a 16-bit access to the Timer/Counter count register. This is also the case for 32-bit registers.
大多数C 语言编译器都提供了自动处理多8位元组寄存器的访问。在这种情况下,CNT 的命名没有加“ H”或“ L”后缀的,可以用来执行16位的计时器/计数器的计数寄存器的访问。这方法也同样使用于32位寄存器。
2.2 Bit Naming Convention
2.2 位命名约定
Register bits can have an individual function or be part of a bit group that have a joint function: An individual bit could be a bit that enables a module, e.g. the USART ENABLE bit. A bit group can consist of two of more bits that jointly select a
specific configuration of the module that they belong to. A bit group offers up to 2n selections, where n is the number of bits in the bit group. The two bits that control the USART Receive Complete interrupt level, RXINTLVL[1:0], is an example of a bit group. These two bits offer the following selections:
寄存器位可以有一个单独的函数,或是一个位组的一部分,有一个共同的功能:一个单独的位可以是启用一个模块的位,如USART ENABLE 位。一个位组可以由两个或两个以上的位组成,这些位共同选择了它们所属的模块的特殊配置。一个位组提供多达2n 个选项,其中的n 是位组中位的数量。这两个位控制的USART 接收结束中断级别,RXINTLVL [1:0 ] ,是一个位组的一个例子。这两个位提供以下选项:
Table 2-1. RXINTLVL bits and corresponding interrupt level selection.
表2-1. RXINTLVL 位和相应的中断级别选项
Bits that are part of a group will always have a number suffix. Bits that are not part of a bit group will never have a number suffix. A Timer/Counter control register D has two bit groups, EVACT and EVSEL. The bits in these groups have a number suffix, while the EVDLY bit, which is not part of a bit group has no number suffix.
作为一个组的一部分的位,将始终有一个数字后缀。不是一个位组的一部分的位,永远不会有一个数字后缀。计时器/计数器控制寄存器D 有两个位组:EVACT 和EVSEL 。在这些组中的位都有一个数字后缀,而EVDLY 位不是一个位组的一部分,因此它没有数字后缀。
Table 2-2. Bits groups and bit names for bits in Timer/Counter Control register D – CTRLD.
表2-2. 适用于计时器/计数器控制寄存器D - CTRLD 中的位的位组和位名称
3 Writing C-code for XMEGA
编写XMEGA 的C 语言代码
The following sections focus on how to write C-code for the XMEGA. The examples show how to make the code highly readable and portable between different XMEGA devices. The examples can also be used as a guideline to write code that is easy to verify and maintain.
以下各节重点放在如何编写XMEGA 的C 语言代码。示例显示了如何使代码具有很强的可读性,并能在不同的XMEGA 器件之间移植。这些例子也可以作为指导编写代码的准则,使其易于验证和维护。
XMEGA modules are located in dedicated and continuous blocks in the memory space and can be see
n as encapsulated units. This reflects on the way that the modules are accessed when coding C: modules are encapsulated using C structs, in which all module registers are contained. Figure 3-1 shows an illustration of this.
XMEGA的模块位于内存空间的专用的连续的块区域中,我们可以把这些模块看作是被封装的单元。这反映了编写C 语言代码时访问模块的路径:模块是用C 语言结构封装的,其中包容了所有的模块寄存器。图3-1给出了这个图解。
Note that some registers have no direct module association. These are not encapsulated in structs, as the struct is used to associate registers with a module.
请注意,某些寄存器没有直接的模块相联,这些寄存器都不是封装在结构里的,因为该结构是用来使寄存器与某个模块相关联的。
For larger code projects the module structs provide advantages, not only to readability, but also because the compilers
can reuse the module drivers and thereby make the code very compact. This is described in more details later.
模块结构为较大的代码项目提供的优势不仅具有可读性,而且还因为编译器可以重复使用模块驱动程序,从而使代码非常紧凑。这在后面会作更详细的描述。
This document introduces a naming convention and register access methods that are different from what AVR programming veterans are used to, but one should be aware that the “classic” way to access registers is still supported by the header files. This also applies on the bit level.
本文档介绍的命名约定和寄存器访问的方法,不同于AVR 编程老手过去常用的方法,但是有一点应该知道:访问寄存器的“经典”方法仍然是要得到头文件的支持。这方法也同样适用于对位级别的访问。
Figure 3-1. Modules placed in dedicated blocks in IO memory space.
图3-1 .放置在IO 内存空间里的专用块区的模块。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论