Microchip Studio 7.0项目移植(从ICC AVR移植到Microchip Studio 7.0)

 Microchip Studio 7.0 系列教程

     1、Microchip Studio 7.0 如何修改字体大小Microchip Studio 7.0 如何修改字体大小

     2、MicroChip Studio 7.0如何快速打开.h文件

     3、Microchip Studio 7.0 文件中如何添加行号

     4、Microchip Studio 7.0项目移植(从ICC AVR移植到Microchip Studio 7.0) 

     5、Microchip Studio 7.0 下载、安装、编译和仿真教程 

     6、Microchip Studio 7.0工程项目如何使用sprintf或memset 

     7、Microchip Studio 7.0项目配置(Optimization(优化)和选择生成HEX文件)

     8、Microchip Studio 7.0工程项目如何添加文件夹,将.C文件存放到分类的文件夹中

     9、Microchip Studio 7.0工程项目如何添加.C文件

   10 、Microchip Studio 7.0 如何添加自定义的.h头文件

   11、Microchip Studio 7.0 如何编译工程项目

   12、GCC AVR(Atmel Studio+ AVR Studio)如何在程序存储器(flash)空间存放字符串常量和使用字符串常量

        从ICC AVR移植到Microchip Studio 7.0要完成以下六方面的移植工作。

        1、MCU头文件的移植。

        2、宏定义macros.h的移植。

        3、延时函数移植。

        4、中断函数的移植。

        5、EEPROM操作函数的移植。

        6、数据在flash区的移植。

一、MCU 头文件移植

        1、在ICC AVR,不同的MCU需要包含不同的头文件。

               例如:MCU为ATMEGA128,需要包含  #include <iom128v.h>

                          MCU为ATMEGA16, 需要包含  #include <iom16v.h>

         2、在Microchip Studio 7.0,所有MCU的头文件都只需要包含 “#include <avr/io.h>” 即可。

#include <avr/io.h>

二、宏定义头文件<macros.h>的移植

        1、在ICC AVR中,头文件<macros.h>包含了#include<AVRdef.h〉,在AVRdef.h中,宏定义了一些常用的汇编指令和一些不常用的函数,参见下面:

        #define WDR()  asm("wdr")
         #define SEI()     asm("sei")
         #define CLI()     asm("cli")
         #define NOP()  asm("nop")
         #define SLEEP()asm("sleep");
         #define_WDR)    asm("wdr")
         #defineSEI()      asm("sei")
         #define CLI()     asm("cli")
         #define NOP()  asm("nop")
         #define_SLEEP()asm("sleep");
         #define BIT(x)  (1<<(x));

        2、在Microchip Studio 7.0中,你就不能直接使用WDR(),SEI(), NOP()啦!因为ICCAVR常包含的文件 #include <macros.h> 和#include<AVRdef.h〉,在Microchip Studio 7.0里面是没有的。

        3、在Microchip Studio 7.0中,你可以先在文件中添加  #include <avr/io.h>,然后直接使用 asm("wdr"),asm("sei"),asm("nop")。

        4、在Microchip Studio 7.0中,使用asm("sei")上述做法比较麻烦。

        我的做法是将这些宏命令添加到一个总的头文件(include.h)中,所有c文件都引用include.h,那么在移植过程中,就不需要修改这方面的代码。

#ifndef __include__
#define  __include__ 

/// include.h      

         #define WDR()  asm("wdr")
         #define SEI()     asm("sei")
         #define CLI()     asm("cli")
         #define NOP()  asm("nop")
         #define SLEEP()asm("sleep");
         #define_WDR)    asm("wdr")
         #defineSEI()      asm("sei")
         #define CLI()     asm("cli")
         #define NOP()  asm("nop")
         #define_SLEEP()asm("sleep");
         #define BIT(x)  (1<<(x));
#endif

三、 延时函数

        1、在ICC AVR中,delay延时函数,需要自己写,往往不准。

        2、在Microchip Studio 7.0中,只需要加载一个头文件 #include <util/delay.h>,就可以使用两个标准的延时函数,分别是

            _delay_ms(double__ms)

            _delay_us(double __us),

        两个函数的参数均为double型的,通常使用整数延时即可。

        比较讨厌一点是,这两个延时函数是基于1MHz的晶振频率,所赋给延时函数的参数值需乘以你所用的晶振频率。

        例如你用14.7456MHz的晶振,延时10ms的函数为_delay_ms(10*14.7456)。我的选择是直接去修改util/delay.h,加入宏定义#define F_CPU 14.7456E6,这样延时10ms的函数写为_delay_ms(10)。这两种方法各有利弊,自己选择。

四、中断函数

        1、例如 T0 溢出中断,在 ICC AVR 中如下定义:

#pragma interrupt_handler timer0_ovf_isr:iv_TIMER0_OVF
void timer0_ovf_isr( void)
{…}

        timer0_ovf_isr 这个函数名是自定义的。

        2、在Microchip Studio 7.0中,首先需加载头文件#include <avr/interrupt.h>,并且函数名为ISR,且中断函数名不可自定义,格式如下:

ISR( TIMER0_OVF_vect )

{…}
TIMER0_OVF_vect 含义同iv_TIMER0_OVF ,是T0溢出中断号。

        不同型号mcu的中断向量号的名称不同,AS的中断向量号请从avr/iomXXX.h中查找。

        例如:atmega128单片机,中断号的名称可以在iom128.h文件中查找,Microchip Studio 7.0的iom128.h文件的路径如下:

 C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATmega_DFP\1.6.364\include\avr

  五、EEPROM操作函数

        1、在ICC AVR中加载头文件#include <eeprom.h>后,可以使用如下两个读写函数:

EEPROM_read(addr, var); //读EEPROM中的一个字节
EEPROM_write(addr, var); //向EEPROM中写入一个字节

        2、在Microchip Studio 7.0中,加载头文件#include <avr/eeprom.h>后,可以使用如下两个读写函数:

_EEGET(var, addr); //读EEPROM中的一个字节
_EEPUT(addr, var); //向EEPROM中写入一个字节

        3、为了移植时不修改代码,我的做法是在总的头文件(include.h)中添加以下宏定义:

#define EEPROM_read(addr, var) _EEGET(var, addr)
#define EEPROM_write(addr, var) _EEPUT(addr, var)

六、定义数据在flash区

        主要用于在字符点阵或图形点阵数据存放在flash区,这样可以减少data区的使用,不至于使data区溢出。
        1、在ICC AVR中,用const关键字定义变量,并在ICC软件设置项中,勾选treat "const" as
__flash即可。

        2、在Microchip Studio 7.0中,需加载头文件#include <avr/pgmspace.h>,并加入以下宏定义:  

#include <avr/pgmspace.h>

       (1)、声明

                    声明时使用PROGMEM关键字

                    例如:声明字节常量

PROGMEM const unsigned char x=1;

                      例如:声明字节一维数组常量

PROGMEM const unsigned char x[5] = { 1, 2, 3, 4, 5 };

                        例如:声明字节多维数组常量

PROGMEM const unsigned char x[3][5] = {
			{ 1, 2, 3, 4, 5 },
			{ 1, 2, 3, 4, 5 },
			{ 1, 2, 3, 4, 5 }
	};

       (2)、flash常量的读取

                    先在ram区定义一个变量,然后使用pgm_read_byte(&)pgm_read_word(&)读取。其中:pgm_read_byte(&)用于读取字节常量,pgm_read_word(&)用于读取字常量。

                     警告:一定要添加&。

                    例如:读取字节常量

PROGMEM const unsigned char x=1;//把数据放到flash
		unsigned char a;//定义一个变量
		a = pgm_read_byte(&x);//取出flash里面的数据到变量a

                      例如:读取字节一维数组常量

PROGMEM const unsigned char x[5] = { 1, 2, 3, 4, 5 };//把数组放到flash
		unsigned char a;//定义一个变量
		a = pgm_read_byte(&x[0]);//取出flash里面的数据(数组的第0个成员)到变量a

                        例如:读取字节多维数组常量

PROGMEM const unsigned char 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


   七、变量优化问题

        ICCAVR运行的好好的,结果移植到Microchip Studio发现出了问题,原因是GCC编译器在函数中定义的变量,经常会被优化掉,导致参数传递不过去,此时只需在定义时添加volatile即可。

        警告:定义变量时,添加volatile关键字,即可防止编译器优化

        例如:

uint8_t volatile USART1_sendPosi = 0;

八、关于prog_uchar关键字

     网上很多人移植ICCAVR到Atmel Studio时,定义数据在flash区时使用了prog_uchar关键字,但是Microchip Studio 7.0已经废弃了prog_uchar关键字,如果使用,编译器会报错。

      Microchip Studio 7.0已经废弃了prog_uchar关键字,如果使用,编译器会报错。

      例如:假如我使用prog_uchar关键字在flash区定义一个常量。

PROGMEM const prog_uchar x[5] = { 1, 2, 3, 4, 5 };

       结果编译后,系统报错,参见下图

九、移植实例

        下面将一个用ICC AVR编写的工程项目移植到Microchip Studio 7.0,所使用的MCU为ATMEGA128。

        (一)、编写include.h

           将所有的宏定义宏命令添加到一个总的头文件(include.h)中,所有c文件都引用include.h,那么在移植过程中,我们将不需要修改这方面的代码。

//=============================================================================================
//下面两条指令是本头部文件条件编译的预处理指令,用于防止本头部文件被其他文件重复引用。
//=============================================================================================
#ifndef  __include_H__				//	条件编译开始
#define __include_H__


#ifndef BIT
#define BIT(x)	(1 << (x))
#endif

#define WDR() 	asm("wdr")
#define SEI()	asm("sei")
#define CLI()	asm("cli")
#define NOP()	asm("nop")
#define SLEEP() 	asm("sleep");
#define _WDR() 	asm("wdr")
#define _SEI()	asm("sei")
#define _CLI()	asm("cli")
#define _NOP()	asm("nop")
#define _SLEEP() 	asm("sleep");

#endif

   

  (二)、将每个.C文件中包含的#include <iom128v.h>和#include <macros.h>屏蔽,替换为#include <avr/io.h>和#include <include.h>

 1、移植前

 2、移植后

         由于#include <include.h>包含了全部宏定义,所以ICC AVR下定义的宏定义移植到Microchip Studio 7.0可以不作任何改动,即:

               SEI(),CLI(),WDR(),NOP(),BIT()   等等可以不用任何改动,直接使用即可。

(三)、移植中断函数

        1、Microchip Studio 7.0下,atmega128单片机的中断号的名称可以在iom128.h文件中查找,microchip Studio 7.0下iom128.h头文件的路径如下

   C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATmega_DFP\1.6.364\include\avr

C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATmega_DFP\1.6.364\include\avr

        2、移植TIMER1比较定时中断

        TIMER1的比较匹配中断号名称为:TIMER1_COMPA_vect,参见下图

(1)、移植前ICC AVR代码如下所示 

(2)、在移植的.C文件首行添加头函数#include <avr/interrupt.h>

  (3)、按照Microchip Studio 7.0中断的要求移植TIMER1比较匹配中断

        3、移植TIMER0溢出定时中断

        TIMER0溢出定时中断号名称为:TIMER0_OVF_vect,参见下图

        (1)、移植前ICC AVR代码如下所示 

 (2)、在移植.C文件首行添加头函数#include <avr/interrupt.h>

 (3)、按照Microchip Studio 7.0中断的要求移植TIMER0溢出定时中断

        3、移植USART0的RX中断

        USART0的RX中断号名称为:USART0_RX_vect。

      (1)、移植前ICC AVR代码如下所示 

      (2)、在移植.C文件首行添加头函数#include <avr/interrupt.h> 

      (3)、按照Microchip Studio 7.0中断的要求移植USART0的RX中断

        4、移植USART0的TX中断

        USART0的TX中断号名称为:USART0_TX_vect。

        (1)、移植前ICC AVR代码如下所示 

       (2)、在移植.C文件首行添加头函数#include <avr/interrupt.h> 

       (3)、按照Microchip Studio 7.0中断的要求移植USART0的TX中断

(四)、移植数据在flash区

       1、在.C文件首部添加头文件#include <avr/pgmspace.h>

        2、const前面添加PROGMEM

       3、当data memory区的变量读取program memory区的数据时,需要添加pgm_read_byte()

     (1)、移植前 ICC AVR程序如下

     (2)、移植后 Microchip Studio 7.0 程序如下

 移植完毕。

最后再次提醒:pgm_read_byte(&)读取字节常量或字节数组

                         pgm_read_word(&)读取字常量或字数组

       

十、编译

        编译移植后的工程项目,编译OK。

致谢:

ICCAVR 与 GCCAVR 程序移植 -新闻中心-济南有人物联网技术有限公司官网 (usr.cn)

(2条消息) 使用ICC AVR过渡到AVR STUDIO_会飞行的小蜗牛的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值