青草国产精品久久久久久,国产高清一区二区三区视频,免费av一区二区三区,午夜熟女插插XX免费视频

產(chǎn)品
有人云 — 物聯(lián)網(wǎng)云平臺 零編程,組態(tài)拖拽即可實現(xiàn)遠程監(jiān)控。同時支持私有部署,擁有屬于自己的軟硬件一體化方案
200
+
私有云項目
數(shù)據(jù)本地化
業(yè)務個性化
10
+
萬 公有云注冊用戶
80%公有云功能免費
付費VIP享自定義品牌服務
有人云官網(wǎng)
有人智造 — ODM/EMS 依托自動化、智能化、柔性化、透明化的智能工廠,
提供代研、代料、代工一站式OEM/ODM服務
有人智造官網(wǎng)
有人智能 — 解決方案 打包提供云、管、邊、端整體解決方案
從問題診斷、方案設計,到實施落地、系統(tǒng)運維
有人智能官網(wǎng)
新聞資訊
keil、IAR和GCCAVR對FLASH和EEPROM的操作
2010-09-19


1.  keil for MSC51

關鍵字code

code unsigned char array[8]={}

2.  IAR for AVR(摘抄)

FLASH常用類型的具體操作方法

(1) FLASH 區(qū)域數(shù)據(jù)存儲。
用關鍵字 __flash 控制來存放, __ flash 關鍵字寫在數(shù)據(jù)類型前后效果一樣
__flash unsigned char a;//定義一個變量存放在flash空間
unsigned char __flash a;//效果同上
__flash unsigned char p[];//定義一個數(shù)組存放在flash空間
對于flash空間的變量的讀操作同SRAM數(shù)據(jù)空間的操作方法一樣,編譯器會自動用
LPM,ELPM 指令來操作。
例:
#i nclude
__flash unsigned char p[];
__flash unsigned char a;
void main(void)
{PORTB=p[1];// 讀flash 數(shù)組變量的操作
PORTB=a;// 讀flash 變量的操作
}
由于在正常的程序中,flash 空間是只讀的,所以沒有賦值的變量是沒有意義的。定義常數(shù)在flash 空間,只要給變量賦與初值就可以了。由于常數(shù)在flash空間的地址是隨機分配的,讀取變量才可以讀取到常數(shù)值。
IAR-AVR –C 編譯器簡要指南
__flash unsigned char a="9";//定義一個常數(shù)存放在flash空間。
__flash unsigned char p[]={1,2,3,4,5,6,7,8};
//定義一個組常數(shù)存放在flash 空間。
例:
#i nclude
__flash unsigned char p[]={1,2,3,4,5,6,7,8};
__flash unsigned char a="9";
void main(void)
{
   PORTB="a";//讀取flash 空間值9
   PORTC="p"[0]; //讀取flash 空間值
}

(2)flash 空間絕對地址定位:
__flash unsigned char a @ 0x8;//定義變量存放在flash 空間0X08單元__flash unsigned char p[] @ 0x22//定義數(shù)組存放在flash 空間,開始地址為0X22單元
__flash unsigned char a @ 0x08=9;//定義常數(shù)存放在flash 空間0X08單元
__flash unsigned char p[] @ 0x22={1,2,3,4,5,6,7,8};
//定義一個組常數(shù)存放在EEPROM空間開始地址為0X22單元
由于常數(shù)在flash 空間的地址是已經(jīng)分配的,讀取flash 空間值可以用變量和地址。

(3) 與 __flash 有關的指針操作。 __flash 關鍵字控制指針的存放和類型。
指向flash 空間的SRAM指針(控制類型屬性)
unsigned char __flash * p;//定義指向flash 空間地址的指針,8位。
unsigned int __flash * p;//定義個指向flash 空間地址的指針,16位。
unsigned int __farflash * p;//定義指向flash 空間地址的指針,24位。
unsigned int __hugeflash * p;//定義指向flash 空間地址的指針,24位。
unsigned char __flash * p;//定義一個指向flash 空間地址的指針,指針本身存放在SRAM中。P的值代表flash 空間的某一地址。*p表示flash 空間該地址單元存放的內(nèi)容。例:假定p=10,表示flash空間地址10單元,而flash 空間10單元的內(nèi)容就用*p來讀取。
例:
#i nclude
char __flash t @ 0x10 ;
char __flash *p ;
void main(void)
{
PORTB=*p;//讀取flash 空間10單元的值
PORTB=*(p+3);//讀取flash 空間0x13單元的值
}

存儲于flash 空間的指針數(shù)據(jù)指針
就象存儲與flash 空間的數(shù)據(jù)一樣控制存儲屬性
__flash unsigned char * p; //定義指向SARMM空間地址的指針,指針本身存放在flash 中。

控制數(shù)據(jù)和指針存放的__flash 定義必須是全局變量,控制類型屬性(好像只有指針)可以是局部變量。
#i nclude
__flash unsigned char p;//控制存放
void main(void)
{
unsigned char __flash * t;//控制屬性
PORTB=p;
PORTB=*t;
}

(4) __root 關鍵字保證沒有使用的函數(shù)或者變量也能夠包含在目標代碼中.
定義存放在__flash 空間的數(shù)據(jù)在程序編譯時會自動生成代碼嵌入到flash代碼中,對于程序沒有使用也要求編譯的數(shù)據(jù)(比如可以在代碼中嵌入你的版本號,時間等)必須加關鍵字__root 限制。
例:
#i nclude
__root __flash unsigned char p @ 0x10 =0x56;
void main(void)
{}
程序沒有使用P變量,編譯也會生成該代碼。
:020000020000FC
:1000000016C018951895189518951895189518955F
:10001000569518951895189518951895189518953A
:10002000189518951895089500008895FECF0FE94A
:100030000DBF00E00EBFC0E8D0E003D0F4DFF4DF76
:06004000F3CF01E008957A
:0400000300000000F9
:00000001FF

(5)flash 操作宏函數(shù):在comp_a90.h intrinsics.h頭文件里有詳細說明。flash 空間具正常情況下有只讀性能,對于讀flash 數(shù)據(jù)編譯器會自動編譯對應的LPM,ELPM指令,但對于flash 空間的自編程寫命令SPM就沒有對應的C指令了,這里不講解詳細的自編程方法,只是講解一下對flash 的讀寫函數(shù)。
直接在程序中讀取flash 空間地址數(shù)據(jù):要包含intrinsics.h頭文件
__load_program_memory(const unsigned char __flash *);//64K空間
//從指定flash 空間地址讀數(shù)據(jù)。該函數(shù)在intrinsics.h頭文件里有詳細說明。
在comp_a90.h文件有它的簡化書寫_LPM(ADDR)。注意匯編指令LPM Rd ,Z中的Z是一個指針。所以用(const unsigned char __flash *)來強制轉(zhuǎn)換為指向flash空間地址指針。故該條宏函數(shù)的正確寫法應該如下:
__load_program_memory((const unsigned char __flash *)ADDR);
例:
#i nclude
#i nclude
void main(void)
{PORTB=__load_program_memory((const unsigned char __flash *)0x12);
}
該條函數(shù)書寫不方便,在comp_a90.h文件有簡化:
#define _LPM(ADDR) __load_program_memory (ADDR)稍微方便一點。改為
#define _LPM(ADDR) __load_program_memory ((const unsigned char
__flash *)ADDR)就更方便了,直接使用數(shù)據(jù)就可以了。
例:
#i nclude
#i nclude
#i nclude
void main(void)
{
PORTB=__LPM(0x12);// 從指定flash 空間地址單元0x12中讀數(shù)據(jù)
}
__extended_load_program_memory(const unsigned char __farflash *);
//128K空間_ELPM(ADDR); //128K空間
參照上面的理解修改可以書寫更簡單。

(6)自編程函數(shù):
_SPM_GET_LOCKBITS();//讀取縮定位
_SPM_GET_FUSEBITS();//讀取熔絲位
_SPM_ERASE(Addr);//16位頁擦除
_SPM_FILLTEMP(Addr,Word);//16位頁緩沖
_SPM_PAGEWRITE(Addr;)//16位頁寫入
_SPM_24_ERASE(Addr); //24位頁擦除
_SPM_24_FILLTEMP(Addr,Data); //24位頁緩沖
_SPM_24_PAGEWRITE(Addr) //24位頁寫入

3. AVR GCC for AVR

AVR具有三種存儲器:FLASH,SRAM和EEPROM。AVR-GCC將程序代碼放在FLASH,數(shù)據(jù)放在SRAM。
(1).程序存儲器
如果要將數(shù)據(jù)(如常量,字符串,等等)放在FLASH里,用戶需要指明數(shù)據(jù)類型__attribute__((progmem))。為了方便使用,AVR-GCC定義了一些更直觀的符號,如下表所示。包含在頭文件pgmspace.h中

#include
類型 定義
prog_void void __attribute__((progmem))
prog_char char __attribute__((progmem))
prog_int int __attribute__((progmem))
prog_long long __attribute__((progmem))
prog_long_long long long __attribute__((progmem))
PGM_P const prog_char *
PGM_VOID_P prog_void const*

example code: m16 timer1 project

const char NumberCode[12] PROGMEM ={'K','e','y', ' ' , ' ' , ' ' ,'N','u','m','b','e','r'};

PGM_P pstr="NumberCode";            //FLASH內(nèi)存的數(shù)據(jù)類型為char,pstr是指向FLASH的指針,其值是16位

pgm_read_byte(pstr++)          //讀FLASH內(nèi)的數(shù)據(jù),pstr內(nèi)容是FLASH 16地址
提供的庫函數(shù)有:
1.__elpm_inline
用法:uint8_t __elpm_inline(uint32_t addr);
說明:執(zhí)行ELPM指令從FLASH里取數(shù)。參數(shù)為32位地址,返回一個8位數(shù)據(jù)。
2.__lpm_inline
用法:uint8_t __elpm_inline(uint16_t addr);
說明:執(zhí)行LPM指令從FLASH里取數(shù)。參數(shù)為16位地址,返回一個8位數(shù)據(jù)。
3.memcpy_P
用法:void* memcpy_P(void* dst, PGM_VOID_P src, size_t n);
說明:memcpy的特殊版本。完成從FLASH取n個字節(jié)的任務。
4.PRG_RDB
用法:uint8_t PGR_RDB(uint16_t addr);
說明:此函數(shù)簡單地調(diào)用__lpm_inline
5.PSTR
用法:PSTR(s);
說明:參數(shù)為字符串。功能是將其放在FLASH里并返回地址。
6.strcmp_P
用法:int strcmp(char const*, PGM_P);
說明:功能與strcmp()類似。第二個參數(shù)指向程序存儲器內(nèi)的字符串。
7.strcpy_P
用法:char* strcpy_P(char*, PGM_P);
說明:功能與strcpy()類似。第二個參數(shù)指向程序存儲器內(nèi)的字符串。
8.strlen_P
用法:size_t strlen_P(PGM_P);
說明:功能與strlen()類似。第二個參數(shù)指向程序存儲器內(nèi)的字符串。
9.strncmp_P
用法:size_t strncmp_P(char const*, PGM_P, size_t);
說明:功能與strncmp()類似。第二個參數(shù)指向程序存儲器內(nèi)的字符串。
10.strncpy_P
用法:size_t strncpy_P(char*, PGM_P, size_t);
說明:功能與strncpy()類似。第二個參數(shù)指向程序存儲器內(nèi)的字符串。

(2).EEPROM
AVR內(nèi)部有EEPROM,但地址空間與SRAM的不相同。在訪問時必須通過I/O寄存器來進行。EEPROM API封裝了這些功能,為用戶提供了高級接口。使用時要包含eeprom.h。在程序里定義EEPROM數(shù)據(jù)的例子如下:
static uint8_t variable_x __attribute__((section(".eeprom"))) = 0;
不同的AVR器件具有不同數(shù)目的EEPROM。鏈接器將針對不同的器件分配存儲器空間。
1. eeprom_is_ready
用法:int eeprom_is_ready(void);
說明:此函數(shù)用于指示是否可以訪問EEPROM。如果EEPROM正在執(zhí)行寫操作,則在4ms內(nèi)無法訪問。此函數(shù)查詢相應的狀態(tài)位來指示現(xiàn)在是否可以訪問EEPROM。
2. eeprom_rb
用法:uint8_t eeprom_rb(uint16_t addr);
說明:從EEPROM里讀出一個字節(jié)的內(nèi)容。參數(shù)addr用于指示要讀出的地址。_EEGET(addr)調(diào)用此函數(shù)。
3. Eeprom_read_block
用法:void eeprom_read_block(void* buf, uint16_t addr, size_t n);
說明:讀出一塊EEROM的內(nèi)容。參數(shù)addr為起始地址,n表明要讀取的字節(jié)數(shù)。數(shù)據(jù)被讀到SRAM的buf里。
4. eeprom_rw
用法:unint16_t eeprom_rw(uint16_t addr);
說明:從EEPROM里讀出一個16位的數(shù)據(jù)。低字節(jié)為低8位,高字節(jié)為高8位。參數(shù)addr為地址。
5. eeprom_wb
用法:void eeprom_wb(uint16_t addr, uint8_t val);
說明:將8位數(shù)據(jù)val寫入地址為addr的EEPROM存儲器里。_EEPUT(addr,val)調(diào)用此函數(shù)。

工作日每天: 14:00~17:00
抖音、天貓 "有人旗艦店"

關注有人微信公眾號
了解更多信息