原创 编程错误记录

2009-8-26 14:59 4336 3 3 分类: MCU/ 嵌入式

1.头文件中函数声明,注意分号的遗漏 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


典型错误报告:



../avr16.c:167: error: expected '{' at end of input


../avr16.c:84: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token


../avr16.c:167: error: old-style parameter declarations in prototyped function definition



错误原因:在头文件的函数声明时,忘了加分号;



#ifndef avr16__h


#define avr16__h


#include<avr/io.h>


 

//#include"avrlibdefs.h"


#include<avr/pgmspace.h>


#include <avr/interrupt.h>


void init_devices(void);


void port_init(void);


void timer2_init(void);


#endif



问题症结编程人员要养成良好的编程习惯


 

2.AVR GCC编译器优化等级对代码的影响



m16-timer1的程序中avr stiduo optimation设置对proteus lcd的显示有影响。



-O3以优化代码大小为主


-Os以优化代码大小为主,同时还兼顾代码大小



你可以在avr-libc-user-manual.pdf或在http://www.avrfreaks.net下查找相关的资料。



3.数据类型匹配问题


1.warning: passing argument 1 of 'average' discards qualifiers from pointer target type



说的是指针不匹配,例如:我定义了这样一个函数


uint16_t average(uint16_t *arr)


{


      ......  


}


然后在另一个函数中调用上面的函数


volatile uint16_t ADC0_value[18];                   // 0通道AD18个数据


volatile uint16_t ADC2_value[18];                   // 2通道AD18个数据


volatile uint16_t ADC3_value[18];                   // 3通道AD18个数据


 

void disp_js(void)


{


    Current = (average(&ADC2_value[0]))/8;


    Voltage = (average(&ADC3_value[0]))/3;


    Temperature = average(&ADC0_value[0]);


}


当我编译的时候就出


../main.c: In function 'disp_js':


../main.c:28: warning: passing argument 1 of 'average' discards qualifiers from pointer target type


../main.c:29: warning: passing argument 1 of 'average' discards qualifiers from pointer target type


../main.c:30: warning: passing argument 1 of 'average' discards qualifiers from pointer target type


 

解决方法:把数组和指针的类型统一起来,volatile uint16_t ADC3_value[18]; 


// 3通道AD18个数据是具有volatile特性而uint16_t average(uint16_t *arr)是普通的,去掉


volatile就没这个警告了。


 

4.重复定义


2.gcc plug-in: Error: Object file not found on expected location



E:\SUNKE\test\DCFD-1\default\DCFD-1.elf


从字面上的意思是就是E:\SUNKE\test\DCFD-1\default\DCFD-1.elf 这个文件没有找到


但是DCFD-1.elf 这个文件应该是GCC生成的啊?他怎么会找不到?


实际引起这个错误的原因多数都是定义变量时出现了错误,比如:重复定义。


解决方法:找到错误的变量删除或修改。


 

3.../modbus.h:10: warning: 'Crc_counter' initialized and declared 'extern'


出现这个警告是因为在头文件中给变量赋值了.


例如:


我在头文件中定义extern uint8_t Crc_counter = 0;//com0校验计数器


我在程序文件中定义了uint8_t Crc_counter = 0;//com0校验计数器


编译的时候就出


.../modbus.h:10: warning: 'Crc_counter' initialized and declared 'extern'


 

解决方法:在头文件中改成extern uint8_t Crc_counter ;//com0校验计数器就可以了


 

4.../modbus.c:28: error: conflicting type qualifiers for 'Uart0_rev_comflag'


../modbus.h:9: error: previous definition of 'Uart0_rev_comflag' was here


出现这个错误提示是因为重复给变量赋值了


我在头文件中定义extern uint8_t Crc_counter = 0;//com0校验计数器


我在程序文件中定义了uint8_t Crc_counter = 0;//com0校验计数器


编译的时候就出


.../modbus.h:10: warning: 'Crc_counter' initialized and declared 'extern'


.../modbus.c:28: error: conflicting type qualifiers for 'Uart0_rev_comflag'


../modbus.h:9: error: previous definition of 'Uart0_rev_comflag' was here


解决方法:在头文件中改成extern uint8_t Crc_counter ;//com0校验计数器就可以了


这个错误和上面3的警告是一个事,解决方法一样


 

5.../modbus.c:29: error: conflicting type qualifiers for 'Crc_counter'


../modbus.h:10: error: previous declaration of 'Crc_counter' was here


在头文件中和程序文件中定义的变量类型不一致


我在头文件中定义extern uint8_t Crc_counter = 0;//com0校验计数器


我在程序文件中定义了volatile uint8_t Crc_counter ;//com0校验计数器


编译的时候就出


.../modbus.c:29: error: conflicting type qualifiers for 'Crc_counter'


../modbus.h:10: error: previous declaration of 'Crc_counter' was here


解决方法:都定义成带volatile 或都不带volatile.


 

在调用程序时一定要使对应的数据类型相匹配,不然会出现问题。


 

ICCAVR中编译时,没有此种警告,但在winavr中却出现了下面警告,可见winavr要比ICCAVR的语法要严格很多了。


**********************************************************************


将所有的uchar都改为char,否则出现警告


如在此程序中有如下声明


声明:


void LCD_write_str(uchar X,uchar Y,uchar *s);


调用:


LCD_write_str(0,0,"605987969@qq.com");


编译警告:


warning:pointer targets in passing argument 3 of 'LCD_write_str' differ in signedness


原因分析:


指针所指的符号不一致,在GCC里,unsigned char *,signed char *char *是不同的类型,如果相互赋值会有警告。


void LCD_write_str(uchar X,uchar Y,uchar *s);第三个参数类型是unsigned char *


而:LCD_write_str(0,0,"abcdefg");第三个参数"abcdefg"类型是char *,


char *转递给unsigned char *,发生了数据类型不匹配的问题,因此产生了警告。


 

补充知识:


1GCC默认charsigned char,IARICCAVR默认charunsigned char


2c标准没有定义char必须是有符号的,所以是否有符号取决于编译器编译时你设的参数。


无符号运算往往比有符号运算生成的代码更小,所以makefile/avrstudio工程里可能默认设置char为无符号。 winavr2个参数-funsigned-char-fsigned-char,选择其中之一决定了char的符号,好像在Makefile文件里修改。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条