• 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***************************

  • 相关阅读:
    poj2623
    poj2635
    案例解析丨 Spark Hive 自定义函数应用
    云图说 | 华为云GPU共享型AI容器,让你用得起,用得好,用的放心
    云小课 |选定合适的证书,做“有证”的合规域名
    记一次 node 项目重构改进
    SpringBoot写后端接口,看这一篇就够了!
    如何让知识图谱告诉你“故障根因”
    我敢说,这个版本的斗地主你肯定没玩过?
    5 分钟带你掌握 Makefile 分析
  • 原文地址:https://www.cnblogs.com/xinjie/p/1546383.html
Copyright © 2020-2023  润新知