AVR 單片機(jī)與GCC 編程----之二
2.1 AVR 單片機(jī)存儲(chǔ)器組織結(jié)構(gòu)
AVR 系列單片機(jī)內(nèi)部有三種類型的被獨(dú)立編址的存儲(chǔ)器,它們分別為:Flash 程序存儲(chǔ)器、內(nèi)部SRAM 數(shù)據(jù)存儲(chǔ)器和EEPROM 數(shù)據(jù)存儲(chǔ)器。
Flash 存儲(chǔ)器為1K~128K 字節(jié),支持并行編程和串行下載,下載壽命通??蛇_(dá)10,000 次。
由于AVR 指令都為16 位或32 位,程序計(jì)數(shù)器對(duì)它按字進(jìn)行尋址,因此FLASH 存儲(chǔ)器按字組織的,但在程序中訪問FLASH 存儲(chǔ)區(qū)時(shí)專用指令LPM 可分別讀取指定地址的高低字節(jié)。
寄存器堆(R0~R31)、I/O 寄存器和SRAM 被統(tǒng)一編址。所以對(duì)寄存器和I/O 口的操作使用與訪問內(nèi)部SRAM 同樣的指令。
32 個(gè)通用寄存器被編址到最前,I/O 寄存器占用接下來的64 個(gè)地址。從0X0060 開始為內(nèi)部SRAM。外部SRAM 被編址到內(nèi)部SRAM 后。
AVR 單片機(jī)的內(nèi)部有64~4K 的EEPROM 數(shù)據(jù)存儲(chǔ)器,它們被獨(dú)立編址,按字節(jié)組織。擦寫壽命可達(dá)100,000 次。
2.2 I/O 寄存器操作
I/O 專用寄存器(SFR)被編址到與內(nèi)部SRAM 同一個(gè)地址空間,為此對(duì)它的操作和SRAM 變量操作類似。
SFR 定義文件的包含:
#include
io.h 文件在編譯器包含路徑下的avr 目錄下,由于AVR 各器件間存在同名寄存器地址有不同的問題,io.h 文件不直接定義SFR 寄存器宏,它根據(jù)在命令行給出的 –mmcu 選項(xiàng)再包含合適的 ioxxxx.h 文件。
在器件對(duì)應(yīng)的ioxxxx.h 文件中定義了器件SFR 的預(yù)處理宏,在程序中直接對(duì)它賦值或引用的方式讀寫SFR,如:
PORTB=0XFF;
Val=PINB;
從io.h 和其總包含的頭文件sfr_defs.h 可以追溯宏P(guān)ORTB 的原型
在io2313.h 中定義:
#define PORTB _SFR_IO8(0x18)
在sfr_defs.h 中定義:
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + 0x20)
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
這樣PORTB=0XFF; 就等同于 *(volatile unsigned char *)(0x38)=0xff;
0x38 在器件AT90S2313 中PORTB 的地址
對(duì)SFR 的定義宏進(jìn)一步說明了SFR 與SRAM 操作的相同點(diǎn)。
關(guān)鍵字volatile 確保本條指令不會(huì)因C 編譯器的優(yōu)化而被省略。
2.3 SRAM 內(nèi)變量的使用
一個(gè)沒有其它屬性修飾的C 變量定義將被指定到內(nèi)部SRAM,avr-libc 提供一個(gè)整數(shù)類型定義文件inttype.h,其中定義了常用的整數(shù)類型如下表:
定義值 長(zhǎng)度(字節(jié)) 值范圍
int8_t 1 -128~127
uint8_t 1 0~255
int16_t 2 -32768~32767
uint16_t 2 0~65535
int32_t 4 -2147483648~2147483647
uint32_t 4 0~4294967295
int64_t 8 -9.22*10^18~-9.22*10^18
uint64_t 8 0~1.844*10^19
根據(jù)習(xí)慣,在程序中可使用以上的整數(shù)定義。
定義、初始化和引用
如下示例:
uint8_t val=8; 定義了一個(gè)SRAM 變量并初始化成8
val=10; 改變變量值
const uint8_t val=8; 定義SRAM 區(qū)常量
register uint8_t val=10; 定義寄存器變量
2.4 在程序中訪問FLASH 程序存儲(chǔ)器
avr-libc 支持頭文件:pgmspace.h
#include < avr/pgmspace.h >
在程序存儲(chǔ)器內(nèi)的數(shù)據(jù)定義使用關(guān)鍵字 __attribute__((__progmem__))。在pgmspace.h
中它被定義成符號(hào) PROGMEM。
1. FLASH 區(qū)整數(shù)常量應(yīng)用
定義格式:
數(shù)據(jù)類型 常量名 PROGMEM = 值 ;
如:
char val8 PROGMEM = 1 ;
int val16 PROGMEM = 1 ;
long val32 PROGMEM =1 ;
對(duì)于不同長(zhǎng)度的整數(shù)類型 avr-libc 提供對(duì)應(yīng)的讀取函數(shù):
pgm_read_byte(prog_void * addr)
pgm_read-word(prg_void *addr)
pgm_read_dword(prg_void* addr)
另外在pgmspace.h 中定義的8 位整數(shù)類型 prog_char prog_uchar 分別指定在FLASH
內(nèi)的8 位有符號(hào)整數(shù)和8 位無符號(hào)整數(shù)。應(yīng)用方式如下:
char ram_val; //ram 內(nèi)的變量
const prog_char flash_val = 1; //flash 內(nèi)常量
ram_val=pgm_read_byte(&flash_val); //讀flash 常量值到RAM 變量
對(duì)于應(yīng)用程序FLASH 常量是不可改變的,因此定義時(shí)加關(guān)鍵字const 是個(gè)好的習(xí)慣。
2. FLASH 區(qū)數(shù)組應(yīng)用:
定義:
const prog_uchar flash_array[] = {0,1,2,3,4,5,6,7,8,9}; //定義
另外一種形式
const unsigned char flash_array[] RROGMEM = {0,1,2,3,4,5,6,7,8,9};
讀取示例:
unsigend char I, ram_val;
for(I=0 ; I<10 ;I ++) // 循環(huán)讀取每一字節(jié)
{
ram_val = pgm_read_byte(flash_array + I);
… … //處理
}
2. FLASH 區(qū)字符串常量的應(yīng)用
全局定義形式:
const char flash_str[] PROGMEM = “Hello, world!”;
函數(shù)內(nèi)定義形式:
const char *flash_str = PSTR(“Hello, world!”);
以下為一個(gè)FLASH 字符串應(yīng)用示例
#include
#include
#include
const char flash_str1[] PROGMEM = “全局定義字符串”;
int main(void)
{
int I;
char *flash_str2=PSTR(“函數(shù)內(nèi)定義字符串”);
while(1)
{
scanf(“%d”,&I);
printf_P(flash_str1);
printf(“”);
printf_P(flash_str2);
printf(“”);
}
}
關(guān)鍵詞:
AVR單片機(jī)GCC編
相關(guān)推薦
技術(shù)專區(qū)
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機(jī)
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線
- 開關(guān)電源
- 單片機(jī)
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩(wěn)壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機(jī)控制
- 藍(lán)牙
- PLC
- PWM
- 汽車電子
- 轉(zhuǎn)換器
- 電源管理
- 信號(hào)放大器
評(píng)論