ICCAVR下移植于ATMEGA32的UCOSII

分享到:

费了九牛二虎之力终于把UCOSII移植到M32上了,似乎没有想怪中那么兴奋,只是感觉轻松了许多,因为原本打算是在三个星期前搞定的,想想根本原因是没有把握好调试程序时的一些细节,为了一些不可能的东西在钻牛角尖....

   计算机网络的老师给我们讲过大部人都是"蜗牛"!?,只有少部分人是"老鹰"......"老鹰"可以一下冲上高空,而"蜗牛"只有慢慢地爬,也可以到达山顶.不过我觉得只要蜗牛掌握了正确的方法或许也有机会变成---老鹰!(也许其他的蜗牛们也是这么想的~~)

   废话少说了.其实正确的写法是uC/OS-II,u就是micro的意思,为了方便均用UCOSII代替,要移植UCOSII必须要知道编译器的堆栈情况.ICCAVR的堆栈指针是向下增长的,堆栈指针指向SRAM的最高地址.其堆栈还分为软堆栈和硬堆栈.软堆栈是用于寄存器入栈的,而硬堆栈用于的函数地址进出栈的,函数调用或进出中断函数时会用到.软堆栈实际是分布在硬堆栈的下面.软堆栈用Y寄存器作为指针,硬堆栈用SP为作指针.(不知看懂了没.表达似乎不太好...)其实ICCAVR也附带有移植于M103的UCOSII,不过M103跟M32是有区别的.

   知道了软硬堆栈就好办了,我的程序是从<嵌入式实时操作系统uC/OS-II(第二版)>的实例1直接改过来的,其实例的中8086的SP指针直接用M32的Y寄存器代替,将M32的硬堆栈指针SP保存到软堆栈中,下面是我的一段堆栈初始化的程序:

OS_STK  *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{  
    INT16U tmp;
    INT8U *stk;
    INT8U *hard_stk;  //硬件堆栈指针
    INT16U stk_tmp;  //硬堆栈变量
   opt = opt;  //防止编译器警告
   pdata="pdata";
   stk_tmp=(INT16U)ptos;  //得到硬堆栈的地址
   hard_stk=(INT8U *)ptos;//指向硬堆栈
   stk    = (INT8U *)ptos-40;//指向软堆栈,40为硬堆栈的大小,ICCAVR的help文档上说过,如果函数不是嵌套很大一般用16就够了,这里我用help文档上说的最大的.
    //函数地址入栈
  tmp = *(INT16U const *)task;//得到函数地址,这里参考了ICCAVR里面自带的M103的UCOSII源文件.
  *hard_stk-- = (INT8U)(tmp); //函数地址入栈
  *hard_stk-- = (INT8U)(tmp>> 8);
  stk_tmp=(INT16U)hard_stk;  //得到硬堆栈的地址
    //Rx入栈
    *stk-- = 0;              
    *stk-- = 1;             
    *stk-- = 2;              
    *stk-- = 3;              
    *stk-- = 4;             
    *stk-- = 5;              
    *stk-- = 6;              
    *stk-- = 7;              
    *stk-- = 8;             
    *stk-- = 9;               
    *stk-- = 10;              
    *stk-- = 11;              
    *stk-- = 12;              
    *stk-- = 13;               
    *stk-- = 14;               
    *stk-- = 15;             
    *stk-- = 16;
    *stk-- = 17;
    *stk-- = 18;              
    *stk-- = 19;                                                                                                                       //为了在OS_CPU_A.S文件上方便一点,R20~R23我设置为编译器不使用,这样似乎有点浪费,读者完可以自己改过来.           
    *stk-- = 24;           
    *stk-- = 25;             
    *stk-- = 26;              
    *stk-- = 27;             
    *stk-- = 30;            
    *stk-- = 31;              
    /*SREG入栈*/
   *stk-- =0x80;                  //PUSH SREG
    /*SP入栈*/
    *stk-- = (INT8U)(stk_tmp);      //sp
    *stk = (INT8U)((stk_tmp)>> 8);  //sp
    return ((OS_STK *)stk);
}

  在OS_CPU.H修改相应的定义:

typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;                    /* Unsigned  8 bit quantity                           */
typedef signed   char  INT8S;                    /* Signed    8 bit quantity                           */
typedef unsigned int   INT16U;                   /* Unsigned 16 bit quantity                           */
typedef signed   int   INT16S;                   /* Signed   16 bit quantity                           */
typedef unsigned long  INT32U;                   /* Unsigned 32 bit quantity                           */
typedef signed   long  INT32S;                   /* Signed   32 bit quantity                           */
typedef float          FP32;                     /* Single precision floating point                    */
typedef double         FP64;                     /* Double precision floating point                    */

typedef unsigned char  OS_STK;        /*堆栈入口为8位  Each stack entry is 8-bit wide             */

#define  OS_CRITICAL_METHOD    1                                                                   #define  OS_ENTER_CRITICAL()   asm("cli") /*关中断*/
#define  OS_EXIT_CRITICAL()    asm("sei")   /*开中断*/

#define  OS_TASK_SW()        OSCtxSw();/*暂时直接用函数代替*/

 

     OS_CPU_A.ASM文件直接改成M32相应的汇编,可参考ATMEGA32的技术文档,当然一些伪指令技术文档里面是没有的,可查找相关的书籍.这里也写出来:             

                                  对寄存器作定义:

                                    TCNT0 = $32;
                                     SREG=$3F;
                                     SPH=$3E;
                                     SPL=$3D;

                                  定义宏:

                      .macro XXX  //XXX宏的名字
                          ;写指令
                      .endmacro  //宏结束
  

  M32我用了定时器0,感觉这个8位的定时器一般会少用.直接用Tools菜单下的,Application Builder来生成定时器的在4M晶振下产生100HZ的初始值,误差为0.2% .

   以下是我在Project option下的设置:

    下面是文件摆放:

     附件是我在ICCAVR下移植的M32的源程序,有兴趣的可以下来看看,关掉了绝大部分的功能......只是建立了两个简单任务,不过要对应上面的两个图设置好,带proteus 7.4 SP3仿真.(点rar图标下载)

继续阅读
基于ATmega32单片机的灭火机器人设计与实现

机器人竞赛是近年来迅速开展起来的一种对抗活动,它涉及人工智能、机械、电子、传感器、精密机械等诸多领域。通过竞赛可以培养学生的创新意识、动手能力、团队写作能力等。其中灭火比赛是开展范围最广、影响最大的机器人竞赛项目之一。

基于ATmega32的漏电保护器智能化测试仪的设计

本测试仪操作简单,解决了手动测试方法存在的测量不准确的问题,达到了自动测量的目的,可检测在线与非在线运行的漏电保护器,提高了检测漏电保护器性能的水平,为进行漏电保护器工作性能的研究、品质检验及生产调试提供了技术手段。仪器设计充分利用了ATmega 32内置的各种功能,使硬件电路结构简单,有效提高了仪器的性价比,已在多家企业和科研单位使用,使用结果表明,仪器工作可靠,达到预期的技术指标。

基于AVR单片机的LED显示屏的灰度设计与实现

LED点阵块具有亮度高、发光均匀、可靠性好、拼装方便等优点,能构成各种尺寸的显示屏。目前,LED显示屏已被广泛应用于文字显示并取得了很好的效果,但是大部分仅能显示滚动的文字信息而不能显示图像,并且还

基于ATmega32的遥控采摘机器人设计

针对机器视觉采摘机器存在的技术不成熟,成本过高等不足,提出采用人工操控的半自动采摘技术,并进行了探索研究。设计了一款模拟采摘机器人,机器人以履带底盘为基座,三自由度机械臂,红外遥控操作。硬件电路以ATmega32为系统控制核心,采摘机器人的动作采用BL35P12为核心红外遥控控制。系统软件基于AVR Studio4开发环境,实现对机械臂运动的全方位精确控制。采摘机器人采用模块化设计,抓取速度快,成本低,易于实现,可扩展性强。

Proteus与ICCAVR的联合调试方法

今天给大家介绍一种即能像AVR Studio 一样进行代码级调试,又可以实时看到MCU 状态的软件,Proteus。 大家都知道ICC-AVR 不能进行代码调试,很多人都选择了AVRS

©2018 Microchip Corporation
facebook google plus twitter linkedin youku weibo rss