LPC2132 调试记
1、查看快速入门,快速掌握烧写FLASH和JTAG工具,ADS1.2。(相关工具在Software&Driver文件夹下)
(1)LPC2131 FLASH工具:philips公司的LPC2100 Flash Utility V2.2.0 .
(a)波特率设置为9600,时钟设为11050KHZ,time-ou[sec]:2(另外,buffer->flashbuf operation->Download flash可以从flash上下载程序到本机后,再与本机的程序比较是否一致,选择Compare Flash时可以进行flash上程序的校验)
(b)"Upload to Flash"前先要P0.14对地拉低(将ISP(JP1)跳线),程序固化后,将ISP(JP1)跳线帽断开,重新复位系统即可运行程序。LPC2100系列ARM7微控制器芯片具有ISP功能,可以通过串口进行程序下载。(这点非常重要,在我们公司的硬件出板后,我调试板子时,用JTAG调试,程序可以运行,但是用串口下载完程序,重新复位后没有一点反应。后来查过就是硬件设计上没有设置这个跳线。也没有按照如上的要求来进行程序的下载和运行。下载和运行时P0.14脚都为低电平。说明一直是在ISP模式下。)
(2)EasyJTAG-H和H-JTAG可进行硬件仿真调试(不知道有谁知道如何固化,敬请赐教)EasyJtag可以固化,但是我使用时,总是有错误出现,连接不到,网上查过错误原因,很多人有过这样的错误,但是没有找到解决方法。
(3)ADS1.2集成开发环境几个注意点:
(a)Debug Settings ->linker->ARM Linker设置RO(或者指定.scf文件)
(b)Debug 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
FilesH-JTAG V0.3.1目录下的H-JTAG .dll,点击“打开”即可。
Option->configure Target ->Choose Target->H-JTAG
2、快速运行示例代码。在此基础上进行修改可以省去很多时间。移植了UCOS-II操作系统,修改了I2C(模拟I2C),UART0, BEEP(用于测试),中断处理,用一个硬件时钟模拟多个软件时钟。参考网上代码后修改(作者:21icbbs LPC900,2005-08)示例代码见最后例1。
3、开发板上调试完毕后,关键在于板子出来后的调试。此时的问题,可能是硬件,可能是软件。需要软硬件配合调试。做好工作日志,因为此时的问题如果不做好记录,会导致大货时问题没有得到更改。比如前面提到的这次硬件设计上没有设计ISP跳线的问题。另外,开发板上的某些硬件可能与实际板子的有所不同,要稍加注意。如:我们公司出板时用的CPU是LPC2132,与LPC2131的不同是LPC2132是64K+16K,还有时钟更改了,不要忘记在代码中把时钟的值更改过来。其他的基本上没有什么问题,直接移植就可以了。现在还差的就是做个最小文件系统啦(留出一块空间512字节,可存储,可擦除,还要带CRC校验)啊,努力吧。要学的东西太多啦。
4、附带讲一下减少代码的一些办法。
(a)在startup.s中的跳转函数入口,不要写main函数,改为其它名字,也就是把自己的入口函数的名字改掉。因为如果是main入口的话,ads1.2会做一大堆全局变量的COPY和搬移。在用ADS单步调试时会发现在进入main之前会先做_main.这就是在做这些工作。但是如果这样做的话,要记得全局变量和静态变量RODATA段的初始值会丢失,需要在用这些变量前再赋下值。
(b)尽量不用或少用库函数,如atoi,strcmp,strcp等等,而是由自己去实现,这样可以减少链接一些不必要的库文件。
以上二者做的适中的话,可能可以减少10K的代码量
(c)UCOS_II.h中提供了内核裁减的可配置,轻松减少代码。
例1:target.c文件
//定义软件定时器数量(至少1个)
#define TIMER_N8
//定义软件定时器结构
//每个定时器只占用2个字节
struct
{
volatile unsigned TV:32;//32位定时值
unsigned long da
void (*function)(unsigned long);//callback
volatile unsigned TR:1;//起停标志,0-停止运行,1-开始运行
volatile unsigned TF:1;//溢出标志,0-未溢出,1-溢出
}Timer[TIMER_N];
/*
利用定时器T0模拟多个软件定时器
原创作者:21icbbs LPC900,2005-08
更改:May Wong 2008-6-13 (LPC2131)
特点:
只占用一个硬件定时器T0,就可以扩展出多达数十个以上的软件定时器
软件定时器基本定时单位是5ms,定时范围很宽:0.01~163.84s
软件定时器数量可以按需要设定,
利用定时器T0的自动重装特性,能够实现所有软件定时器的精确定时
所有软件定时器都工作在32位倒计时方式,用TR和TF位控制,使用极为方便
第0号定时器专门用于Delay()函数,其它定时器可供用户程序自由使用
*/
/*
函数:TimerOn()
功能:启动定时器
参数:
t:定时器初值,取值0~4294967295
t>0时,定时(0.01*t)s
t=0时,定时163.84s
unsigned long da
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].da
break;
}
}
if (i == TIMER_N)
return -1;
else
returni;
}
/*
函数:TimerOff()
功能:关闭定时器
参数:
n:定时器序号
*/
void TimerOff(unsigned char n)
{
Timer[n].TR = 0;
Timer[n].TF = 0;
}
/*
函数:Delay()
功能:延时0.01~163.84s
参数:
t:延时参数,取值0~16383
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 { //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].da 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[i].TR = 0; Timer[i].TF = 0; Timer[i].TV = 0; } T0IR = 0xffffffff;/*timer intrrupt register1 reset*/ T0PR= 0;/*时钟不分频*/ T0TC = 0;/*counter*/ T0TCR = 0x01;/*counter control reginster 1 reset */ T0MCR = 0x03;/*[0:1] 11tc reset/ intrrupt when match*/ T0MR0 = (Fpclk / OS_TICKS_PER_SEC);/*(Fcclk / 4) * 1/ 2005ms钟定时*/ } /********************************************************************************************************* ** 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" #defineTASK_STK_SIZE64 #defineLEN50 //OS_STKTaskStk[TASK_STK_SIZE]; OS_STKTaskStartStk[TASK_STK_SIZE]; voidTaskStart(void *da #defineBEEP(1<<7)/* P0.7引脚控制BEEPjust 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的第一个任务,通常由它初始化目标板和建立其它任务 **输 入:无 **输 出:无 **全局变量:无 **调用模块: ** ********************************************************************************************************/ voidTaskStart (void *pdata) { pdata = pdata;/*避免编译警告*/ /*test timer0*/ testTimer(); while(1) } /*********************************************************************************************************End Of File***************************
评论