Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2259090
  • 博文数量: 187
  • 博客积分: 1457
  • 博客等级: 上尉
  • 技术积分: 2423
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-13 09:41
个人简介

如需要绘制PCB,设计电路可以和我联系。sunhenu@163.com.

文章分类

全部博文(187)

文章存档

2017年(2)

2016年(2)

2015年(7)

2014年(13)

2013年(80)

2012年(83)

分类: LINUX

2012-04-17 09:36:20

继续看target.C,配置完了PLL,下面的就简单一些了,

GPIOResetInit();看名字,就知道干啥的,不说了。

init_VIC();初始化VIC函数,这个还是要说一下的啊,后面使用中断,经常遇到,很重要。

它被定义在irq.c中,

 

******************************************************************************

** Function name:   init_VIC

**

** Descriptions:    Initialize VIC interrupt controller.

** parameters:      None

** Returned value:    None

**

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

void init_VIC(void)

{

DWORD i = 0;

DWORD *vect_addr, *vect_cntl;

 

  /* initialize VIC*/

  VICINTENCLEAR = 0xffffffff;

  VICADDRESS = 0;

  VICINTSELECT = 0;

 

  /* set all the vector and vector control register to 0 */

  for ( i = 0; i < VIC_SIZE; i )

  {

    vect_addr = (DWORD *)(VIC_BASE_ADDR VECT_ADDR_INDEX i*4);

    vect_cntl = (DWORD *)(VIC_BASE_ADDR VECT_CNTL_INDEX i*4);

    *vect_addr = 0x0;

    *vect_cntl = 0xF;

  }

  return;

}

 

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

** Function name:   install_irq

**

** Descriptions:    Install interrupt handler

** parameters:      Interrupt number, interrupt handler address,

**            interrupt priority

** Returned value:    true or false, return false if IntNum is out of range

**

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

DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority )

{

  DWORD *vect_addr;

  DWORD *vect_cntl;

 

  VICINTENCLEAR = 1 << IntNumber; /* Disable Interrupt */

  if ( IntNumber >= VIC_SIZE )

  {

    return ( FALSE );

  }

  else

  {

    /* find first un-assigned VIC address for the handler */

    vect_addr = (DWORD *)(VIC_BASE_ADDR VECT_ADDR_INDEX IntNumber*4);

    vect_cntl = (DWORD *)(VIC_BASE_ADDR VECT_CNTL_INDEX IntNumber*4);

    *vect_addr = (DWORD)HandlerAddr;  /* set interrupt vector */

    *vect_cntl = Priority;

    VICINTENABLE = 1 << IntNumber;  /* Enable Interrupt */

    return( TRUE );

  }

}

 

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

**                            End Of File

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

 

先看void init_VIC(void)

 

VICINTENCLEAR = 0xffffffff;

VICADDRESS = 0;

VICINTSELECT = 0;

不说了,直接上图,继续是英文,呵呵,不管做硬件设计,还是软件设计,诸位还是去适应英文吧,原因……,大家都懂。

 

接下来是个for循环

  /* set all the vector and vector control register to 0 */

  for ( i = 0; i < VIC_SIZE; i )

  {

    vect_addr = (DWORD *)(VIC_BASE_ADDR VECT_ADDR_INDEX i*4);

    vect_cntl = (DWORD *)(VIC_BASE_ADDR VECT_CNTL_INDEX i*4);

    *vect_addr = 0x0;

    *vect_cntl = 0xF;

  }

注释解释的很清楚,简单明了,其实我们自己再写程序的时候,规范的话,要加上注释,哪怕简单的几个单词也可以,这样既方便自己调试,也方便别人配合,个人观点的啊。

这里主要说一下VIC_BASE_ADDRVECT_ADDR_INDEX这几个宏定义

#define VIC_SIZE    32

#define VIC_BASE_ADDR ((unsigned int)&VICIRQSTATUS)

#define VECT_ADDR_INDEX 0x100

#define VECT_CNTL_INDEX 0x200

VIC_BASE_ADDR 值其实就是0xFFFFF000 ,就是寄存器的地址,也就是指针,所以for循环在赋值的时候,使用了*,因为你是给寄存器赋值,不可以给寄存器地址赋值,在这个LPC2368芯片中这个寄存器地址是确定了的。

 

VIC相关控制器的地址排列很有规律的,下面是LPC2378.H的内容,我可以使用一基地址,然后加上一些索引,或者说固定的差值,可以很方便的设置各个寄存器。下面的寄存器地址都是相差0x04

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

 **

 ** VIC

 **

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

__IO_REG32_BIT(VICIRQSTATUS,          0xFFFFF000,__READ       ,__vicint_bits);

__IO_REG32_BIT(VICFIQSTATUS,          0xFFFFF004,__READ       ,__vicint_bits);

__IO_REG32_BIT(VICRAWINTR,            0xFFFFF008,__READ       ,__vicint_bits);

__IO_REG32_BIT(VICINTSELECT,          0xFFFFF00C,__READ_WRITE ,__vicint_bits);

__IO_REG32_BIT(VICINTENABLE,          0xFFFFF010,__READ_WRITE ,__vicint_bits);

__IO_REG32_BIT(VICINTENCLEAR,         0xFFFFF014,__WRITE      ,__vicint_bits);

__IO_REG32_BIT(VICSOFTINT,            0xFFFFF018,__READ_WRITE ,__vicint_bits);

__IO_REG32_BIT(VICSOFTINTCLEAR,       0xFFFFF01C,__WRITE      ,__vicint_bits);

__IO_REG32_BIT(VICPROTECTION,         0xFFFFF020,__READ_WRITE ,__vicprotection_bits);

__IO_REG32_BIT(VICSWPRIORITYMASK,     0xFFFFF024,__READ_WRITE ,__vicswprmask_bits);

__IO_REG32(    VICVECTADDR0,          0xFFFFF100,__READ_WRITE);

__IO_REG32(    VICVECTADDR1,          0xFFFFF104,__READ_WRITE);

__IO_REG32(    VICVECTADDR2,          0xFFFFF108,__READ_WRITE);

__IO_REG32(    VICVECTADDR3,          0xFFFFF10C,__READ_WRITE);

__IO_REG32(    VICVECTADDR4,          0xFFFFF110,__READ_WRITE);

__IO_REG32(    VICVECTADDR5,          0xFFFFF114,__READ_WRITE);

__IO_REG32(    VICVECTADDR6,          0xFFFFF118,__READ_WRITE);

__IO_REG32(    VICVECTADDR7,          0xFFFFF11C,__READ_WRITE);

__IO_REG32(    VICVECTADDR8,          0xFFFFF120,__READ_WRITE);

__IO_REG32(    VICVECTADDR9,          0xFFFFF124,__READ_WRITE);

__IO_REG32(    VICVECTADDR10,         0xFFFFF128,__READ_WRITE);

__IO_REG32(    VICVECTADDR11,         0xFFFFF12C,__READ_WRITE);

__IO_REG32(    VICVECTADDR12,         0xFFFFF130,__READ_WRITE);

__IO_REG32(    VICVECTADDR13,         0xFFFFF134,__READ_WRITE);

__IO_REG32(    VICVECTADDR14,         0xFFFFF138,__READ_WRITE);

__IO_REG32(    VICVECTADDR15,         0xFFFFF13C,__READ_WRITE);

__IO_REG32(    VICVECTADDR16,         0xFFFFF140,__READ_WRITE);

__IO_REG32(    VICVECTADDR17,         0xFFFFF144,__READ_WRITE);

__IO_REG32(    VICVECTADDR18,         0xFFFFF148,__READ_WRITE);

__IO_REG32(    VICVECTADDR19,         0xFFFFF14C,__READ_WRITE);

__IO_REG32(    VICVECTADDR20,         0xFFFFF150,__READ_WRITE);

__IO_REG32(    VICVECTADDR21,         0xFFFFF154,__READ_WRITE);

__IO_REG32(    VICVECTADDR22,         0xFFFFF158,__READ_WRITE);

__IO_REG32(    VICVECTADDR23,         0xFFFFF15C,__READ_WRITE);

__IO_REG32(    VICVECTADDR24,         0xFFFFF160,__READ_WRITE);

__IO_REG32(    VICVECTADDR25,         0xFFFFF164,__READ_WRITE);

__IO_REG32(    VICVECTADDR26,         0xFFFFF168,__READ_WRITE);

__IO_REG32(    VICVECTADDR27,         0xFFFFF16C,__READ_WRITE);

__IO_REG32(    VICVECTADDR28,         0xFFFFF170,__READ_WRITE);

__IO_REG32(    VICVECTADDR29,         0xFFFFF174,__READ_WRITE);

__IO_REG32(    VICVECTADDR30,         0xFFFFF178,__READ_WRITE);

__IO_REG32(    VICVECTADDR31,         0xFFFFF17C,__READ_WRITE);

__IO_REG32_BIT(VICVECTPRIORITY0,      0xFFFFF200,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY1,      0xFFFFF204,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY2,      0xFFFFF208,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY3,      0xFFFFF20C,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY4,      0xFFFFF210,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY5,      0xFFFFF214,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY6,      0xFFFFF218,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY7,      0xFFFFF21C,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY8,      0xFFFFF220,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY9,      0xFFFFF224,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY10,     0xFFFFF228,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY11,     0xFFFFF22C,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY12,     0xFFFFF230,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY13,     0xFFFFF234,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY14,     0xFFFFF238,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY15,     0xFFFFF23C,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY16,     0xFFFFF240,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY17,     0xFFFFF244,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY18,     0xFFFFF248,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY19,     0xFFFFF24C,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY20,     0xFFFFF250,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY21,     0xFFFFF254,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY22,     0xFFFFF258,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY23,     0xFFFFF25C,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY24,     0xFFFFF260,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY25,     0xFFFFF264,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY26,     0xFFFFF268,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY27,     0xFFFFF26C,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY28,     0xFFFFF270,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY29,     0xFFFFF274,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY30,     0xFFFFF278,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32_BIT(VICVECTPRIORITY31,     0xFFFFF27C,__READ_WRITE ,__vicvectpr_bits);

__IO_REG32(    VICADDRESS,            0xFFFFFF00,__READ_WRITE);

 

好了VIC初始化就到这里,在这个.C文件里,还有一个函数

DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority )

注释也说得很明白

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

** Function name:   install_irq

**

** Descriptions:    Install interrupt handler

** parameters:      Interrupt number, interrupt handler address, interrupt priority

** Returned value:    true or false, return false if IntNum is out of range

**

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

这个函数有3个行参,第一个是中断号,第二个是指向中断函数的指针,也可以说中断函数的地址,第三个是定义这个中断的优先级。

其他的不说,说最要紧的,

/* find first un-assigned VIC address for the handler */

    vect_addr = (DWORD *)(VIC_BASE_ADDR VECT_ADDR_INDEX IntNumber*4);

    vect_cntl = (DWORD *)(VIC_BASE_ADDR VECT_CNTL_INDEX IntNumber*4);

    *vect_addr = (DWORD)HandlerAddr;  /* set interrupt vector */

    *vect_cntl = Priority;

VICINTENABLE = 1 << IntNumber;  /* Enable Interrupt */

 

看到了把,中断号是什么意思了,就是类似索引的东西,乘以差值,就是其对应的寄存器地址,比如说我们这个demo程序使用的timer0,你去查看

Timer0bit4,所以相应的中断号也就是4.

*vect_addr = (DWORD)HandlerAddr;  /* set interrupt vector */

这个语句就是把中断函数地址赋值到中断地址寄存器中,一旦,中断发生,cpu就会找到这个函数,然后执行,也就是响应了中断吧,这个更具体的,后面结合timer说说。

好了,TargetResetInit();终于说完了。

这里说明一下,因为这个文章,是学习笔记,所以中间有些概念或者说法有问题,请诸位指正,我呢,个人观点,不喜欢去死扣概念什么的,软件就是要灵活一些。

主函数中还有GPIOInit( 1, REGULAR_PORT, DIR_OUT, BEEP_MASK);这句,

你到fio.C中间看看代码,就明白它是什么意思了,就是普通端口和快速端口的设置不多说,

但是要注意一点,比如我们前面提到的P1.27驱动蜂鸣器,如果你设置了P1.27为普通端口,那么你在给P1.27赋值就要使用BEEP_IO,同样设置为快速端口,赋值使用BEEP_FIO,其他的参数同样,否则P1.27电平不会变化。具体的就自己去manul lpc23xx.pdf看吧,其实这里也提到了一个学习方法,自学新的芯片, 自己对照pdf文档,一步一步的来,很容易看懂。

等到以后我介绍ADUC842的时候就会使用这样的方法,今天就这样吧,我还要工作呢,不然老板有意见呢。

阅读(2235) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

星期五啦2012-04-18 21:42:03

恩恩,楼主分析的不错,多看看别人的东西,很有好处啊

sunhenu2012-04-18 08:33:48

新手来鸟: 自学新的芯片, 自己对照pdf文档,一步一步的来,很容易看懂。这个向往更深的学呢.....
如何你不想去做产品系统的构建,你还想在芯片这个范围多努力,那你就去研究嵌入式吧,ARM,MIPS,POWERPC,这些架构的芯片,都可以嵌入系统LINUX,UCOS,这样它们就可以实现比较完善的功能了,还可以加入显示界面,像QT,现在android很火,有完整的一套开发工具,你可以自己把握。以后的文章,我把我以前使用立宇泰的一个板子,做的linux和QT,一些文档整理一下,放到这个博客,可以参考一下,当然了,有些东西我也是参考别人的,然后自己动手在板子上调试通过的。

sunhenu2012-04-18 08:29:38

新手来鸟: 自学新的芯片, 自己对照pdf文档,一步一步的来,很容易看懂。这个向往更深的学呢.....
在深一点就是,你把这个芯片的绝大部分功能,都自己编辑程序,调试一边,IIC,SPI,UART,USB,CAN,NET,等等,在接下来,你就是要跳出芯片这个范围了,从整体或者说系统把握了,因为你学习芯片,是为了设计一个项目,或者说一个产品,那么这个产品,有哪些功能,分成哪些模块,模块之间如何通信,也就是说,它们如何协调到一起,这些就是更深的了,系统构建,要考虑很多事情。

新手来鸟2012-04-17 21:46:23

自学新的芯片, 自己对照pdf文档,一步一步的来,很容易看懂。这个向往更深的学呢