如需要绘制PCB,设计电路可以和我联系。sunhenu@163.com.
分类: 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_ADDR和VECT_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,你去查看
Timer0是bit4,所以相应的中断号也就是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的时候就会使用这样的方法,今天就这样吧,我还要工作呢,不然老板有意见呢。
sunhenu2012-04-18 08:33:48