GCCAVR(Atmel Studio)在程序存储器(flash)空间存放常量或者常量数组
GCC中把超出内存的数据存入flash区的方法
AVRGCC中将变量定义在flash空间的方法(大数据存储)
自我介绍:
大家好,我是小灬贱。这是我在CSDN第一次写博客。文章里面如有不妥之处或者表达不清晰的地方还请各位多多指教。可以在文下评论或者私信我。
一、我的设备
1.软件环境:Atmel studio 7.0
2.芯片:Atmega16
二、准备
1.头文件:#include <avr/pgmspace.h>
三、开始存放
1.存放一字节到flash
PROGMEM const unsigned char x=1;
通过这行代码,我们就在flash里面写入了一个名字为x的无符号字符型的常量,然后这个常量里面的数值是1。
这个常量里面的数值是可以自行给定,比如x=2,x=3等等,最大给到255,因为我们定义了无符号字符型。当然
我们也可以定义整数型,长整型等等。
2.存放一组一维数组到flash
PROGMEM const prog_uchar x[5] = { 1, 2, 3, 4, 5 };
通过这行代码,我们就在flash里面写入了一个名字为x的无符号字符型的一维数组,这个数组有5个成员,数
组里面的数分别是1,2,3,4,5。
这个数组里面的数值是可以自行给定,x[5] = { 1, 1, 1, 1, 1 }等等,数组里的每个成员最大给到255,因
为我们定义了无符号字符型。当然我们也可以定义整数型,长整型等等。
2.存放一组多维数组到flash
PROGMEM const prog_uchar x[3][5] = {
{ 1, 2, 3, 4, 5 },
{ 1, 2, 3, 4, 5 },
{ 1, 2, 3, 4, 5 }
};
通过这行代码,我们就在flash里面写入了一个名字为x的无符号字符型的二维数组,这个数组有三行五列,
15个成员。
四、开始使用
1.使用存放在flash里面的常量数据
PROGMEM const unsigned char x=1;//把数据放到flash
unsigned char a;//定义一个变量
a = pgm_read_byte(&x);//取出flash里面的数据到变量a
PORTA = a;//把flash的数据给到PA口
这四行代码我们可以得知怎么去使用我们一开始存放到flash的数据
2.使用存放在flash里面的数组数据
PROGMEM const prog_uchar x[5] = { 1, 2, 3, 4, 5 };//把数组放到flash
unsigned char a;//定义一个变量
a = pgm_read_byte(&x[0]);//取出flash里面的数据(数组的第0个成员)到变量a
PORTA = a;//把flash的数据给到PA口
这四行代码我们可以得知怎么去使用我们一开始存放到flash的数组
2.使用存放在flash里面的数组数据
PROGMEM const prog_uchar x[3][5] = {
{ 1, 2, 3, 4, 5 },
{ 1, 2, 3, 4, 5 },
{ 1, 2, 3, 4, 5 }
};//把数组放到flash
unsigned char a;//定义一个变量
a = pgm_read_byte(&x[0][0]);//取出flash里面的数据(多维数组的第0个成员)到变量a
PORTA = a;//把flash的数据给到PA口
这八行代码我们可以得知怎么去使用我们一开始存放到flash的多维数组
五、扩展资料
avr对ram和flash是独立编址的,ram是按8位编址,而flash却按16位编址,读ram和读flash的汇编指令也是不同的。
类似flash数据类型还有:prog_void 、prog_char 、prog_int8_t、prog_uint8_t、prog_int16_t、prog_uint16_t、prog_int32_t、prog_uint32_t等。
读取指令pgm_read_xxx宏定义其实就是一段包括了flash读取指令的内联汇编代码。函数原型为:pgm_read_byte(address_short)、pgm_read_word(address_short)、 pgm_read_dword(address_short)、pgm_read_float(address_short)。括号中是地址值。
六、总结
流程走起
在这次学习中,我发现了存放数据其实就跟平常定义变量差不多,只不过是前面多了一串代码:PROGMEM const;不管你存放是什么类型的常量,只需要在前面添加这一串就可以把常量放到flash里面。
我们读取的时候要先创建一个变量然后再把flash里面的数据放到变量里面,然后我们变量里面的数据才是我们正常使用的数据。(当然我们也可以不定义变量直接使用,这涉及到其他的操作)
我们怎么把数据放到变量呢?
变量=Pgm_Read_Byte(&数据)数据是我们之前的PROGMEM const prog_uchar 数据=1;
咦?为什么多了一个&符号呢?
啊,这个符号在这里的意思是取这个数据的地址的意思。
为什么要取地址呢?
因为这个子程序传入的是一个地址值,所以我们要取出这个数据的地址给这个子程序,然后这个子程序就把对应地址的数据返回。这个子程序是Pgm_Read_Byte();
咦?那我这个数据类型是其他呢?
哈哈,来,我们拓展资料里面就有讲到这个读取指令
读取指令:pgm_read_xxx宏定义其实就是一段包括了flash读取指令的内联汇编代码。函数原型为:pgm_read_byte(address_short)、pgm_read_word(address_short)、 pgm_read_dword(address_short)、pgm_read_float(address_short)。括号中是地址值。
其中Pgm_Read_Byte();就是读这个地址开始往后一个字节的数据
Pgm_read_word();就是读这个地址开始往后两个字节(一个字)的数据
Pgm_read_dword();就是读这个地址开始往后四个字节(一个双字)的数据
Pgm_read_float();就是读这个地址开始往后四个字节(单精度浮点型)的数据
好啦,本文到此结束。谢谢!
有什么问题可以评论留言哦
2019/09/22