• LPC2132 调试记 (转)


      from: http://www.cnblogs.com/appleit666/archive/2008/06/13/1218795.html
    LPC2132 调试记

    最近公司开发一个新项目,出于成本的考虑,要求空间只能是32K+8K。选用LPC2131(ARM7 微控制器芯片芯片),同时也选择了UCOS-II实时操作系统。移植整个操作系统加上一些必备的驱动,总共花了12K。现在作个小结,简单的介绍下整个流程。(写得非常肤浅,新手而已,只是因为以前调过LPC2100开发板,所以经理将这个任务交给了我)(以前的项目是数据采集系统。上位机用的三星的 S3C2410LINUX2.6.x内核,用QToptia用户界面+sqlite数据库,底层是SOCKET编程,下位机是菲利浦的LPC2100,主要用于采 集数据和AD转换(OSusLinux, SOCKET编程+底层ADC驱动))

    1、查看快速入门,快速掌握烧写FLASHJTAG工具,ADS1.2。(相关工具在Software&Driver文件夹下)

     (1)LPC2131 FLASH 工具:philips公司的LPC2100 Flash Utility V2.2.0 .
         a)波特率设置为9600,时钟设为11050KHZtime-ou[sec]:2(另外,buffer->flashbuf operation->Download flash 可以从flash上下载程序到本机后,再与本机的程序比较是否一致,选择Compare Flash时可以进行flash上程序的校验)
             (b) "Upload to Flash"前先要P0.14对地拉低(将ISPJP1)跳线),程序固化后,将ISPJP1)跳线帽断开,重新复位系统即可运行程序。LPC2100 系列ARM7 微控制器芯片具有ISP 功能,可以通过串口进行程序下载。(这点非常重要,在我们公司的硬件出板后,我调试板子时,用JTAG调试,程序可以运行,但是用串口下载完程序,重新复位后没有一点反应。后来查过就是硬件设计上没有设置这个跳线。也没有按照如上的要求来进行程序的下载和运行。下载和运行时P0.14脚都为低电平。说明一直是在ISP模式下。)
      

    2EasyJTAG-HH-JTAG可进行硬件仿真调试(不知道有谁知道如何固化,敬请赐教)EasyJtag可以固化,但是我使用时,总是有错误出现,连接不到,网上查过错误原因,很多人有过这样的错误,但是没有找到解决方法。

     

    3ADS1.2集成开发环境几个注意点:

    aDebug Settings ->linker->ARM Linker设置RO(或者指定.scf文件)

    bDebug Settings ->Target->Target Settings->Post-Linker (ARM fromELF)

     (c)  Debug Settings ->Liker->ARM fromELF 指定output format(Intel 32 bit Hex)

          output file name(/xx/xx/xxx.hex)

     (d)指定生成的文件夹为DebugInRam,如果是RelInFlash的话,会对芯片加密,需

    要用ISP全局擦除后,才能恢复JTAG 调试及ISP 读/写操作。

     (e) ADX 配置好调试目标。Option->configure Target->ADD-> D:"Program

    Files"H-JTAG V0.3.1目录下的H-JTAG .dll,点击打开即可。

    Option->configure Target ->Choose Target->H-JTAG

     

    2、快速运行示例代码。在此基础上进行修改可以省去很多时间。移植了UCOS-II操作系统,修改了I2C(模拟I2C),UART0, BEEP(用于测试),中断处理,用一个硬件时钟模拟多个软件时钟。参考网上代码后修改(作者:21icbbs LPC9002005-08)示例代码见最后例1

    3、开发板上调试完毕后,关键在于板子出来后的调试。此时的问题,可能是硬件,可能是软件。需要软硬件配合调试。做好工作日志,因为此时的问题如果不做好记录,会导致大货时问题没有得到更改。比如前面提到的这次硬件设计上没有设计ISP跳线的问题。另外,开发板上的某些硬件可能与实际板子的有所不同,要稍加注意。如:我们公司出板时用的CPULPC2132,与LPC2131的不同是LPC213264K+16K,还有时钟更改了,不要忘记在代码中把时钟的值更改过来。其他的基本上没有什么问题,直接移植就可以了。现在还差的就是做个最小文件系统啦(留出一块空间512字节,可存储,可擦除,还要带CRC校验)啊,努力吧。要学的东西太多啦。

    4、附带讲一下减少代码的一些办法。

    a)在startup.s中的跳转函数入口,不要写main函数,改为其它名字,也就是把自己的入口函数的名字改掉。因为如果是main入口的话,ads1.2会做一大堆全局变量的COPY和搬移。在用ADS单步调试时会发现在进入main之前会先做_main.这就是在做这些工作。但是如果这样做的话,要记得全局变量和静态变量RODATA段的初始值会丢失,需要在用这些变量前再赋下值。

    (b)尽量不用或少用库函数,如atoi,strcmp,strcp等等,而是由自己去实现,这样可以减少链接一些不必要的库文件。

    以上二者做的适中的话,可能可以减少10K的代码量

    cUCOS_II.h中提供了内核裁减的可配置,轻松减少代码。

    1 target.c文件

    //定义软件定时器数量(至少1个)

    #define TIMER_N   8

    //定义软件定时器结构

    //每个定时器只占用2个字节

    struct

    {

           volatile unsigned TV:32;        //32位定时值

         unsigned long data;            //作为参数被传入定时器处理函数

         void (*function)(unsigned long); //callback

         volatile unsigned TR:1;          //起停标志,0-停止运行,1-开始运行

         volatile unsigned TF:1;          //溢出标志,0-未溢出,1-溢出

     }Timer[TIMER_N];

    /*

          利用定时器T0模拟多个软件定时器

    原创作者:21icbbs LPC9002005-08

    更改:May Wong 2008-6-13 (LPC2131)

    特点:

         只占用一个硬件定时器T0,就可以扩展出多达数十个以上的软件定时器

         软件定时器基本定时单位是5ms,定时范围很宽:0.01163.84s

         软件定时器数量可以按需要设定,

         利用定时器T0的自动重装特性,能够实现所有软件定时器的精确定时

         所有软件定时器都工作在32位倒计时方式,用TRTF位控制,使用极为方便

         0号定时器专门用于Delay()函数,其它定时器可供用户程序自由使用

    */

    /*

    函数:TimerOn()

    功能:启动定时器

    参数: 

                       t:定时器初值,取值04294967295

                       t>0时,定时(0.01*t)s

                      t=0时,定时163.84s

                unsigned long data                :作为参数被传入定时器处理函数

               void (*function)(unsigned long): callback function

                return -1(error)      else 定时器序号

    */

    int TimerOn(unsigned int t,unsigned long funpara,void(*function)(unsigned long))

    {

        unsigned int i;

         INT32U da_year,da_mon,da_day,ti_hour,ti_min,ti_sec;   /*test start time*/

         for (i = 1; i < TIMER_N;i++)

         {

                  

             if (Timer[i].TR == 0)

             {

                 //Timer[i].TR = 0;

                 Timer[i].TF = 0;

                 Timer[i].TV = t;

                 Timer[i].TR = 1;

                 Timer[i].function = function;

                 Timer[i].data = funpara;

                  break;

             }

         }

        if (i == TIMER_N)

                  return -1;

         else

               return i;

    }

    /*

    函数:TimerOff()

    功能:关闭定时器

    参数:

         n:定时器序号

    */

    void TimerOff(unsigned char n)

    {

         Timer[n].TR = 0;

         Timer[n].TF = 0;

    }

    /*

    函数:Delay()

    功能:延时0.01163.84s

    参数:

         t:延时参数,取值016383

         t>0时,延时(0.01*t)s

         t=0时,延时163.84s

    */

    void Delay(unsigned int t)

    {

        Timer[0].TR = 0;

        Timer[0].TF = 0;

        Timer[0].TV = t;

         Timer[0].TR = 1;

        // TimerOn(t,NULL,NULL);

         for (;;)

         {

             //PCON |= 0x01;

             T0TCR |= 0x01; /*reset*/

             if (Timer[0].TF)

             {

                 TimerOff(0);

                 break;

             }

         }

    }

    /*********************************************************************************************************

    ** Function name:                Timer0_Exception

    **

    ** Descriptions:                   Timer0 interrupt service function

    **

    ** input parameters:             None

    ** Returned value:                None

    **        

    ** Used global variables:       None

    ** Calling modules:               None

    **

    **------------------------------------------------------------------------------------------------------

    ********************************************************************************************************/

    /*

    函数:Timer0_Exception()

    功能:定时器中断服务函数,每(Fcclk / 4) * 1/ 200中断1

    */

    void Timer0_Exception(void)

    {

         //unsigned char i;

         unsigned int i;

         //TF2 = 0;

       

         for ( i=0; i<TIMER_N; i++ )

         {

             //beep();              //beep ok

        

             if (Timer[i].TR)

             {

                  

                 if ( --Timer[i].TV == 0 )

                 {

                     UART0Putch('0');

                     Timer[i].TF = 1;

                            TimerOff(i);

                          (Timer[i].function)(Timer[i].data);

                            UART0Putch('0');

                              // beep();

                              //UART0Putch('0');         

                       }

                 

            }

       }

        T0IR = 0x01;              /* match tunnel 1 intrrupt flag 清除中断标*/   

        VICVectAddr = 0;            //interrupt close 通知中断控制器中断结束   

        OSTimeTick();

    }

    /*********************************************************************************************************

    ** Function name:                Timer0Init

    **

    ** Descriptions:                   Initialize the Time0

    **

    ** input parameters:             None

    ** Returned value:                None

    **        

    ** Used global variables:       None

    ** Calling modules:               None

    **-------------------------------------------------------------------------------------------------------

    ** Modified by:

    ** Modified date:

    **------------------------------------------------------------------------------------------------------

    ********************************************************************************************************/

            void Timer0Init(void)

    {

         unsigned int x;

         unsigned char i;

           for ( i=0; i<TIMER_N; i++ )

         {

             Timer[i].TR = 0;

             Timer[i].TF = 0;

             Timer[i].TV = 0;

         }

             

        T0IR = 0xffffffff;           /*timer intrrupt register   1 reset*/

        T0PR   = 0;                     /* 时钟不分频*/ 

        T0TC = 0;                     /*counter*/

        T0TCR = 0x01;             /*counter control reginster 1 reset */

        T0MCR = 0x03;             /*[0:1] 11   tc reset/ intrrupt when match*/

        T0MR0 = (Fpclk / OS_TICKS_PER_SEC);    /*(Fcclk / 4) * 1/ 200 5ms 钟定时*/ 

     }

    /*********************************************************************************************************

    ** Function name:                VICInit

    **

    ** Descriptions:                   Initialize the Interrupt Vevtor Controller

    **

    ** input parameters:             None

    ** Returned value:                None

    **        

    ** Used global variables:       None

    ** Calling modules:               None

    **

    **------------------------------------------------------------------------------------------------------

    ********************************************************************************************************/

            void VICInit(void)

    {

        extern void IRQ_Handler(void);

        extern void Timer0_Handler(void);

        extern void I2c_Handler(void);

    #if 0

      extern void UART0_Handler(void);

      #endif

        VICIntEnClr = 0xffffffff;                   /*clear interrupt*/

        VICDefVectAddr = (uint32)IRQ_Handler;

        VICVectAddr0 = (uint32)Timer0_Handler;/* 设置中断服务程序地址             */

        VICVectCntl0 = (0x20 | 0x04);             /* 设置定时器0中断通道分配最高优先级*/

        VICIntEnable = 1 << 4;                         /* 使能定时器0中断

     /*I2c*/

       VICVectAddr12 = (uint32)I2c_Handler;

        VICVectCntl12 = (0x20 | 9);

    #if 0

     /*Uart*/

        VICVectAddr14 = (uint32)UART0_Handler;

        VICVectCntl14 = (0x20 | 0x06);

        VICIntEnable = 1 << 6;

    #endif

     }

    /*********************************************************************************************************

    ** Function name:                TargetInit

    **

    ** Descriptions:                   Initialize the target board; it is called in a necessary place, change it as

    **                                              needed

    **

    ** input parameters:             None

    ** Returned value:                None

    **        

    ** Used global variables:       None

    ** Calling modules:               None

    **

    ********************************************************************************************************/

     void TargetInit(void)

    {

        OS_ENTER_CRITICAL();

        srand((uint32) TargetInit);

        VICInit();

        Timer0Init();

        I2cInit(100000);

       UART0Init(115200);

        OS_EXIT_CRITICAL();

    }

    Main中测试代码如下:

    #include "config.h"

    #define TASK_STK_SIZE                  64

    #define   LEN                                    50

    //OS_STK        TaskStk[TASK_STK_SIZE];

    OS_STK        TaskStartStk[TASK_STK_SIZE];

    void TaskStart(void *data);

    #define     BEEP   (1<<7)           /* P0.7引脚控制BEEP just test I2C */

    void initbeep()

     {

            /* 关闭BEEP */

          IO0DIR |= BEEP;                                                        /* 设置BEEP控制口为输出 */

          PINSEL0 = (PINSEL0 & 0xffff3fff);

          IO0SET = BEEP;  

     }

    void beep()

    {

            /*for test*/

            IO0CLR = BEEP;

            OSTimeDly(OS_TICKS_PER_SEC / 2);                                              /* 蜂鸣器响一声 */

            IO0SET = BEEP; 

    }

    /*********************************************************************************************************

    ** 函数名称: main

    ** 功能描述: c语言的主函数,由它启动多任务环境

    ** 输 入:

    ** 输 出:

    ** 全局变量:

    ** 调用模块: PC_DispClrScr,OSInit,OSTaskCreate,OSStart

    **------------------------------------------------------------------------------------------------------

    ********************************************************************************************************/

     int main (void)

    {

         OSInit();

        TargetInit();

        initbeep();

        OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 5);

       OSStart();

        return 0;

    }

    void testfun3(unsigned long para)

    {

        UART0Putch('3');

    }

    void testTimer()

    {

         /* -1 not enough timer else return timer No.*/

           if(TimerOn(800,10,testfun3) == -1)      

                  beep();           

           else

                  UART0Putch('n');      //ok 

    }

    /*********************************************************************************************************

    ** 函数名称: TaskStart

    ** 功能描述: μCOS-II的第一个任务,通常由它初始化目标板和建立其它任务

    ** 输 入:

    ** 输 出:

    ** 全局变量:

    ** 调用模块:

    **

    ********************************************************************************************************/

    void TaskStart (void *pdata)

    {

        pdata = pdata;                                        /* 避免编译警告 */

      /*test timer0*/

       testTimer();

       while(1)

    }

    /*********************************************************************************************************        End Of File***************************

  • 相关阅读:
    springmvc log4j 配置
    intellij idea maven springmvc 环境搭建
    spring,property not found on type
    intellij idea maven 工程生成可执行的jar
    device eth0 does not seem to be present, delaying initialization
    macos ssh host配置及免密登陆
    centos7 搭建 docker 环境
    通过rest接口获取自增id (twitter snowflake算法)
    微信小程序开发体验
    gitbook 制作 beego 参考手册
  • 原文地址:https://www.cnblogs.com/xinjie/p/1546383.html
Copyright © 2020-2023  润新知