共2条
1/1 1 跳转至页
ARM ARM菜鸟中断系统提高班学习笔记
问
/*----------------------------------------------------------------------
ARM菜鸟外部中断及中断控制提高班学习结业笔记
HotPower@126.com 2005.7.22 于西安大雁塔村队部
-----------------------------------------------------------------------*/
/***********************************************************************/
/* This file is part of the CA ARM C Compiler package */
/* Copyright KEIL ELEKTRONIK GmbH 2002 - 2004 */
/***********************************************************************/
/* */
/* MAIN.C: Demonstration of various interrupt functions */
/* */
/***********************************************************************/
#include <LPC213x.H> // Philips Peripheral Registers
#include "LPC213xDEF.H" //ARM菜鸟HotPower创建定义文件
/*
* software interrupt function accept parameters and run in
* supervisor mode (interrupt protected).
*/
int myfunc1 (int i1, long i2) __swi (8) {
return (i1 / i2);
}
int myfunc2 (int i1) __swi (9) {
return (i1<<4);
}
void SetVICProtection(unsigned long val) __swi (10) {
VICProtection = val;//VICProtection可以随意置'1',但清'0'必须在管理模式下
}
/*
*具有特权保护的用户非向量中断,它只能在VICProtection=0时在用户模式下调用,比SWI更安全
*/
void UserDefineIRQ (void) __irq {
if (VICIRQStatus & (1 << VICIntSel_SoftInt31)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << VICIntSel_SoftInt31); //清除VICIntSel_SoftInt31中断标志
VICSoftIntClr = (1 << VICIntSel_SoftInt31);
}
VICVectAddr = 0;
}
/*
* standard interrupt function saves only R0 - R12 and returns with
*/
void DefaultIRQ (void) __irq {//VICIntSelect=0且VICVectCntl0~VICVectCntl15都未中断使能
unsigned long temp;
temp = VICIRQStatus;
if (temp & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
EXTINT = (1 << EINT0); //清除INT0中断标志
}
else if (temp & (1 << VICIntSel_EINT1)) {
IOPIN1 ^= (1 << P1_17); //取反P1.17
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
}
else if (temp & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
EXTINT = (1 << EINT2); //清除INT2中断标志
}
else if (temp & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << EINT3); //清除INT3中断标志
}
VICSoftIntClr = temp;
VICVectAddr = 0;
}
void EINT0IRQ (void) __irq {//IRQ中断函数EINT0IRQ被挂接在VICVectCntl0
if (VICIRQStatus & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
}
VICSoftIntClr = (1 << VICIntSel_EINT0);
EXTINT = (1 << EINT0); //清除INT0中断标志
VICVectAddr = 0;
}
void EINT1IRQ (void) __irq {//IRQ中断函数EINT1IRQ被挂接在VICVectCntl1
if (VICIRQStatus & (1 << VICIntSel_EINT1)) {
IOSET1 = (1 << P1_17); //P1.17=1
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
IOCLR1 = (1 << P1_17); //P1.17=0
VICSoftIntClr = (1 << VICIntSel_EINT1);
}
VICVectAddr = 0;
}
void EINT2IRQ (void) __irq {//IRQ中断函数EINT2IRQ被挂接在VICVectCntl2
if (VICIRQStatus & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
}
EXTINT = (1 << EINT2); //清除INT2中断标志
VICSoftIntClr = (1 << VICIntSel_EINT2);
VICVectAddr = 0;
}
void EINT3IRQ (void) __irq {//IRQ中断函数EINT3IRQ被挂接在VICVectCntl3
if (VICIRQStatus & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
}
EXTINT = (1 << EINT3); //清除INT3中断标志
VICSoftIntClr = (1 << VICIntSel_EINT3);
VICVectAddr = 0;
}
/*
* fast interrupt function saves only R0 - R7 and returns with
*/
void FIQ_Handler (void) __fiq {//VICIntSelect非0
unsigned temp;
temp = VICFIQStatus;
if (temp & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
EXTINT = (1 << EINT0); //清除INT0中断标志
}
else if (temp & (1 << VICIntSel_EINT1)) {
IOSET1 = (1 << P1_17); //P1.17=1
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
IOCLR1 = (1 << P1_17); //P1.17=0
}
else if (temp & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
EXTINT = (1 << EINT2); //清除INT2中断标志
}
else if (temp & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << EINT3); //清除INT3中断标志
}
VICSoftIntClr = temp;
VICVectAddr = 0;
}
/*
* task functions have no register save/restore and no return.
*/
void tsk (void) __task {
while (1);
}
/*
* Sample 'main' function
*/
int res;
void main (void) {
IODIR1 = (1 << P1_23) | (1 << P1_22) | (1 << P1_21) | (1 << P1_20)
|(1 << P1_19) | (1 << P1_18) | (1 << P1_17) | (1 << P1_16);//设置LED输出方式
PINSEL0 |= (P0_14_EINT1 << P0_14_PINSEL) //选择P0.14为INT1外部中断引脚
// | (P0_7_EINT2 << P0_7_PINSEL) //选择P0.7为INT2外部中断引脚
| (P0_15_EINT2 << P0_15_PINSEL); //选择P0.15为INT2外部中断引脚
// | (P0_9_EINT3 << P0_9_PINSEL) //选择P0.9也为INT3外部中断引脚
// | (P0_1_EINT0 << P0_1_PINSEL) //选择P0.1也为INT0外部中断引脚
// | (P0_3_EINT1 << P0_3_PINSEL); //选择P0.3也为INT1外部中断引脚
PINSEL1 |= (P0_16_EINT0 << P0_16_PINSEL) //选择P0.16为INT0外部中断引脚
// | (P0_20_EINT3 << P0_20_PINSEL) //选择P0.20也为INT3外部中断引脚
| (P0_30_EINT3 << P0_30_PINSEL);//选择P0.30也为INT3外部中断引脚(Keil仿真不了)
EXTPOLAR &= ~((1 << EXTPOLAR0) //INT0为低电平有效
| (1 << EXTPOLAR1) //INT1为低电平有效
| (1 << EXTPOLAR2) //INT2为低电平有效
| (1 << EXTPOLAR3));//INT3为低电平有效
EXTPOLAR |= (1 << EXTPOLAR0); //INT0为高电平有效
EXTMODE |= (1 << EXTMODE0) //设置INT0为边沿触发
| (1 << EXTMODE2) //设置INT2为边沿触发
| (1 << EXTMODE3);//设置INT3为边沿触发
EXTMODE &= ~(1 << EXTMODE1);//设置INT1为电平触发
VICVectCntl0 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT0;//获取EINT0的IRQ级别
VICVectAddr0 = (unsigned long *) &EINT0IRQ;//取INT0中断服务地址
VICVectCntl1 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT1;//获取EINT1的IRQ级别
VICVectAddr1 = (unsigned long *) &EINT1IRQ;//取INT1中断服务地址
VICVectCntl2 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT2;//获取EINT2的IRQ级别
VICVectAddr2 = (unsigned long *) &EINT2IRQ;//取INT2中断服务地址
VICVectCntl3 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT3;//获取EINT3的IRQ级别
VICVectAddr3 = (unsigned long *) &EINT3IRQ;//取INT3中断服务地址
VICVectCntl4 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_SoftInt31;//获取VICIntSel_SoftInt31的IRQ级别
VICVectAddr4 = (unsigned long *) &UserDefineIRQ;//取VicInt31中断服务地址
// VICVectCntl0 &= ~VICIntSel_Enable;//放弃EINT0的IRQ级别,获取默认中断级别
VICVectCntl1 &= ~VICIntSel_Enable;//放弃EINT1的IRQ级别,获取默认中断级别
// VICVectCntl2 &= ~VICIntSel_Enable;//放弃EINT2的IRQ级别,获取默认中断级别
VICDefVectAddr = (unsigned long *) &DefaultIRQ;//取默认中断服务地址
VICIntSelect = 0;//全部中断为IRQ中断或默认中断
/*
VICIntSelect = (1 << VICIntSel_EINT0) //设置EINT0为FIQ中断
| (1 << VICIntSel_EINT1) //设置EINT1为FIQ中断
| (1 << VICIntSel_EINT2) //设置EINT2为FIQ中断
| (1 << VICIntSel_EINT3);//设置EINT2为FIQ中断
*/
EXTINT = (1 << EINT0) | (1 << EINT1) | (1 << EINT2) | (1 << EINT3); //清除INT中断标志
// VICSoftIntClr = 0xffffffff;//清除所有软中断标志
VICSoftIntClr = (1 << VICIntSel_EINT0) //清除EINT0软中断标志
| (1 << VICIntSel_EINT1) //清除EINT1软中断标志
| (1 << VICIntSel_EINT2) //清除EINT2软中断标志
| (1 << VICIntSel_EINT3);//清除EINT3软中断标志
VICIntEnable = (1 << VICIntSel_EINT0) //使能EINT0中断
| (1 << VICIntSel_EINT1) //使能EINT1中断
| (1 << VICIntSel_EINT2) //使能EINT2中断
| (1 << VICIntSel_EINT3);//使能EINT3中断
VICIntEnable |= (1 << VICIntSel_SoftInt31);//使能VICIntSel_SoftInt31中断
SetVICProtection(1);//打开特权保护,阻止VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_EINT0);//(VICIntEnable & (1 << VICIntSel_EINT0))使能才能软中断
SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_EINT1);//(VICIntEnable & (1 << VICIntSel_EINT1))使能才能软中断
SetVICProtection(1);//打开特权保护,阻止VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_EINT2);//(VICIntEnable & (1 << VICIntSel_EINT2))使能才能软中断
SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_EINT3);//(VICIntEnable & (1 << VICIntSel_EINT3))使能才能软中断
SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_SoftInt31);//(VICIntEnable & (1 << VICIntSel_SoftInt31))使能才能软中断
res = myfunc1 (10, 2); // call SWI functions
res += myfunc2 (res);
while (1); // endless loop
} 答 1: LPC213XDEF.H头文件/*----------------------------------------------------
文 件 名: LPC213XDEF.H
创 建 人: ARM菜鸟 HotPower@126.com
创 建 日 期: 2005.7.23 0:38
最近修改日期: 2005.7.23 10:38
创 建 地 点 : 西安大雁塔村队部
说 明 : 未经过硬件调试
------------------------------------------------------*/
#ifndef __LPC213xDEF_H
#define __LPC213xDEF_H
#define BV(val) (1 << val)
#define VICIntSel_Watchdog 0//看门狗中断(WDINT)
#define VICIntSel_SoftInt1 1//保留给软件中断
#define VICIntSel_DbgCommRx 2//ARM内核中断
#define VICIntSel_DbgCommTx 3//ARM内核中断
#define VICIntSel_Time0 4//定时器0中断
#define VICIntSel_Time1 5//定时器1中断
#define VICIntSel_UART0 6//UART0中断
#define VICIntSel_UART1 7//UART1中断
#define VICIntSel_PWM0 8//PWM0中断
#define VICIntSel_I2C0 9//I2C0中断
#define VICIntSel_SPI0 10//SPI0中断
#define VICIntSel_SSP 11//SSP中断
#define VICIntSel_SPI1 11//SPI1中断
#define VICIntSel_PLL 12//PLL中断
#define VICIntSel_RTC 13//RTC中断
#define VICIntSel_EINT0 14//系统控制外部中断0
#define VICIntSel_EINT1 15//系统控制外部中断1
#define VICIntSel_EINT2 16//系统控制外部中断2
#define VICIntSel_EINT3 17//系统控制外部中断3
#define VICIntSel_ADC0 18//A/D转换器0中断
#define VICIntSel_I2C1 19//I2C1中断
#define VICIntSel_BOD 20//掉电检测中断
#define VICIntSel_ADC1 21//A/D转换器1中断
#define VICIntSel_SoftInt22 22//保留给软件中断
#define VICIntSel_SoftInt23 23//保留给软件中断
#define VICIntSel_SoftInt24 24//保留给软件中断
#define VICIntSel_SoftInt25 25//保留给软件中断
#define VICIntSel_SoftInt26 26//保留给软件中断
#define VICIntSel_SoftInt27 27//保留给软件中断
#define VICIntSel_SoftInt28 28//保留给软件中断
#define VICIntSel_SoftInt29 29//保留给软件中断
#define VICIntSel_SoftInt30 30//保留给软件中断
#define VICIntSel_SoftInt31 31//保留给软件中断
#define VICIntSel_Enable 32//
/*
P0口GPIO位寻址位定义
*/
#define P0_0 0//P0.0
#define P0_1 1//P0.1
#define P0_2 2//P0.2
#define P0_3 3//P0.3
#define P0_4 4//P0.4
#define P0_5 5//P0.5
#define P0_6 6//P0.6
#define P0_7 7//P0.7
#define P0_8 8//P0.8
#define P0_9 9//P0.9
#define P0_10 10//P0.10
#define P0_11 11//P0.11
#define P0_12 12//P0.12
#define P0_13 13//P0.13
#define P0_14 14//P0.14
#define P0_15 15//P0.15
#define P0_16 16//P0.16
#define P0_17 17//P0.17
#define P0_18 18//P0.18
#define P0_19 19//P0.19
#define P0_20 20//P0.20
#define P0_21 21//P0.21
#define P0_22 22//P0.22
#define P0_23 23//P0.23
#define P0_24 24//P0.24
#define P0_25 25//P0.25
#define P0_26 26//P0.26
#define P0_27 27//P0.27
#define P0_28 28//P0.28
#define P0_29 29//P0.29
#define P0_30 30//P0.30
#define P0_31 31//P0.31
/*
P1口GPIO位寻址位定义
*/
#define P1_0 0//P1.0
#define P1_1 1//P1.1
#define P1_2 2//P1.2
#define P1_3 3//P1.3
#define P1_4 4//P1.4
#define P1_5 5//P1.5
#define P1_6 6//P1.6
#define P1_7 7//P1.7
#define P1_8 8//P1.8
#define P1_9 9//P1.9
#define P1_10 10//P1.10
#define P1_11 11//P1.11
#define P1_12 12//P1.12
#define P1_13 13//P1.13
#define P1_14 14//P1.14
#define P1_15 15//P1.15
#define P1_16 16//P1.16
#define P1_17 17//P1.17
#define P1_18 18//P1.18
#define P1_19 19//P1.19
#define P1_20 20//P1.20
#define P1_21 21//P1.21
#define P1_22 22//P1.22
#define P1_23 23//P1.23
#define P1_24 24//P1.24
#define P1_25 25//P1.25
#define P1_26 26//P1.26
#define P1_27 27//P1.27
#define P1_28 28//P1.28
#define P1_29 29//P1.29
#define P1_30 30//P1.30
#define P1_31 31//P1.31
/*
外部中断标志寄存器EXTINT位定义
*/
#define EINT0 0//EXTINT.0//写'1'清除EINT0中断标志
#define EINT1 1//EXTINT.1//写'1'清除EINT1中断标志
#define EINT2 2//EXTINT.2//写'1'清除EINT2中断标志
#define EINT3 3//EXTINT.3//写'1'清除EINT3中断标志
/*
外部中断方式寄存器EXTMODE位定义
*/
#define EXTMODE0 0//EXTMODE.0//该位为0时,EINT0使用电平激活;该位为1时,EINT0使用边沿激活。
#define EXTMODE1 1//EXTMODE.1//该位为0时,EINT1使用电平激活;该位为1时,EINT1使用边沿激活。
#define EXTMODE2 2//EXTMODE.2//该位为0时,EINT2使用电平激活;该位为1时,EINT2使用边沿激活。
#define EXTMODE3 3//EXTMODE.3//该位为0时,EINT3使用电平激活;该位为1时,EINT3使用边沿激活。
/*
外部中断极性寄存器EXTPOLAR位定义
*/
#define EXTPOLAR0 0//EXTPOLAR.0//该位为0时,EINT0低电平或下降沿有效(由EXTMODE0决定)。
//该位为1时,EINT0高电平或上升沿有效(由EXTMODE0决定)。
#define EXTPOLAR1 1//EXTPOLAR.1//该位为0时,EINT1低电平或下降沿有效(由EXTMODE1决定)。
//该位为1时,EINT1高电平或上升沿有效(由EXTMODE1决定)。
#define EXTPOLAR2 2//EXTPOLAR.2//该位为0时,EINT2低电平或下降沿有效(由EXTMODE2决定)。
//该位为1时,EINT2高电平或上升沿有效(由EXTMODE2决定)。
#define EXTPOLAR3 3//EXTPOLAR.3//该位为0时,EINT3低电平或下降沿有效(由EXTMODE3决定)。
//该位为1时,EINT3高电平或上升沿有效(由EXTMODE3决定)。
/*
外部中断唤醒寄存器EXTWAKE位定义
*/
#define EXTWAKE0 0//EXTWAKE.0//该位为1时,使能EINT0将处理器从掉电模式唤醒。
#define EXTWAKE1 1//EXTWAKE.1//该位为1时,使能EINT1将处理器从掉电模式唤醒。
#define EXTWAKE2 2//EXTWAKE.2//该位为1时,使能EINT2将处理器从掉电模式唤醒。
#define EXTWAKE3 3//EXTWAKE.3//该位为1时,使能EINT3将处理器从掉电模式唤醒。
#define BODWAKE 14//EXTWAKE.14//该位为1时,BOD中断产生时可将处理器从掉电模式唤醒。
#define RTCWAKE 15//EXTWAKE.15//该位为1时,RTC中断产生时可将处理器从掉电模式唤醒。
/*
GPIO管脚功能配置
应用示例:
PINSEL0 |= (P0_0_TXD0 << P0_0_PINSEL) | (P0_1_RXD0 << P0_1_PINSEL); //选择P0.0和P0.1为UART0的输出输入引脚
或:
PINSEL0 |= (TXD0 << P0_0_PINSEL) | (RXD0 << P0_1_PINSEL); //选择P0.0和P0.1为UART0的输出输入引脚
PINSEL0 |= (P0_3_EINT1 << P0_3_PINSEL); //选择P0.3为INT1外部中断引脚
PINSEL0 |= (P0_14_EINT1 << P0_14_PINSEL); //选择P0.14也可为INT1外部中断引脚
PINSEL0 |= (P0_1_EINT0 << P0_1_PINSEL) //选择P0.1为INT0外部中断引脚
PINSEL1 |= (P0_16_EINT0 << P0_16_PINSEL); //选择P0.16也可为INT0外部中断引脚
注:由于INT0,INT1可配置多个引脚,故不能简化,必须指明引脚号
PINSEL0 |= (EINT1 << P0_3_PINSEL); //出错
PINSEL0 |= (EINT1 << P0_14_PINSEL); //出错
因为P0_3_EINT1=3,P0_14_EINT1=2.故功能虽然相同,但功能序号不同!!!
*/
#define P0_0_GPIO 0//通用数字输入输出管脚
#define TXD0 1//UART0的发送器输出
#define PWM1 2//脉宽调制器输出1
#define P0_0_TXD0 1//UART0的发送器输出
#define P0_0_PWM1 2//脉宽调制器输出1
#define P0_0_PINSEL 2 * P0_0
#define P0_1_GPIO 0//通用数字输入输出管脚
#define RXD0 1//UART0的接收器输入
#define PWM3 2//脉宽调制器输出3
#define P0_1_RXD0 1//UART0的接收器输入
#define P0_1_PWM3 2//脉宽调制器输出3
#define P0_1_EINT0 3//**外部中断0输入
#define P0_1_PINSEL 2 * P0_1
#define P0_2_GPIO 0//通用数字输入输出管脚
#define SCL0 1//I2C0时钟输入/输出。开漏输出(符合I2C规范)
#define P0_2_SCL0 1//I2C0时钟输入/输出。开漏输出(符合I2C规范)
#define P0_2_CAP0_0 2//***定时器0的捕获输入通道0
#define P0_2_PINSEL 2 * P0_2
#define P0_3_GPIO 0//通用数字输入输出管脚
#define SDA0 1//I2C0数据输入/输出。开漏输出(符合I2C规范)
#define P0_3_SDA0 1//I2C0数据输入/输出。开漏输出(符合I2C规范)
#define P0_3_MAT0_0 2//**定时器0的匹配输出通道0
#define P0_3_EINT1 3//**外部中断1输入
#define P0_3_PINSEL 2 * P0_3
#define P0_4_GPIO 0//通用数字输入输出管脚
#define SCK0 1//SPI0的串行时钟。SPI时钟从主机输出,从机输入
#define AD0_6 3//A/D转换器0输入6。该模拟输入总是连接到相应的管脚
#define P0_4_SCK0 1//SPI0的串行时钟。SPI时钟从主机输出,从机输入
#define P0_4_CAP0_1 2//**定时器0的捕获输入通道1
#define P0_4_AD0_6 3//A/D转换器0输入6。该模拟输入总是连接到相应的管脚
#define P0_4_PINSEL 2 * P0_4
#define P0_5_GPIO 0//通用数字输入输出管脚
#define MISO0 1//SPI0主机输入从机输出端。从机到主机的数据传输
#define P0_5_MISO0 1//SPI0主机输入从机输出端。从机到主机的数据传输
#define P0_5_MAT0_1 2//**定时器0的匹配输出通道1
#define P0_5_AD0_7 3//A/D转换器0输入7。该模拟输入总是连接到相应的管脚
#define P0_5_PINSEL 2 * P0_5
#define P0_6_GPIO 0//通用数字输入输出管脚
#define MOSI0 1//SPI0主机输出从机输入端。主机到从机的数据传输
#define P0_6_MOSI0 1//SPI0主机输出从机输入端。主机到从机的数据传输
#define P0_6_CAP0_2 2//***定时器0的捕获输入通道2
#define P0_6_AD1_0 3//A/D转换器1输入0。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_6_PINSEL 2 * P0_6
#define P0_7_GPIO 0//通用数字输入输出管脚
#define SSEL0 1//SPI0从机选择。选择SPI接口用作从机
#define PWM2 2//脉宽调制器输出2
#define P0_7_SSEL0 1//SPI0从机选择。选择SPI接口用作从机
#define P0_7_PWM2 2//脉宽调制器输出2
#define P0_7_EINT2 3//**外部中断2输入
#define P0_7_PINSEL 2 * P0_7
#define P0_8_GPIO 0//通用数字输入输出管脚
#define TXD1 1//UART1的发送器输出
#define PWM4 2//脉宽调制器输出4
#define AD1_1 3//A/D转换器1输入1。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_8_TXD1 1//UART1的发送器输出
#define P0_8_PWM4 2//脉宽调制器输出4
#define P0_8_AD1_1 3//A/D转换器1输入1。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_8_PINSEL 2 * P0_8
#define P0_9_GPIO 0//通用数字输入输出管脚
#define RXD1 1//UART1的接收器输入
#define PWM6 2//脉宽调制器输出6
#define P0_9_RXD1 1//UART1的接收器输入
#define P0_9_PWM6 2//脉宽调制器输出6
#define P0_9_EINT3 3//***外部中断3输入
#define P0_9_PINSEL 2 * P0_9
#define P0_10_GPIO 0//通用数字输入输出管脚
#define RTS1 1//UART1请求发送出端(仅用于LP138)
#define CAP1_0 2//定时器1的捕获输入通道0
#define AD1_2 3//A/D转换器1输入2。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_10_RTS1 1//UART1请求发送出端(仅用于LP138)
#define P0_10_CAP1_0 2//定时器1的捕获输入通道0
#define P0_10_AD1_2 3//A/D转换器1输入2。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_10_PINSEL 2 * P0_10
#define P0_11_GPIO 0//通用数字输入输出管脚
#define CTS1 1//UART1清除发送入端(仅用于LP138)
#define CAP1_1 2//定时器1的捕获输入通道1
#define SCL1 3//I2C1时钟输入/输。开漏输出(符合I2C规范)
#define P0_11_CTS1 1//UART1清除发送入端(仅用于LP138)
#define P0_11_CAP1_1 2//定时器1的捕获输入通道1
#define P0_11_SCL1 3//I2C1时钟输入/输。开漏输出(符合I2C规范)
#define P0_11_PINSEL 2 * P0_11
#define P0_12_GPIO 0//通用数字输入输出管脚
#define DSR1 1//UART1数据设置就绪端(仅用于 LPC2138)
#define MAT1_0 2//定时器1的匹配输出通道0
#define AD1_3 3//A/D转换器1输入3。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_12_DSR1 1//UART1数据设置就绪端(仅用于 LPC2138)
#define P0_12_MAT1_0 2//定时器1的匹配输出通道0
#define P0_12_AD1_3 3//A/D转换器1输入3。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_12_PINSEL 2 * P0_12
#define P0_13_GPIO 0//通用数字输入输出管脚
#define DTR1 1//UART1数据终端就绪
#define MAT1_1 2//定时器1的匹配输出通道1
#define AD1_4 3//A/D转换器1输入4。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_13_DTR1 1//UART1数据终端就绪
#define P0_13_MAT1_1 2//定时器1的匹配输出通道1
#define P0_13_AD1_4 3//A/D转换器1输入4。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_13_PINSEL 2 * P0_13
#define P0_14_GPIO 0//通用数字输入输出管脚
#define DCD1 1//UART1数据载波检测输入(仅用于 LPC2138)
#define SDA1 3//I2C1数据输入/输出。开漏输出(符合I2C规范)
#define P0_14_DCD1 1//UART1数据载波检测输入(仅用于 LPC2138)
#define P0_14_EINT1 2//**外部中断1输入
#define P0_14_SDA1 3//I2C1数据输入/输出。开漏输出(符合I2C规范)
#define P0_14_PINSEL 2 * P0_14
#define P0_15_GPIO 0//通用数字输入输出管脚
#define RI1 1//UART1铃响指示输入(仅用于 LPC2138)
#define AD1_5 3//A/D转换器1输入5。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_15_RI1 1//UART1铃响指示输入(仅用于 LPC2138)
#define P0_15_EINT2 2//**外部中断2输入
#define P0_14_AD1_5 3//A/D转换器1输入5。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_15_PINSEL 2 * P0_15
#define P0_16_GPIO 0//通用数字输入输出管脚
#define P0_16_EINT0 1//**外部中断0输入
#define P0_16_MAT0_2 2//**定时器0的匹配输出通道2
#define P0_16_CAP0_2 3//***定时器0的捕获输入通道2
#define P0_16_PINSEL 2 * P0_0
#define P0_17_GPIO 0//通用数字输入输出管脚
#define SCK1 2//SPI1的串行时钟。SPI时钟从主机输出,从机输入
#define P0_17_CAP1_2 1//**定时器1的捕获输入通道2
#define P0_17_SCK1 2//SPI1的串行时钟。SPI时钟从主机输出,从机输入
#define P0_17_MAT1_2 3//**定时器1的匹配输出通道2
#define P0_17_PINSEL 2 * P0_1
#define P0_18_GPIO 0//通用数字输入输出管脚
#define MISO1 2//SPI1主机输入从机输出端。从机到主机的数据传输
#define P0_18_CAP1_3 1//**定时器1的捕获输入通道3
#define P0_18_MISO1 2//SPI1主机输入从机输出端。从机到主机的数据传输
#define P0_18_MAT1_3 3//**定时器1的匹配输出通道3
#define P0_18_PINSEL 2 * P0_2
#define P0_19_GPIO 0//通用数字输入输出管脚
#define MOSI1 2//SPI1主机输出从机输入端。主机到从机的数据传输
#define P0_19_MAT1_2 1//**定时器1的匹配输出通道2
#define P0_18_MOSI1 2//SPI1主机输出从机输入端。主机到从机的数据传输
#define P0_19_CAP1_2 3//**定时器1的捕获输入通道2
#define P0_19_PINSEL 2 * P0_3
#define P0_20_GPIO 0//通用数字输入输出管脚
#define SSEL1 2//SPI1从机选择。选择SPI接口用作从机
#define P0_20_MAT1_3 1//**定时器1的匹配输出通道3
#define P0_20_SSEL1 2//SPI1从机选择。选择SPI接口用作从机
#define P0_20_EINT3 3//***外部中断3输入
#define P0_20_PINSEL 2 * P0_4
#define P0_21_GPIO 0//通用数字输入输出管脚
#define PWM5 1//脉宽调制器输出5
#define AD1_6 2//A/D转换器1输入6。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_21_PWM5 1//脉宽调制器输出5
#define P0_21_AD1_6 2//A/D转换器1输入6。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_21_CAP1_3 3//**定时器1的捕获输入通道3
#define P0_21_PINSEL 2 * P0_5
#define P0_22_GPIO 0//通用数字输入输出管脚
#define AD1_7 1//A/D转换器1输入7。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_22_AD1_7 1//A/D转换器1输入7。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_22_CAP0_0 2//***定时器0的捕获输入通道0
#define P0_22_MAT0_0 3//**定时器0的匹配输出通道0
#define P0_22_PINSEL 2 * P0_6
#define P0_23_GPIO 0//通用数字输入输出管脚
#define P0_23_PINSEL 2 * P0_7
//#define P0_24_GPIO 0//P0.24 脚未用
//#define P0_24_PINSEL 2 * P0_8
#define P0_25_GPIO 0//通用数字输入输出管脚
#define AD0_4 1//A/D转换器0输入4。该模拟输入总是连接到相应的管脚.D/A 转换器输出(仅用于 LPC2138)
#define P0_25_AD0_4 1//A/D转换器0输入4。该模拟输入总是连接到相应的管脚.D/A 转换器输出(仅用于 LPC2138)
#define P0_25_PINSEL 2 * P0_9
#define P0_26_GPIO 0//通用数字输入输出管脚
#define AD0_5 1//A/D转换器0输入5。该模拟输入总是连接到相应的管脚
#define P0_26_AD0_5 1//A/D转换器0输入5。该模拟输入总是连接到相应的管脚
#define P0_26_PINSEL 2 * P0_10
#define P0_27_GPIO 0//通用数字输入输出管脚
#define AD0_0 1//A/D转换器0输入0。该模拟输入总是连接到相应的管脚
#define P0_27_AD0_0 1//A/D转换器0输入0。该模拟输入总是连接到相应的管脚
#define P0_27_CAP0_1 2//**定时器0的捕获输入通道1
#define P0_27_MAT0_1 3//**定时器0的捕获输入通道1
#define P0_27_PINSEL 2 * P0_11
#define P0_28_GPIO 0//通用数字输入输出管脚
#define AD0_1 1//A/D转换器0输入1。该模拟输入总是连接到相应的管脚
#define P0_28_AD0_1 1//A/D转换器0输入1。该模拟输入总是连接到相应的管脚
#define P0_28_CAP0_2 2//***定时器0的捕获输入通道2
#define P0_28_MAT0_2 3//**定时器0的匹配输出通道2
#define P0_28_PINSEL 2 * P0_12
#define P0_29_GPIO 0//通用数字输入输出管脚
#define AD0_2 1//A/D转换器0输入2。该模拟输入总是连接到相应的管脚
#define CAP0_3 2//定时器0的捕获输入通道3
#define MAT0_3 3//定时器0的匹配输出通道3
#define P0_29_AD0_2 1//A/D转换器0输入2。该模拟输入总是连接到相应的管脚
#define P0_29_CAP0_3 2//定时器0的捕获输入通道3
#define P0_29_MAT0_3 3//定时器0的匹配输出通道3
#define P0_29_PINSEL 2 * P0_13
#define P0_30_GPIO 0//通用数字输入输出管脚
#define AD0_3 1//A/D转换器0输入3。该模拟输入总是连接到相应的管脚
#define P0_30_AD0_3 1//A/D转换器0输入3。该模拟输入总是连接到相应的管脚
#define P0_30_EINT3 2//***外部中断3输入
#define P0_30_CAP0_0 3//***定时器0的捕获输入通道0
#define P0_30_PINSEL 2 * P0_14
#define P0_31_GPO 0//通用数字输出管脚(注意:此管脚仅为输出)
#define P0_31_PINSEL 2 * P0_15
//RSIR
#define RSIR (*((volatile unsigned char *) 0xE01FC180))//
#define POR 0//RSIR.0//POR信号有效时该位置位,并清除RSIR寄存器的其它位
#define EXTR 1//RSIR.1//RESET信号有效时该位置位
#define WDTR 2//RSIR.2//当看门狗定时器溢出和看门狗方式寄存器的WDTRESET位为1时,该位置位。
//该位可被其它任何一个复位源清除。
#define BODR 3//RSIR.3//当3.3V的电源降到低于2.6V时该位置位
#endif // __LPC213xDEF_H
答 2: ARM菜农浇水心得---"看书"不如"抄书","抄书"不如"撕书"好累呀...
村里"交通不便"---没ARM开发板,没ARM的书,没见过ARM的芯片,没...
创建LPC213XDEF.H头文件就费时进6个小时...
菜农无知没见过类似的头文件定义,但那些IO模块功能的链接写法实在太累,
一气之下决定自己创建,虽然累些,但没见过通过建立头文件也能对IO搞个456出来...
这样引用宏就方便多了,...
例如接个串口0,只需简单地写为:
PINSEL0 |= (P0_0_TXD0 << P0_0_PINSEL);//设置P0.0为TXD0引脚
PINSEL0 |= (P0_1_RXD0 << P0_1_PINSEL);//设置P0.1为RXD0引脚
例如接个SPI0,只需简单地写为:
PINSEL0 |= (P0_4_SCK0 << P0_4_PINSEL);//设置P0.4为SCK0引脚
PINSEL0 |= (P0_5_MISO0 << P0_5_PINSEL);//设置P0.5为MISO0引脚
PINSEL0 |= (P0_6_MOSI0 << P0_6_PINSEL);//设置P0.6为MOSI0引脚
可能有人会说: 这不更麻烦吗???为何不定义为:
PINSEL0 |= (SCK0 << P0_4_PINSEL);//设置P0.4为SCK0引脚
PINSEL0 |= (MISO0 << P0_5_PINSEL);//设置P0.5为MISO0引脚
PINSEL0 |= (MOSI0 << P0_6_PINSEL);//设置P0.6为MOSI0引脚
这样不更简单吗???
因为我暂时考虑通用性和多引脚链接某一个功能(如EINT3等)
以后我会将不重复的功能简化的,但也保留现在的"版本"...
研究了两天的ARM中断,收获很大,但也带来了更多的担心...
终于搞清了所有的中断寄存器的使用,心得都在提高班笔记中,它可以任意组合...
看来学习最好的方法就是"抄书"而非"看书","抄书"虽然很累,但收获将远远大于"看书"...
因为菜农没开发板,那么"抄书"肯定会升华为"撕书"... 答 3: ARM菜鸟中断系统安全之担忧最近论坛内有"风声"说LPC2132要淘汰AVR,就恶补了几天的Philips ARM.
经过农校的扫盲,首先选修了最烦人的IO配置和中断控制...
感觉IO无上拉电阻配置确实遗憾...估计和5V接口连接有关,也罢...
头痛的是IO功能配置的晕...还好,自己先创建了LPC213XDEF.H头文件止痛...
中断还不难,就VICVectCntlX,VICVectAddrX,VICDefVectAddr,VICIntSelect,VICIntEnable等几个寄存器瞎折腾...
都说中断退出前应该清除VICVectAddr,但我仿真时VICSoftInt对应位也应该清除.否则搞个VICSoftInt = (1 << VICIntSel_EINT0);就死翘翘了...
再者,ARM与MCU最大的不同是中断向量的存贮方式的不同,这也在工控中带来了质的不同!!!
MCU中断向量一般在ROM中存入中断的实际跳入地址,而ARM必须连接到具体的中断.即ARM中断地址实际上是在RAM中保存的,这样可能很容易受到干扰信号的攻击!!!
所以动态保护或恢复VICVectCntlX,VICVectAddrX等几个瞎折腾的寄存器就成了工控中的新课题...
MCU中的"千万不要在中断中喂狗"的"学说"就是基于MCU中断向量是存在ROM中不易受攻击的"理论"...
因为程序飞但MCU的固定中断程序地址是定死的,所以程序飞也能成功的进入定时中断...."MCU疯狗论"就会很容易地将其从死难的边缘救起...
而ARM的中断体制可能比MCU更加灵活但却带来了新课题所要付出的代价...
个人之忧,个人之虑,个人之意见... 答 4: ARM菜鸟心中的中断防御系统设想在Philips ARM的中断体系中,中断干扰应该主要侵入SWI,IRQ,FIQ这三个中断向量.
SWI比较好防御,但IRQ,FIQ确实很难防御...
但是FIQ的向量可以在编译时固定,虽然IRQ分支很多没定义VICVectAddrX或VICVectCntl未开放中断,但都会归入VICDefVectAddr.
这样我们就可以从FIQ_Handler()和DefaultIRQ()中拦截...
拦截模型:
void FIQ_Handler (void) __fiq {//VICIntSelect非0
unsigned temp;
temp = VICFIQStatus;
if (temp & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
EXTINT = (1 << EINT0); //清除INT0中断标志
}
else if (temp & (1 << VICIntSel_EINT1)) {
IOSET1 = (1 << P1_17); //P1.17=1
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
IOCLR1 = (1 << P1_17); //P1.17=0
}
else if (temp & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
EXTINT = (1 << EINT2); //清除INT2中断标志
}
else if (temp & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << EINT3); //清除INT3中断标志
}
else {//其他干扰源
//再次填入干扰处理代码
}
VICSoftIntClr = temp;//抗击无效VICSoftInt=XXX的入侵
VICVectAddr = 0;
}
void DefaultIRQ (void) __irq {//VICIntSelect=0且VICVectCntl0~VICVectCntl15都未中断使能
unsigned long temp;
temp = VICIRQStatus;
if (temp & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
EXTINT = (1 << EINT0); //清除INT0中断标志
}
else if (temp & (1 << VICIntSel_EINT1)) {
IOPIN1 ^= (1 << P1_17); //取反P1.17
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
}
else if (temp & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
EXTINT = (1 << EINT2); //清除INT2中断标志
}
else if (temp & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << EINT3); //清除INT3中断标志
}
else {//其他干扰源
//再次填入干扰处理代码
}
VICSoftIntClr = temp;//抗击无效VICSoftInt=XXX的入侵
VICVectAddr = 0;
}
我并非主张将中断都在FIQ_Handler()和DefaultIRQ()中处理,而是在原设计上
"加高一层",以增强防御能力...
纸上谈兵,个人意见...
发表此说并非说ARM不如MCU抗打击,而是想如何去面对现实... 答 5: 佩服--为你的学习劲头,买块开发板吧,这对学习满有用的! 答 6: 哈哈,开发板对我没多大意思,纸上谈兵一样上战场这些玩意对我来说应该是喝凉水吧...
稍后继续分析... 答 7: ARM菜鸟终于在Keil里用上了C++心情很好,就是中断还暂时未搞定...不过已决定在ARM中放弃C语言编程... 答 8: 实际应用上FIQ只用一个中断源才可以体现出FIQ快速的优越性... 答 9: PIC的单中断向量的抗干扰能力可能这是重点之一 答 10: 期待菜鸟中断系统高级班学习笔记...中断嵌套...
uCOS-II... 答 11: 哈哈...终于水鸟快毕业了不急...慢慢忽悠...
ARM菜鸟外部中断及中断控制提高班学习结业笔记
HotPower@126.com 2005.7.22 于西安大雁塔村队部
-----------------------------------------------------------------------*/
/***********************************************************************/
/* This file is part of the CA ARM C Compiler package */
/* Copyright KEIL ELEKTRONIK GmbH 2002 - 2004 */
/***********************************************************************/
/* */
/* MAIN.C: Demonstration of various interrupt functions */
/* */
/***********************************************************************/
#include <LPC213x.H> // Philips Peripheral Registers
#include "LPC213xDEF.H" //ARM菜鸟HotPower创建定义文件
/*
* software interrupt function accept parameters and run in
* supervisor mode (interrupt protected).
*/
int myfunc1 (int i1, long i2) __swi (8) {
return (i1 / i2);
}
int myfunc2 (int i1) __swi (9) {
return (i1<<4);
}
void SetVICProtection(unsigned long val) __swi (10) {
VICProtection = val;//VICProtection可以随意置'1',但清'0'必须在管理模式下
}
/*
*具有特权保护的用户非向量中断,它只能在VICProtection=0时在用户模式下调用,比SWI更安全
*/
void UserDefineIRQ (void) __irq {
if (VICIRQStatus & (1 << VICIntSel_SoftInt31)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << VICIntSel_SoftInt31); //清除VICIntSel_SoftInt31中断标志
VICSoftIntClr = (1 << VICIntSel_SoftInt31);
}
VICVectAddr = 0;
}
/*
* standard interrupt function saves only R0 - R12 and returns with
*/
void DefaultIRQ (void) __irq {//VICIntSelect=0且VICVectCntl0~VICVectCntl15都未中断使能
unsigned long temp;
temp = VICIRQStatus;
if (temp & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
EXTINT = (1 << EINT0); //清除INT0中断标志
}
else if (temp & (1 << VICIntSel_EINT1)) {
IOPIN1 ^= (1 << P1_17); //取反P1.17
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
}
else if (temp & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
EXTINT = (1 << EINT2); //清除INT2中断标志
}
else if (temp & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << EINT3); //清除INT3中断标志
}
VICSoftIntClr = temp;
VICVectAddr = 0;
}
void EINT0IRQ (void) __irq {//IRQ中断函数EINT0IRQ被挂接在VICVectCntl0
if (VICIRQStatus & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
}
VICSoftIntClr = (1 << VICIntSel_EINT0);
EXTINT = (1 << EINT0); //清除INT0中断标志
VICVectAddr = 0;
}
void EINT1IRQ (void) __irq {//IRQ中断函数EINT1IRQ被挂接在VICVectCntl1
if (VICIRQStatus & (1 << VICIntSel_EINT1)) {
IOSET1 = (1 << P1_17); //P1.17=1
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
IOCLR1 = (1 << P1_17); //P1.17=0
VICSoftIntClr = (1 << VICIntSel_EINT1);
}
VICVectAddr = 0;
}
void EINT2IRQ (void) __irq {//IRQ中断函数EINT2IRQ被挂接在VICVectCntl2
if (VICIRQStatus & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
}
EXTINT = (1 << EINT2); //清除INT2中断标志
VICSoftIntClr = (1 << VICIntSel_EINT2);
VICVectAddr = 0;
}
void EINT3IRQ (void) __irq {//IRQ中断函数EINT3IRQ被挂接在VICVectCntl3
if (VICIRQStatus & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
}
EXTINT = (1 << EINT3); //清除INT3中断标志
VICSoftIntClr = (1 << VICIntSel_EINT3);
VICVectAddr = 0;
}
/*
* fast interrupt function saves only R0 - R7 and returns with
*/
void FIQ_Handler (void) __fiq {//VICIntSelect非0
unsigned temp;
temp = VICFIQStatus;
if (temp & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
EXTINT = (1 << EINT0); //清除INT0中断标志
}
else if (temp & (1 << VICIntSel_EINT1)) {
IOSET1 = (1 << P1_17); //P1.17=1
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
IOCLR1 = (1 << P1_17); //P1.17=0
}
else if (temp & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
EXTINT = (1 << EINT2); //清除INT2中断标志
}
else if (temp & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << EINT3); //清除INT3中断标志
}
VICSoftIntClr = temp;
VICVectAddr = 0;
}
/*
* task functions have no register save/restore and no return.
*/
void tsk (void) __task {
while (1);
}
/*
* Sample 'main' function
*/
int res;
void main (void) {
IODIR1 = (1 << P1_23) | (1 << P1_22) | (1 << P1_21) | (1 << P1_20)
|(1 << P1_19) | (1 << P1_18) | (1 << P1_17) | (1 << P1_16);//设置LED输出方式
PINSEL0 |= (P0_14_EINT1 << P0_14_PINSEL) //选择P0.14为INT1外部中断引脚
// | (P0_7_EINT2 << P0_7_PINSEL) //选择P0.7为INT2外部中断引脚
| (P0_15_EINT2 << P0_15_PINSEL); //选择P0.15为INT2外部中断引脚
// | (P0_9_EINT3 << P0_9_PINSEL) //选择P0.9也为INT3外部中断引脚
// | (P0_1_EINT0 << P0_1_PINSEL) //选择P0.1也为INT0外部中断引脚
// | (P0_3_EINT1 << P0_3_PINSEL); //选择P0.3也为INT1外部中断引脚
PINSEL1 |= (P0_16_EINT0 << P0_16_PINSEL) //选择P0.16为INT0外部中断引脚
// | (P0_20_EINT3 << P0_20_PINSEL) //选择P0.20也为INT3外部中断引脚
| (P0_30_EINT3 << P0_30_PINSEL);//选择P0.30也为INT3外部中断引脚(Keil仿真不了)
EXTPOLAR &= ~((1 << EXTPOLAR0) //INT0为低电平有效
| (1 << EXTPOLAR1) //INT1为低电平有效
| (1 << EXTPOLAR2) //INT2为低电平有效
| (1 << EXTPOLAR3));//INT3为低电平有效
EXTPOLAR |= (1 << EXTPOLAR0); //INT0为高电平有效
EXTMODE |= (1 << EXTMODE0) //设置INT0为边沿触发
| (1 << EXTMODE2) //设置INT2为边沿触发
| (1 << EXTMODE3);//设置INT3为边沿触发
EXTMODE &= ~(1 << EXTMODE1);//设置INT1为电平触发
VICVectCntl0 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT0;//获取EINT0的IRQ级别
VICVectAddr0 = (unsigned long *) &EINT0IRQ;//取INT0中断服务地址
VICVectCntl1 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT1;//获取EINT1的IRQ级别
VICVectAddr1 = (unsigned long *) &EINT1IRQ;//取INT1中断服务地址
VICVectCntl2 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT2;//获取EINT2的IRQ级别
VICVectAddr2 = (unsigned long *) &EINT2IRQ;//取INT2中断服务地址
VICVectCntl3 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT3;//获取EINT3的IRQ级别
VICVectAddr3 = (unsigned long *) &EINT3IRQ;//取INT3中断服务地址
VICVectCntl4 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_SoftInt31;//获取VICIntSel_SoftInt31的IRQ级别
VICVectAddr4 = (unsigned long *) &UserDefineIRQ;//取VicInt31中断服务地址
// VICVectCntl0 &= ~VICIntSel_Enable;//放弃EINT0的IRQ级别,获取默认中断级别
VICVectCntl1 &= ~VICIntSel_Enable;//放弃EINT1的IRQ级别,获取默认中断级别
// VICVectCntl2 &= ~VICIntSel_Enable;//放弃EINT2的IRQ级别,获取默认中断级别
VICDefVectAddr = (unsigned long *) &DefaultIRQ;//取默认中断服务地址
VICIntSelect = 0;//全部中断为IRQ中断或默认中断
/*
VICIntSelect = (1 << VICIntSel_EINT0) //设置EINT0为FIQ中断
| (1 << VICIntSel_EINT1) //设置EINT1为FIQ中断
| (1 << VICIntSel_EINT2) //设置EINT2为FIQ中断
| (1 << VICIntSel_EINT3);//设置EINT2为FIQ中断
*/
EXTINT = (1 << EINT0) | (1 << EINT1) | (1 << EINT2) | (1 << EINT3); //清除INT中断标志
// VICSoftIntClr = 0xffffffff;//清除所有软中断标志
VICSoftIntClr = (1 << VICIntSel_EINT0) //清除EINT0软中断标志
| (1 << VICIntSel_EINT1) //清除EINT1软中断标志
| (1 << VICIntSel_EINT2) //清除EINT2软中断标志
| (1 << VICIntSel_EINT3);//清除EINT3软中断标志
VICIntEnable = (1 << VICIntSel_EINT0) //使能EINT0中断
| (1 << VICIntSel_EINT1) //使能EINT1中断
| (1 << VICIntSel_EINT2) //使能EINT2中断
| (1 << VICIntSel_EINT3);//使能EINT3中断
VICIntEnable |= (1 << VICIntSel_SoftInt31);//使能VICIntSel_SoftInt31中断
SetVICProtection(1);//打开特权保护,阻止VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_EINT0);//(VICIntEnable & (1 << VICIntSel_EINT0))使能才能软中断
SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_EINT1);//(VICIntEnable & (1 << VICIntSel_EINT1))使能才能软中断
SetVICProtection(1);//打开特权保护,阻止VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_EINT2);//(VICIntEnable & (1 << VICIntSel_EINT2))使能才能软中断
SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_EINT3);//(VICIntEnable & (1 << VICIntSel_EINT3))使能才能软中断
SetVICProtection(0);//关闭特权保护,允许VICSoftInt软中断
VICSoftInt = (1 << VICIntSel_SoftInt31);//(VICIntEnable & (1 << VICIntSel_SoftInt31))使能才能软中断
res = myfunc1 (10, 2); // call SWI functions
res += myfunc2 (res);
while (1); // endless loop
} 答 1: LPC213XDEF.H头文件/*----------------------------------------------------
文 件 名: LPC213XDEF.H
创 建 人: ARM菜鸟 HotPower@126.com
创 建 日 期: 2005.7.23 0:38
最近修改日期: 2005.7.23 10:38
创 建 地 点 : 西安大雁塔村队部
说 明 : 未经过硬件调试
------------------------------------------------------*/
#ifndef __LPC213xDEF_H
#define __LPC213xDEF_H
#define BV(val) (1 << val)
#define VICIntSel_Watchdog 0//看门狗中断(WDINT)
#define VICIntSel_SoftInt1 1//保留给软件中断
#define VICIntSel_DbgCommRx 2//ARM内核中断
#define VICIntSel_DbgCommTx 3//ARM内核中断
#define VICIntSel_Time0 4//定时器0中断
#define VICIntSel_Time1 5//定时器1中断
#define VICIntSel_UART0 6//UART0中断
#define VICIntSel_UART1 7//UART1中断
#define VICIntSel_PWM0 8//PWM0中断
#define VICIntSel_I2C0 9//I2C0中断
#define VICIntSel_SPI0 10//SPI0中断
#define VICIntSel_SSP 11//SSP中断
#define VICIntSel_SPI1 11//SPI1中断
#define VICIntSel_PLL 12//PLL中断
#define VICIntSel_RTC 13//RTC中断
#define VICIntSel_EINT0 14//系统控制外部中断0
#define VICIntSel_EINT1 15//系统控制外部中断1
#define VICIntSel_EINT2 16//系统控制外部中断2
#define VICIntSel_EINT3 17//系统控制外部中断3
#define VICIntSel_ADC0 18//A/D转换器0中断
#define VICIntSel_I2C1 19//I2C1中断
#define VICIntSel_BOD 20//掉电检测中断
#define VICIntSel_ADC1 21//A/D转换器1中断
#define VICIntSel_SoftInt22 22//保留给软件中断
#define VICIntSel_SoftInt23 23//保留给软件中断
#define VICIntSel_SoftInt24 24//保留给软件中断
#define VICIntSel_SoftInt25 25//保留给软件中断
#define VICIntSel_SoftInt26 26//保留给软件中断
#define VICIntSel_SoftInt27 27//保留给软件中断
#define VICIntSel_SoftInt28 28//保留给软件中断
#define VICIntSel_SoftInt29 29//保留给软件中断
#define VICIntSel_SoftInt30 30//保留给软件中断
#define VICIntSel_SoftInt31 31//保留给软件中断
#define VICIntSel_Enable 32//
/*
P0口GPIO位寻址位定义
*/
#define P0_0 0//P0.0
#define P0_1 1//P0.1
#define P0_2 2//P0.2
#define P0_3 3//P0.3
#define P0_4 4//P0.4
#define P0_5 5//P0.5
#define P0_6 6//P0.6
#define P0_7 7//P0.7
#define P0_8 8//P0.8
#define P0_9 9//P0.9
#define P0_10 10//P0.10
#define P0_11 11//P0.11
#define P0_12 12//P0.12
#define P0_13 13//P0.13
#define P0_14 14//P0.14
#define P0_15 15//P0.15
#define P0_16 16//P0.16
#define P0_17 17//P0.17
#define P0_18 18//P0.18
#define P0_19 19//P0.19
#define P0_20 20//P0.20
#define P0_21 21//P0.21
#define P0_22 22//P0.22
#define P0_23 23//P0.23
#define P0_24 24//P0.24
#define P0_25 25//P0.25
#define P0_26 26//P0.26
#define P0_27 27//P0.27
#define P0_28 28//P0.28
#define P0_29 29//P0.29
#define P0_30 30//P0.30
#define P0_31 31//P0.31
/*
P1口GPIO位寻址位定义
*/
#define P1_0 0//P1.0
#define P1_1 1//P1.1
#define P1_2 2//P1.2
#define P1_3 3//P1.3
#define P1_4 4//P1.4
#define P1_5 5//P1.5
#define P1_6 6//P1.6
#define P1_7 7//P1.7
#define P1_8 8//P1.8
#define P1_9 9//P1.9
#define P1_10 10//P1.10
#define P1_11 11//P1.11
#define P1_12 12//P1.12
#define P1_13 13//P1.13
#define P1_14 14//P1.14
#define P1_15 15//P1.15
#define P1_16 16//P1.16
#define P1_17 17//P1.17
#define P1_18 18//P1.18
#define P1_19 19//P1.19
#define P1_20 20//P1.20
#define P1_21 21//P1.21
#define P1_22 22//P1.22
#define P1_23 23//P1.23
#define P1_24 24//P1.24
#define P1_25 25//P1.25
#define P1_26 26//P1.26
#define P1_27 27//P1.27
#define P1_28 28//P1.28
#define P1_29 29//P1.29
#define P1_30 30//P1.30
#define P1_31 31//P1.31
/*
外部中断标志寄存器EXTINT位定义
*/
#define EINT0 0//EXTINT.0//写'1'清除EINT0中断标志
#define EINT1 1//EXTINT.1//写'1'清除EINT1中断标志
#define EINT2 2//EXTINT.2//写'1'清除EINT2中断标志
#define EINT3 3//EXTINT.3//写'1'清除EINT3中断标志
/*
外部中断方式寄存器EXTMODE位定义
*/
#define EXTMODE0 0//EXTMODE.0//该位为0时,EINT0使用电平激活;该位为1时,EINT0使用边沿激活。
#define EXTMODE1 1//EXTMODE.1//该位为0时,EINT1使用电平激活;该位为1时,EINT1使用边沿激活。
#define EXTMODE2 2//EXTMODE.2//该位为0时,EINT2使用电平激活;该位为1时,EINT2使用边沿激活。
#define EXTMODE3 3//EXTMODE.3//该位为0时,EINT3使用电平激活;该位为1时,EINT3使用边沿激活。
/*
外部中断极性寄存器EXTPOLAR位定义
*/
#define EXTPOLAR0 0//EXTPOLAR.0//该位为0时,EINT0低电平或下降沿有效(由EXTMODE0决定)。
//该位为1时,EINT0高电平或上升沿有效(由EXTMODE0决定)。
#define EXTPOLAR1 1//EXTPOLAR.1//该位为0时,EINT1低电平或下降沿有效(由EXTMODE1决定)。
//该位为1时,EINT1高电平或上升沿有效(由EXTMODE1决定)。
#define EXTPOLAR2 2//EXTPOLAR.2//该位为0时,EINT2低电平或下降沿有效(由EXTMODE2决定)。
//该位为1时,EINT2高电平或上升沿有效(由EXTMODE2决定)。
#define EXTPOLAR3 3//EXTPOLAR.3//该位为0时,EINT3低电平或下降沿有效(由EXTMODE3决定)。
//该位为1时,EINT3高电平或上升沿有效(由EXTMODE3决定)。
/*
外部中断唤醒寄存器EXTWAKE位定义
*/
#define EXTWAKE0 0//EXTWAKE.0//该位为1时,使能EINT0将处理器从掉电模式唤醒。
#define EXTWAKE1 1//EXTWAKE.1//该位为1时,使能EINT1将处理器从掉电模式唤醒。
#define EXTWAKE2 2//EXTWAKE.2//该位为1时,使能EINT2将处理器从掉电模式唤醒。
#define EXTWAKE3 3//EXTWAKE.3//该位为1时,使能EINT3将处理器从掉电模式唤醒。
#define BODWAKE 14//EXTWAKE.14//该位为1时,BOD中断产生时可将处理器从掉电模式唤醒。
#define RTCWAKE 15//EXTWAKE.15//该位为1时,RTC中断产生时可将处理器从掉电模式唤醒。
/*
GPIO管脚功能配置
应用示例:
PINSEL0 |= (P0_0_TXD0 << P0_0_PINSEL) | (P0_1_RXD0 << P0_1_PINSEL); //选择P0.0和P0.1为UART0的输出输入引脚
或:
PINSEL0 |= (TXD0 << P0_0_PINSEL) | (RXD0 << P0_1_PINSEL); //选择P0.0和P0.1为UART0的输出输入引脚
PINSEL0 |= (P0_3_EINT1 << P0_3_PINSEL); //选择P0.3为INT1外部中断引脚
PINSEL0 |= (P0_14_EINT1 << P0_14_PINSEL); //选择P0.14也可为INT1外部中断引脚
PINSEL0 |= (P0_1_EINT0 << P0_1_PINSEL) //选择P0.1为INT0外部中断引脚
PINSEL1 |= (P0_16_EINT0 << P0_16_PINSEL); //选择P0.16也可为INT0外部中断引脚
注:由于INT0,INT1可配置多个引脚,故不能简化,必须指明引脚号
PINSEL0 |= (EINT1 << P0_3_PINSEL); //出错
PINSEL0 |= (EINT1 << P0_14_PINSEL); //出错
因为P0_3_EINT1=3,P0_14_EINT1=2.故功能虽然相同,但功能序号不同!!!
*/
#define P0_0_GPIO 0//通用数字输入输出管脚
#define TXD0 1//UART0的发送器输出
#define PWM1 2//脉宽调制器输出1
#define P0_0_TXD0 1//UART0的发送器输出
#define P0_0_PWM1 2//脉宽调制器输出1
#define P0_0_PINSEL 2 * P0_0
#define P0_1_GPIO 0//通用数字输入输出管脚
#define RXD0 1//UART0的接收器输入
#define PWM3 2//脉宽调制器输出3
#define P0_1_RXD0 1//UART0的接收器输入
#define P0_1_PWM3 2//脉宽调制器输出3
#define P0_1_EINT0 3//**外部中断0输入
#define P0_1_PINSEL 2 * P0_1
#define P0_2_GPIO 0//通用数字输入输出管脚
#define SCL0 1//I2C0时钟输入/输出。开漏输出(符合I2C规范)
#define P0_2_SCL0 1//I2C0时钟输入/输出。开漏输出(符合I2C规范)
#define P0_2_CAP0_0 2//***定时器0的捕获输入通道0
#define P0_2_PINSEL 2 * P0_2
#define P0_3_GPIO 0//通用数字输入输出管脚
#define SDA0 1//I2C0数据输入/输出。开漏输出(符合I2C规范)
#define P0_3_SDA0 1//I2C0数据输入/输出。开漏输出(符合I2C规范)
#define P0_3_MAT0_0 2//**定时器0的匹配输出通道0
#define P0_3_EINT1 3//**外部中断1输入
#define P0_3_PINSEL 2 * P0_3
#define P0_4_GPIO 0//通用数字输入输出管脚
#define SCK0 1//SPI0的串行时钟。SPI时钟从主机输出,从机输入
#define AD0_6 3//A/D转换器0输入6。该模拟输入总是连接到相应的管脚
#define P0_4_SCK0 1//SPI0的串行时钟。SPI时钟从主机输出,从机输入
#define P0_4_CAP0_1 2//**定时器0的捕获输入通道1
#define P0_4_AD0_6 3//A/D转换器0输入6。该模拟输入总是连接到相应的管脚
#define P0_4_PINSEL 2 * P0_4
#define P0_5_GPIO 0//通用数字输入输出管脚
#define MISO0 1//SPI0主机输入从机输出端。从机到主机的数据传输
#define P0_5_MISO0 1//SPI0主机输入从机输出端。从机到主机的数据传输
#define P0_5_MAT0_1 2//**定时器0的匹配输出通道1
#define P0_5_AD0_7 3//A/D转换器0输入7。该模拟输入总是连接到相应的管脚
#define P0_5_PINSEL 2 * P0_5
#define P0_6_GPIO 0//通用数字输入输出管脚
#define MOSI0 1//SPI0主机输出从机输入端。主机到从机的数据传输
#define P0_6_MOSI0 1//SPI0主机输出从机输入端。主机到从机的数据传输
#define P0_6_CAP0_2 2//***定时器0的捕获输入通道2
#define P0_6_AD1_0 3//A/D转换器1输入0。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_6_PINSEL 2 * P0_6
#define P0_7_GPIO 0//通用数字输入输出管脚
#define SSEL0 1//SPI0从机选择。选择SPI接口用作从机
#define PWM2 2//脉宽调制器输出2
#define P0_7_SSEL0 1//SPI0从机选择。选择SPI接口用作从机
#define P0_7_PWM2 2//脉宽调制器输出2
#define P0_7_EINT2 3//**外部中断2输入
#define P0_7_PINSEL 2 * P0_7
#define P0_8_GPIO 0//通用数字输入输出管脚
#define TXD1 1//UART1的发送器输出
#define PWM4 2//脉宽调制器输出4
#define AD1_1 3//A/D转换器1输入1。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_8_TXD1 1//UART1的发送器输出
#define P0_8_PWM4 2//脉宽调制器输出4
#define P0_8_AD1_1 3//A/D转换器1输入1。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_8_PINSEL 2 * P0_8
#define P0_9_GPIO 0//通用数字输入输出管脚
#define RXD1 1//UART1的接收器输入
#define PWM6 2//脉宽调制器输出6
#define P0_9_RXD1 1//UART1的接收器输入
#define P0_9_PWM6 2//脉宽调制器输出6
#define P0_9_EINT3 3//***外部中断3输入
#define P0_9_PINSEL 2 * P0_9
#define P0_10_GPIO 0//通用数字输入输出管脚
#define RTS1 1//UART1请求发送出端(仅用于LP138)
#define CAP1_0 2//定时器1的捕获输入通道0
#define AD1_2 3//A/D转换器1输入2。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_10_RTS1 1//UART1请求发送出端(仅用于LP138)
#define P0_10_CAP1_0 2//定时器1的捕获输入通道0
#define P0_10_AD1_2 3//A/D转换器1输入2。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_10_PINSEL 2 * P0_10
#define P0_11_GPIO 0//通用数字输入输出管脚
#define CTS1 1//UART1清除发送入端(仅用于LP138)
#define CAP1_1 2//定时器1的捕获输入通道1
#define SCL1 3//I2C1时钟输入/输。开漏输出(符合I2C规范)
#define P0_11_CTS1 1//UART1清除发送入端(仅用于LP138)
#define P0_11_CAP1_1 2//定时器1的捕获输入通道1
#define P0_11_SCL1 3//I2C1时钟输入/输。开漏输出(符合I2C规范)
#define P0_11_PINSEL 2 * P0_11
#define P0_12_GPIO 0//通用数字输入输出管脚
#define DSR1 1//UART1数据设置就绪端(仅用于 LPC2138)
#define MAT1_0 2//定时器1的匹配输出通道0
#define AD1_3 3//A/D转换器1输入3。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_12_DSR1 1//UART1数据设置就绪端(仅用于 LPC2138)
#define P0_12_MAT1_0 2//定时器1的匹配输出通道0
#define P0_12_AD1_3 3//A/D转换器1输入3。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_12_PINSEL 2 * P0_12
#define P0_13_GPIO 0//通用数字输入输出管脚
#define DTR1 1//UART1数据终端就绪
#define MAT1_1 2//定时器1的匹配输出通道1
#define AD1_4 3//A/D转换器1输入4。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_13_DTR1 1//UART1数据终端就绪
#define P0_13_MAT1_1 2//定时器1的匹配输出通道1
#define P0_13_AD1_4 3//A/D转换器1输入4。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_13_PINSEL 2 * P0_13
#define P0_14_GPIO 0//通用数字输入输出管脚
#define DCD1 1//UART1数据载波检测输入(仅用于 LPC2138)
#define SDA1 3//I2C1数据输入/输出。开漏输出(符合I2C规范)
#define P0_14_DCD1 1//UART1数据载波检测输入(仅用于 LPC2138)
#define P0_14_EINT1 2//**外部中断1输入
#define P0_14_SDA1 3//I2C1数据输入/输出。开漏输出(符合I2C规范)
#define P0_14_PINSEL 2 * P0_14
#define P0_15_GPIO 0//通用数字输入输出管脚
#define RI1 1//UART1铃响指示输入(仅用于 LPC2138)
#define AD1_5 3//A/D转换器1输入5。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_15_RI1 1//UART1铃响指示输入(仅用于 LPC2138)
#define P0_15_EINT2 2//**外部中断2输入
#define P0_14_AD1_5 3//A/D转换器1输入5。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_15_PINSEL 2 * P0_15
#define P0_16_GPIO 0//通用数字输入输出管脚
#define P0_16_EINT0 1//**外部中断0输入
#define P0_16_MAT0_2 2//**定时器0的匹配输出通道2
#define P0_16_CAP0_2 3//***定时器0的捕获输入通道2
#define P0_16_PINSEL 2 * P0_0
#define P0_17_GPIO 0//通用数字输入输出管脚
#define SCK1 2//SPI1的串行时钟。SPI时钟从主机输出,从机输入
#define P0_17_CAP1_2 1//**定时器1的捕获输入通道2
#define P0_17_SCK1 2//SPI1的串行时钟。SPI时钟从主机输出,从机输入
#define P0_17_MAT1_2 3//**定时器1的匹配输出通道2
#define P0_17_PINSEL 2 * P0_1
#define P0_18_GPIO 0//通用数字输入输出管脚
#define MISO1 2//SPI1主机输入从机输出端。从机到主机的数据传输
#define P0_18_CAP1_3 1//**定时器1的捕获输入通道3
#define P0_18_MISO1 2//SPI1主机输入从机输出端。从机到主机的数据传输
#define P0_18_MAT1_3 3//**定时器1的匹配输出通道3
#define P0_18_PINSEL 2 * P0_2
#define P0_19_GPIO 0//通用数字输入输出管脚
#define MOSI1 2//SPI1主机输出从机输入端。主机到从机的数据传输
#define P0_19_MAT1_2 1//**定时器1的匹配输出通道2
#define P0_18_MOSI1 2//SPI1主机输出从机输入端。主机到从机的数据传输
#define P0_19_CAP1_2 3//**定时器1的捕获输入通道2
#define P0_19_PINSEL 2 * P0_3
#define P0_20_GPIO 0//通用数字输入输出管脚
#define SSEL1 2//SPI1从机选择。选择SPI接口用作从机
#define P0_20_MAT1_3 1//**定时器1的匹配输出通道3
#define P0_20_SSEL1 2//SPI1从机选择。选择SPI接口用作从机
#define P0_20_EINT3 3//***外部中断3输入
#define P0_20_PINSEL 2 * P0_4
#define P0_21_GPIO 0//通用数字输入输出管脚
#define PWM5 1//脉宽调制器输出5
#define AD1_6 2//A/D转换器1输入6。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_21_PWM5 1//脉宽调制器输出5
#define P0_21_AD1_6 2//A/D转换器1输入6。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_21_CAP1_3 3//**定时器1的捕获输入通道3
#define P0_21_PINSEL 2 * P0_5
#define P0_22_GPIO 0//通用数字输入输出管脚
#define AD1_7 1//A/D转换器1输入7。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_22_AD1_7 1//A/D转换器1输入7。该模拟输入总是连接到相应的管脚(仅用于 LPC2138)
#define P0_22_CAP0_0 2//***定时器0的捕获输入通道0
#define P0_22_MAT0_0 3//**定时器0的匹配输出通道0
#define P0_22_PINSEL 2 * P0_6
#define P0_23_GPIO 0//通用数字输入输出管脚
#define P0_23_PINSEL 2 * P0_7
//#define P0_24_GPIO 0//P0.24 脚未用
//#define P0_24_PINSEL 2 * P0_8
#define P0_25_GPIO 0//通用数字输入输出管脚
#define AD0_4 1//A/D转换器0输入4。该模拟输入总是连接到相应的管脚.D/A 转换器输出(仅用于 LPC2138)
#define P0_25_AD0_4 1//A/D转换器0输入4。该模拟输入总是连接到相应的管脚.D/A 转换器输出(仅用于 LPC2138)
#define P0_25_PINSEL 2 * P0_9
#define P0_26_GPIO 0//通用数字输入输出管脚
#define AD0_5 1//A/D转换器0输入5。该模拟输入总是连接到相应的管脚
#define P0_26_AD0_5 1//A/D转换器0输入5。该模拟输入总是连接到相应的管脚
#define P0_26_PINSEL 2 * P0_10
#define P0_27_GPIO 0//通用数字输入输出管脚
#define AD0_0 1//A/D转换器0输入0。该模拟输入总是连接到相应的管脚
#define P0_27_AD0_0 1//A/D转换器0输入0。该模拟输入总是连接到相应的管脚
#define P0_27_CAP0_1 2//**定时器0的捕获输入通道1
#define P0_27_MAT0_1 3//**定时器0的捕获输入通道1
#define P0_27_PINSEL 2 * P0_11
#define P0_28_GPIO 0//通用数字输入输出管脚
#define AD0_1 1//A/D转换器0输入1。该模拟输入总是连接到相应的管脚
#define P0_28_AD0_1 1//A/D转换器0输入1。该模拟输入总是连接到相应的管脚
#define P0_28_CAP0_2 2//***定时器0的捕获输入通道2
#define P0_28_MAT0_2 3//**定时器0的匹配输出通道2
#define P0_28_PINSEL 2 * P0_12
#define P0_29_GPIO 0//通用数字输入输出管脚
#define AD0_2 1//A/D转换器0输入2。该模拟输入总是连接到相应的管脚
#define CAP0_3 2//定时器0的捕获输入通道3
#define MAT0_3 3//定时器0的匹配输出通道3
#define P0_29_AD0_2 1//A/D转换器0输入2。该模拟输入总是连接到相应的管脚
#define P0_29_CAP0_3 2//定时器0的捕获输入通道3
#define P0_29_MAT0_3 3//定时器0的匹配输出通道3
#define P0_29_PINSEL 2 * P0_13
#define P0_30_GPIO 0//通用数字输入输出管脚
#define AD0_3 1//A/D转换器0输入3。该模拟输入总是连接到相应的管脚
#define P0_30_AD0_3 1//A/D转换器0输入3。该模拟输入总是连接到相应的管脚
#define P0_30_EINT3 2//***外部中断3输入
#define P0_30_CAP0_0 3//***定时器0的捕获输入通道0
#define P0_30_PINSEL 2 * P0_14
#define P0_31_GPO 0//通用数字输出管脚(注意:此管脚仅为输出)
#define P0_31_PINSEL 2 * P0_15
//RSIR
#define RSIR (*((volatile unsigned char *) 0xE01FC180))//
#define POR 0//RSIR.0//POR信号有效时该位置位,并清除RSIR寄存器的其它位
#define EXTR 1//RSIR.1//RESET信号有效时该位置位
#define WDTR 2//RSIR.2//当看门狗定时器溢出和看门狗方式寄存器的WDTRESET位为1时,该位置位。
//该位可被其它任何一个复位源清除。
#define BODR 3//RSIR.3//当3.3V的电源降到低于2.6V时该位置位
#endif // __LPC213xDEF_H
答 2: ARM菜农浇水心得---"看书"不如"抄书","抄书"不如"撕书"好累呀...
村里"交通不便"---没ARM开发板,没ARM的书,没见过ARM的芯片,没...
创建LPC213XDEF.H头文件就费时进6个小时...
菜农无知没见过类似的头文件定义,但那些IO模块功能的链接写法实在太累,
一气之下决定自己创建,虽然累些,但没见过通过建立头文件也能对IO搞个456出来...
这样引用宏就方便多了,...
例如接个串口0,只需简单地写为:
PINSEL0 |= (P0_0_TXD0 << P0_0_PINSEL);//设置P0.0为TXD0引脚
PINSEL0 |= (P0_1_RXD0 << P0_1_PINSEL);//设置P0.1为RXD0引脚
例如接个SPI0,只需简单地写为:
PINSEL0 |= (P0_4_SCK0 << P0_4_PINSEL);//设置P0.4为SCK0引脚
PINSEL0 |= (P0_5_MISO0 << P0_5_PINSEL);//设置P0.5为MISO0引脚
PINSEL0 |= (P0_6_MOSI0 << P0_6_PINSEL);//设置P0.6为MOSI0引脚
可能有人会说: 这不更麻烦吗???为何不定义为:
PINSEL0 |= (SCK0 << P0_4_PINSEL);//设置P0.4为SCK0引脚
PINSEL0 |= (MISO0 << P0_5_PINSEL);//设置P0.5为MISO0引脚
PINSEL0 |= (MOSI0 << P0_6_PINSEL);//设置P0.6为MOSI0引脚
这样不更简单吗???
因为我暂时考虑通用性和多引脚链接某一个功能(如EINT3等)
以后我会将不重复的功能简化的,但也保留现在的"版本"...
研究了两天的ARM中断,收获很大,但也带来了更多的担心...
终于搞清了所有的中断寄存器的使用,心得都在提高班笔记中,它可以任意组合...
看来学习最好的方法就是"抄书"而非"看书","抄书"虽然很累,但收获将远远大于"看书"...
因为菜农没开发板,那么"抄书"肯定会升华为"撕书"... 答 3: ARM菜鸟中断系统安全之担忧最近论坛内有"风声"说LPC2132要淘汰AVR,就恶补了几天的Philips ARM.
经过农校的扫盲,首先选修了最烦人的IO配置和中断控制...
感觉IO无上拉电阻配置确实遗憾...估计和5V接口连接有关,也罢...
头痛的是IO功能配置的晕...还好,自己先创建了LPC213XDEF.H头文件止痛...
中断还不难,就VICVectCntlX,VICVectAddrX,VICDefVectAddr,VICIntSelect,VICIntEnable等几个寄存器瞎折腾...
都说中断退出前应该清除VICVectAddr,但我仿真时VICSoftInt对应位也应该清除.否则搞个VICSoftInt = (1 << VICIntSel_EINT0);就死翘翘了...
再者,ARM与MCU最大的不同是中断向量的存贮方式的不同,这也在工控中带来了质的不同!!!
MCU中断向量一般在ROM中存入中断的实际跳入地址,而ARM必须连接到具体的中断.即ARM中断地址实际上是在RAM中保存的,这样可能很容易受到干扰信号的攻击!!!
所以动态保护或恢复VICVectCntlX,VICVectAddrX等几个瞎折腾的寄存器就成了工控中的新课题...
MCU中的"千万不要在中断中喂狗"的"学说"就是基于MCU中断向量是存在ROM中不易受攻击的"理论"...
因为程序飞但MCU的固定中断程序地址是定死的,所以程序飞也能成功的进入定时中断...."MCU疯狗论"就会很容易地将其从死难的边缘救起...
而ARM的中断体制可能比MCU更加灵活但却带来了新课题所要付出的代价...
个人之忧,个人之虑,个人之意见... 答 4: ARM菜鸟心中的中断防御系统设想在Philips ARM的中断体系中,中断干扰应该主要侵入SWI,IRQ,FIQ这三个中断向量.
SWI比较好防御,但IRQ,FIQ确实很难防御...
但是FIQ的向量可以在编译时固定,虽然IRQ分支很多没定义VICVectAddrX或VICVectCntl未开放中断,但都会归入VICDefVectAddr.
这样我们就可以从FIQ_Handler()和DefaultIRQ()中拦截...
拦截模型:
void FIQ_Handler (void) __fiq {//VICIntSelect非0
unsigned temp;
temp = VICFIQStatus;
if (temp & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
EXTINT = (1 << EINT0); //清除INT0中断标志
}
else if (temp & (1 << VICIntSel_EINT1)) {
IOSET1 = (1 << P1_17); //P1.17=1
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
IOCLR1 = (1 << P1_17); //P1.17=0
}
else if (temp & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
EXTINT = (1 << EINT2); //清除INT2中断标志
}
else if (temp & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << EINT3); //清除INT3中断标志
}
else {//其他干扰源
//再次填入干扰处理代码
}
VICSoftIntClr = temp;//抗击无效VICSoftInt=XXX的入侵
VICVectAddr = 0;
}
void DefaultIRQ (void) __irq {//VICIntSelect=0且VICVectCntl0~VICVectCntl15都未中断使能
unsigned long temp;
temp = VICIRQStatus;
if (temp & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
EXTINT = (1 << EINT0); //清除INT0中断标志
}
else if (temp & (1 << VICIntSel_EINT1)) {
IOPIN1 ^= (1 << P1_17); //取反P1.17
while(EXTINT & (1 << EINT1)) {
EXTINT = (1 << EINT1); //清除INT1中断标志
}
}
else if (temp & (1 << VICIntSel_EINT2)) {
IOPIN1 ^= (1 << P1_18); //取反P1.18
EXTINT = (1 << EINT2); //清除INT2中断标志
}
else if (temp & (1 << VICIntSel_EINT3)) {
IOPIN1 ^= (1 << P1_19); //取反P1.19
EXTINT = (1 << EINT3); //清除INT3中断标志
}
else {//其他干扰源
//再次填入干扰处理代码
}
VICSoftIntClr = temp;//抗击无效VICSoftInt=XXX的入侵
VICVectAddr = 0;
}
我并非主张将中断都在FIQ_Handler()和DefaultIRQ()中处理,而是在原设计上
"加高一层",以增强防御能力...
纸上谈兵,个人意见...
发表此说并非说ARM不如MCU抗打击,而是想如何去面对现实... 答 5: 佩服--为你的学习劲头,买块开发板吧,这对学习满有用的! 答 6: 哈哈,开发板对我没多大意思,纸上谈兵一样上战场这些玩意对我来说应该是喝凉水吧...
稍后继续分析... 答 7: ARM菜鸟终于在Keil里用上了C++心情很好,就是中断还暂时未搞定...不过已决定在ARM中放弃C语言编程... 答 8: 实际应用上FIQ只用一个中断源才可以体现出FIQ快速的优越性... 答 9: PIC的单中断向量的抗干扰能力可能这是重点之一 答 10: 期待菜鸟中断系统高级班学习笔记...中断嵌套...
uCOS-II... 答 11: 哈哈...终于水鸟快毕业了不急...慢慢忽悠...
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图四被打赏50分 | |
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 |