manfield 发表于 2011-6-13 16:33:54

求助:cvavr中flash操作遇到问题

从GCC移植到cvavr时遇到了这个问题,想了很多办法都没有解决,所以只能求助大家了。
做的是lcd的显示。将ASCII放入了flash中,显示时需要从flash中读出数组,将GCC下的读flash函数pgm_read_byte()改写为如下:
/***********************************************************
unsigned char pgm_read_byte(flash unsigned char *temp)
{
   return *temp;
}
*************************************************************/
调用时使用的是这个函数:
/**************************************************************
LCD_write_byte(pgm_read_byte(font6x8+c*6+line), 1);
**************************************************************/
将返回的字节写入LCD,这个函数没有问题。

编译时出现了warning:
Warning: F:\AVR\mega32tst\lcd-char.c(527), included from: systicks.c: overflow is possible in 8 bit multiplication, casting to 'int' may be required

实际的表现出来的是:
可以读出flash内容,但是当读出‘K’以下的ASCII时没有问题,从L开始时就会从ASCII码为0的地方开始。
应该是哪块溢出了,但是没有想明白具体是哪儿。

想过一个方法,对指向flash的指针直接赋值
如:
/*****************************************************
flash unsigned char *x;
x=a;                      //a为计算出的指针地址
*****************************************************/
但是提示出错error:
Error: F:\AVR\mega32tst\lcd-char.c(375), included from: systicks.c: a value of type 'unsigned int' can't be assigned to an entity of type 'flash unsigned char *'

彻底被击败了,有没有哪位也遇到过这个问题的,一起讨论下或者支个招吧!
麻烦大伙了。

machao 发表于 2011-6-13 23:09:11

1。首先应该看CVAVR的HELP,里面什么都有,如果你不看,或者看不懂,那么说明你还不具备“高手”的特质和能力
2。通过这个例子,也可以证明,一般的人应该使用CVAVR,相对比ICC、GCC、IAR等使用方便些,容易掌握和使用。当然你要考虑移植性什么的,另做讨论。不过,对于面向硬件低层的东西,那个软件都谈不上移植性好。比如,数组定义在FLASH中,标准C中是没有的,但你会发现CVAVR用起来方便。

下面是CVAVR中的说明,应该对LZ有帮助的。


The flash or __flash keywords can be used to specify that a constant must be placed in FLASH memory, no matter what is the state of the Store Global Constants in FLASH Memory option:


flash <type definition> <identifier> = constant expression;
__flash <type definition> <identifier> = constant expression;


Example:


flash intinteger_constant=1234+5;
flash char char_constant='a';
flash long long_int_constant1=99L;
flash long long_int_constant2=0x10000000;
flash intinteger_array1[]={1,2,3};
flash char string_constant1[]="This is a string constant located in FLASH";


The constant literal char strings, enclosed in double quotation marks, that are passed as function arguments, are stored in the memory type pointed by the pointer used as function parameter.
Example:


/* This function displays a string located in RAM. */
void display_ram(char *s) {


/* .......*/


}


/* This function displays a string located in FLASH. */
void display_flash(flash char *s) {


/* .......*/


}


/* This function displays a string located in EEPROM. */
void display_eeprom(eeprom char *s) {


/* .......*/


}


void main(void) {
/* The literal string "Hello world" will be placed
   by the compiler in FLASH memory and copied at program
   startup to RAM, so it can be accessed by the pointer
   to RAM used as function parameter.
   The code efficiency is low, because both FLASH and
   RAM memories are used for the string storage. */
display_ram("Hello world");


/* The literal string "Hello world" will be placed
   by the compiler in FLASH memory only, good code
   efficiency beeing achieved. */
display_flash("Hello world");


/* The literal string "Hello world" will be placed
   by the compiler in EEPROM memory only.
   The code efficiency is very good because no
   FLASH memory will be allocated for the string. */
display_eeprom("Hello world");


while (1);
}

manfield 发表于 2011-6-13 23:54:29

回复【1楼】machao
-----------------------------------------------------------------------

多谢马潮老师,我找到原因了,并不是因为读写flash的问题,而是pgm_read_byte(font6x8+c*6+line)中c*6的问题。
将其改为:
/******************************************
unsigned int d;
d=c;             //或者强制类型转换      
d*=6;            //d=(unsigned int )c * 6
pgm_read_byte(font6x8+d+line);
******************************************/
解决问题。


之前从没有遇到过这种情况,不知道是我对数据类型的理解有问题还是cvavr存在bug。
不过估计是前者的可能性更加大点。

machao 发表于 2011-6-14 00:45:39

你还没有入门,只能看热闹,看不出门道。

在CVAVR中定义变量或数组在FLASH(eeprom)中后,可以直接使用的,如:

flash charASCII_TAB[]={0x30,0x31,0x32,.......};

......

a=1;

lcd(ascii_tab);


OK了!省多少事情。什么指针、AVR的FLASH地址是按字编址的、高8位在高端还是低端,都不用考虑。比哪个C平台都方便。

chushichongyu 发表于 2011-6-28 14:46:41

喜欢这个帖子

manfield 发表于 2011-6-28 18:40:30

回复【4楼】chushichongyu
-----------------------------------------------------------------------
这么老的帖子都被翻出来了,当时这个子程序是gcc下的,所以得重写下读flash的函数,不过也是第一次用cvavr,果然像马潮老师说的比哪个平台都方便。

machao 发表于 2011-6-28 20:50:15

作为“高手”,知道做什么事情用哪个工具最方便。

每个平台都有自己的特点和优势,对于初学和面向硬件的系统,CVAVR比任何的C平台都合适。

lujin49 发表于 2012-7-10 10:06:37

向马老师学习
页: [1]
查看完整版本: 求助:cvavr中flash操作遇到问题