打印

关于ARM7上电启动的问题,谢谢帮助!

[复制链接]
2879|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
s700|  楼主 | 2011-9-24 13:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 s700 于 2011-9-24 13:50 编辑

芯片是LPC2368, 其中P2.0--P2.7各接上一个led,高电平点亮,即是端口输出‘1’,相应led亮。
写了一个跑马灯的程序,但是系统没一点反应,下载程序到目标板后Keil显示正常,显示如下:
Erase Done.
Programming Done.
Verify OK.
Application running ...

我运用keil写的程序,启动代码采用Keil自带的LPC2300.s。个人感觉是上电芯片未启动的问题,不知道是否正确,希望各位大神指点一下,谢过了。
程序如下:
#include "lpc23xx.h"

typedef unsigned long DWORD;
typedef char BYTE;

#define I_Bit   0x80
#define F_Bit   0x40
#define VIC_SIZE 32
#define TIMER0_INT  4

#define SYS32Mode  0x1F
#define IRQ32Mode  0x12
#define FIQ32Mode  0x11

#define FALSE 0
#define TRUE 1

#define HIGHEST_PRIORITY 0x01
#define LOWEST_PRIORITY  0x0F

#define VECT_ADDR_INDEX 0x100
#define VECT_PRIO_INDEX 0x200

#define Fcclk 48000000
#define Fpclk (Fcclk / 2)
#define TIME_INTERVAL (Fpclk/100 - 1)

static DWORD sysreg;
#define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode }
#define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg }

volatile DWORD timer0_counter;

void Timer0Handler (void) __irq
{  
  T0IR = 1;   
  IENABLE;   
  timer0_counter++;
  IDISABLE;
  VICVectAddr = 0;
}
DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority )
{
    DWORD *vect_addr;
    DWORD *vect_prio;
      
    VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */
    if ( IntNumber >= VIC_SIZE )
    {
  return ( FALSE );
    }
    else
    {
   vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4);
  vect_prio = (DWORD *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + IntNumber*4);
  *vect_addr = (DWORD)HandlerAddr;
  *vect_prio = Priority;
  VICIntEnable = 1 << IntNumber;
  return( TRUE );
    }
}
DWORD init_timer ( BYTE timer_num, DWORD TimerInterval )  
{
  if ( timer_num == 0 )
  {
timer0_counter = 0;
T0MR0 = TimerInterval;
T0MCR = 3;   
if ( install_irq( TIMER0_INT, (void *)Timer0Handler, HIGHEST_PRIORITY ) == FALSE )
{
   return (FALSE);
}  
else
{
   return (TRUE);
}
  }
  return (FALSE);
}

#define FAST_PORT  0x01
#define REGULAR_PORT 0x02

#define DIR_OUT   0x01
#define DIR_IN   0x02

#define HS_PORT_DIR_BASE   FIO_BASE_ADDR + 0x00
#define HS_PORT_DIR_INDEX   0x20
#define GPIOM   0x00000001

void GPIOInit( DWORD PortNum, DWORD PortType, DWORD PortDir )
{
  if ( (PortType == FAST_PORT) && (PortNum == 2))
  {
if ( (PortNum == 0) || (PortNum == 1) )
{
   SCS |= GPIOM;
}
if ( PortDir == DIR_OUT )
{
   (*(volatile unsigned long *)(HS_PORT_DIR_BASE
   + PortNum * HS_PORT_DIR_INDEX)) = 0xFFFFFFFF;
}
else
{
   (*(volatile unsigned long *)(HS_PORT_DIR_BASE
   + PortNum * HS_PORT_DIR_INDEX)) = 0x00000000;
    }
  }
  return;
}

#define PLL_MValue   11
#define PLL_NValue   0
#define CCLKDivValue  5
#define USBCLKDivValue  5

void ConfigurePLL ( void )
{
  DWORD MValue, NValue;
  if ( PLLSTAT & (1 << 25) )
  {
PLLCON = 1;   
PLLFEED = 0xaa;
PLLFEED = 0x55;
  }
  PLLCON = 0;   
  PLLFEED = 0xaa;
  PLLFEED = 0x55;
   
  SCS |= 0x20;   
  while( !(SCS & 0x40) );
  CLKSRCSEL = 0x1;
  PLLCFG = PLL_MValue | (PLL_NValue << 16);
  PLLFEED = 0xaa;
  PLLFEED = 0x55;
      
  PLLCON = 1;   
  PLLFEED = 0xaa;
  PLLFEED = 0x55;
  CCLKCFG = CCLKDivValue;
#if USE_USB
  USBCLKCFG = USBCLKDivValue;  
#endif
  while ( ((PLLSTAT & (1 << 26)) == 0) );   
  MValue = PLLSTAT & 0x00007FFF;
  NValue = (PLLSTAT & 0x00FF0000) >> 16;
  while ((MValue != PLL_MValue) && ( NValue != PLL_NValue) );
  PLLCON = 3;   
  PLLFEED = 0xaa;
  PLLFEED = 0x55;
  while ( ((PLLSTAT & (1 << 25)) == 0) );
  return;
}
void enable_timer( BYTE timer_num )
{
  if ( timer_num == 0 )
  {
T0TCR = 1;   
  }
  else
  {
T1TCR = 1;
  }
  return;
}
void GPIOResetInit( void )
{
  PINSEL0 = 0x00000000;
  PINSEL1 = 0x00000000;
  PINSEL2 = 0x00000000;
  PINSEL3 = 0x00000000;
  PINSEL4 = 0x00000000;
  PINSEL5 = 0x00000000;
  PINSEL6 = 0x00000000;
  PINSEL7 = 0x00000000;
  PINSEL8 = 0x00000000;
  PINSEL9 = 0x00000000;
  PINSEL10 = 0x00000000;
   
  IODIR0 = 0x00000000;
  IODIR1 = 0x00000000;
  IOSET0 = 0x00000000;
  IOSET1 = 0x00000000;
   
  FIO0DIR = 0x00000000;
  FIO1DIR = 0x00000000;
  FIO2DIR = 0x00000000;
  FIO3DIR = 0x00000000;
  FIO4DIR = 0x00000000;
   
  FIO0SET = 0x00000000;
  FIO1SET = 0x00000000;
  FIO2SET = 0x00000000;
  FIO3SET = 0x00000000;
  FIO4SET = 0x00000000;
  return;        
}
void init_VIC(void)
{
    DWORD i = 0;
    DWORD *vect_addr, *vect_prio;
   
    VICIntEnClr = 0xffffffff;  
    VICVectAddr = 0;   
    VICIntSelect = 0;  
    for ( i = 0; i < VIC_SIZE; i++ )      {
  vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + i*4);    vect_prio = (DWORD *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + i*4);  
  *vect_addr = 0x0;
  *vect_prio = 0xF;
    }
    return;
}

void TargetResetInit(void)
{
#ifdef __DEBUG_RAM   
  MEMMAP = 0x2;  
#endif
#ifdef __DEBUG_FLASH   
  MEMMAP = 0x1;  
#endif
#if USE_USB
  PCONP |= 0x80000000;  
#endif
   ConfigurePLL();
  #if (Fpclk / (Fcclk / 4)) == 1
  PCLKSEL0 = 0x00000000;
  PCLKSEL1 = 0x00000000;
#endif
#if (Fpclk / (Fcclk / 4)) == 2
  PCLKSEL0 = 0xAAAAAAAA;
  PCLKSEL1 = 0xAAAAAAAA;  
#endif
#if (Fpclk / (Fcclk / 4)) == 4
  PCLKSEL0 = 0x55555555;
  PCLKSEL1 = 0x55555555;
#endif
    MAMCR = 0;
#if Fcclk < 20000000
  MAMTIM = 1;
#else
#if Fcclk < 40000000
  MAMTIM = 2;
#else
  MAMTIM = 3;
#endif
#endif
  MAMCR = 2;
  GPIOResetInit();
  init_VIC();
  return;
}
int main(void)
{
   DWORD counter;
   init_timer( 0, TIME_INTERVAL );
   
   GPIOInit( 2, FAST_PORT, DIR_OUT );
   enable_timer( 0 );
   counter = 0;
   FIO2SET = 1 << counter;
   
   while(1)
   {
     if ( timer0_counter >= (0x20 * counter) )
{
   FIO2SET = 1 << counter;
   counter++;
   if ( counter > 8 )
   {
  counter = 0;
  timer0_counter = 0;
  FIO2CLR = 0x000000FF;
   }
}
  }
  return 0;
}

相关帖子

沙发
hnylcxq| | 2011-9-25 21:37 | 只看该作者
keil环境下开发,怎么这么麻烦啊?是不是没有板级支持包啊,我用的ADS,好像大部分工作都背ADS给完成了,没见过点亮一个灯要这么复杂的啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

8

帖子

1

粉丝