共2条
1/1 1 跳转至页
ARTX ARTX菜鸟中断嵌套笔记
问
/*--------------------------------------------------------
ARTX菜鸟中断嵌套笔记
代码长度 6660(优化)
HotPower@126.com 2005.9.17 于西安大雁塔村队部
---------------------------------------------------------*/
#include <ARTX.h>
#include <LPC213x.H> // Philips Peripheral Registers
#include <LPC213xDEF.H> //ARM菜鸟HotPower创建定义文件
//本程序共有7个任务,需改写OS_TASK_CNT为7
OS_TID IdTask, IdTask1, IdTask2;
OS_TID IdTaskEint0, IdTaskEint1, IdTaskEint2, IdTaskEint3;
void TaskMain (void) __task;
void Task1 (void) __task;
void Task2 (void) __task;
void TaskEint0 (void) __task;//外部中断Eint0处理任务
void TaskEint1 (void) __task;//外部中断Eint1处理任务
void TaskEint2 (void) __task;//外部中断Eint2处理任务
void TaskEint3 (void) __task;//外部中断Eint3处理任务
volatile unsigned int FCount = 1;
volatile unsigned int Count = 0;
volatile unsigned int Count1 = 0;
volatile unsigned int Count2 = 0;
volatile unsigned int Count10 = 0;
volatile unsigned int Count20 = 0;
volatile unsigned int Sum0 = 0;
volatile unsigned int Sum00 = 0;
volatile unsigned int Sum1 = 0;
volatile unsigned int Sum10 = 0;
volatile unsigned int Sum2 = 0;
volatile unsigned int Sum20 = 0;
volatile unsigned int Sum3 = 0;
volatile unsigned int Sum30 = 0;
unsigned int Eint1Count = 0;
void EINT0IRQ(void) __irq;//声明中断ISR函数
void EINT1IRQ(void) __irq;//声明中断ISR函数
void EINT2IRQ(void) __irq;//声明中断ISR函数
void EINT3IRQ(void) __irq;//声明中断ISR函数
// Macros for Interrupt Nesting
#define IENABLE /* Nested Interrupts Entry */ \
__asm { MRS LR, SPSR } /* Copy SPSR_irq to LR */ \
__asm { STMFD SP!, {LR} } /* Save SPSR_irq */ \
__asm { MSR CPSR_c, #0x1F } /* Enable IRQ (Sys Mode) */ \
__asm { STMFD SP!, {LR} } /* Save LR */ \
#define IDISABLE /* Nested Interrupts Exit */ \
__asm { LDMFD SP!, {LR} } /* Restore LR */ \
__asm { MSR CPSR_c, #0x92 } /* Disable IRQ (IRQ Mode) */ \
__asm { LDMFD SP!, {LR} } /* Restore SPSR_irq to LR */ \
__asm { MSR SPSR_cxsf, LR } /* Copy LR to SPSR_irq */ \
void ei() __ARM __swi(8)
{
__asm
{
STMFD SP,{R0}
MRS R0, SPSR
BIC R0, R0, #0xc0;//打开irq,fiq中断
MSR SPSR_c, R0
LDMFD SP,{R0}
}
}
void di() __ARM __swi(9)
{
__asm
{
STMFD SP,{R0}
MRS R0, SPSR
ORR R0, R0, #0xc0;//关闭irq,fiq中断
MSR SPSR_c, R0
LDMFD SP,{R0}
}
}
void EINT0IRQ (void) __irq{//IRQ中断函数EINT0IRQ被挂接在VICVectCntl0
if (VICIRQStatus & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
isr_evt_set (0x1000, IdTaskEint0);//退出中断后立即执行TaskEint0任务
}
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
EXTINT = (1 << EINT1); //清除INT1中断标志
IENABLE;//开放中断嵌套
PINSEL0 &= ~(P0_3_EINT1 << P0_3_PINSEL); //重新选择P0.3为普通IO引脚!!!
while ((IOPIN0 & (1 << P0_3)) == 0);//等待P0.3变为高电平,注意没上句程序将不能测IO引脚电平!!!
PINSEL0 |= (P0_3_EINT1 << P0_3_PINSEL); //重新选择P0.3为INT1外部中断引脚!!!
IDISABLE;//关闭中断嵌套
isr_evt_set (0x2000, IdTaskEint1);//退出中断后立即执行TaskEint1任务
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
isr_evt_set (0x3000, IdTaskEint2);//退出中断后立即执行TaskEint2任务
}
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
isr_evt_set (0x4000, IdTaskEint3);//退出中断后立即执行TaskEint3任务
}
EXTINT = (1 << EINT3); //清除INT3中断标志
VICSoftIntClr = (1 << VICIntSel_EINT3);
VICVectAddr = 0;
}
void TaskMain (void) __task {
IdTask = os_tsk_self ();//取本任务ID
os_tsk_prio_self (13);//任务级别
IdTask1 = os_tsk_create (Task1, 11);//创建Task1任务及级别
IdTask2 = os_tsk_create (Task2, 11);//创建Task2任务及级别
IdTaskEint0 = os_tsk_create (TaskEint0, 100);//创建TaskEint0任务及级别
IdTaskEint1 = os_tsk_create (TaskEint1, 100);//创建TaskEint1任务及级别
IdTaskEint2 = os_tsk_create (TaskEint2, 100);//创建TaskEint2任务及级别
IdTaskEint3 = os_tsk_create (TaskEint3, 100);//创建TaskEint3任务及级别
for (;;) {
Count ++;//TaskMain任务事件计数
if ((Count % 10) == 0) os_evt_set (FCount, IdTask1);//每10次执行Task1任务
else os_evt_set (0x2222, IdTask2);//其他9次执行Task2任务
IOPIN0 ^= (1 << P0_16); //取反P0.16
os_dly_wait (1);//延时10mS并将控制权交还OS
}
}
void Task1 (void) __task {
OS_RESULT result;
unsigned int i;
for (;;) {
result = os_evt_wait_or(0xffff, 0xffff);//等待Task1任务事件发生
if(result == OS_R_EVT) {//未超时
i = os_evt_get();
switch(i) {
case 1: FCount = 2;
break;
case 2: FCount = 3;
break;
case 3: FCount = 4;
break;
case 4: FCount = 1;
break;
}
Count1 ++;//Task1任务事件计数
}
else {
Count10 ++;
}
}
}
void Task2 (void) __task {
OS_RESULT result;
//volatile unsigned int Count2 = 0;
for (;;) {
result = os_evt_wait_and(0x2222, 0xffff);//等待Task2任务事件发生
if(result == OS_R_EVT) {//未超时
Count2 ++;//Task2任务事件计数
}
else {
Count20 ++;
}
}
}
void TaskEint0 (void) __task {
OS_RESULT result;
for (;;) {
result = os_evt_wait_and(0x1000, 0xffff);//等待TaskEint0任务事件发生
if(result == OS_R_EVT) {//未超时
Sum0 ++;//TaskEint0任务事件计数
}
else {
Sum00 ++;
}
}
}
void TaskEint1 (void) __task {
OS_RESULT result;
//unsigned int Eint1Count = 0;
for (;;) {
result = os_evt_wait_and(0x2000, 0xffff);//等待TaskEint1任务事件发生
if(result == OS_R_EVT) {//未超时
Sum1 ++;//TaskEint1任务事件计数
IOSET1 = (1 << P1_23);
Eint1Count = 0;
PINSEL0 &= ~(P0_3_EINT1 << P0_3_PINSEL); //重新选择P0.3为普通IO引脚!!!
while ((IOPIN0 & (1 << P0_3)) == 0) {//等待P0.3变为高电平,注意没上句程序将不能测IO引脚电平!!!
os_dly_wait (1);//延时10mS并将控制权交还OS
Eint1Count ++;
}
PINSEL0 |= (P0_3_EINT1 << P0_3_PINSEL); //重新选择P0.3为INT1外部中断引脚!!!
if (Eint1Count >= 2) {//20mS
if (Eint1Count >= 100) {//1000mS
IOPIN1 |= (1 << P1_22);//可认为长压键
}
else {//大于20mS小于1S
IOPIN1 &= ~(1 << P1_22);//可认为短压键
}
}
else {//认为无键压下
}
IOCLR1 = (1 << P1_23);
}
else {
Sum10 ++;
}
}
}
//以上结论为:非IO配置的引脚不能测试IO引脚,否则只能临时改变IO配置才能正确测试IO引脚!!!
void TaskEint2 (void) __task {
OS_RESULT result;
for (;;) {
result = os_evt_wait_and(0x3000, 0xffff);//等待TaskEint2任务事件发生
if(result == OS_R_EVT) {//未超时
Sum2 ++;//TaskEint2任务事件计数
}
else {
Sum20 ++;
}
}
}
void TaskEint3 (void) __task {
OS_RESULT result;
for (;;) {
result = os_evt_wait_and(0x4000, 0xffff);//等待TaskEint3任务事件发生
if(result == OS_R_EVT) {//未超时
Sum3 ++;//TaskEint3任务事件计数
}
else {
Sum30 ++;
}
}
}
void main (void) {
di();//关irq,fiq中断
IODIR0 = 0;//全部设置为输入方式
IODIR0 |= (1 << P0_16);//设置LED输出方式
IODIR1 = 0;//全部设置为输入方式
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 = 0;//全部选择第1功能
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 = 0;//全部选择第1功能
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仿真不了,非也,原来PINSEL1没初始化!!!)
//以上多引脚配置为中断功能但只有管脚号小的才能引发中断!!!
//即
//Eint0---P0.1(有效),P0.16(无效)
//Eint1---P0.3(有效),P0.14(无效)
//Eint2---P0.7(有效),P0.15(无效)
//Eint3---P0.9(有效),P0.20(无效),P30(无效)
//Eint3---P0.9(有效),P0.20(无效)
//Eint3---P0.9(有效),P30(无效)
//Eint3---P0.20(有效),P30(无效)
//以上只是通过Keil仿真得出,可能有误导之嫌!!!
//不知如何才能让多引脚引发中断???
EXTPOLAR &= ~((1 << EXTPOLAR0) //INT0为低电平有效
| (1 << EXTPOLAR1) //INT1为低电平有效
| (1 << EXTPOLAR2) //INT2为低电平有效
| (1 << EXTPOLAR3));//INT3为低电平有效
EXTPOLAR |= (1 << EXTPOLAR0); //INT0为高电平有效
EXTMODE |= (1 << EXTMODE0) //设置INT0为边沿触发
| (1 << EXTMODE1) //设置INT1为边沿触发(将原来的电平触发改为边沿触发不要兜死OS且进行IO测试演示)
| (1 << EXTMODE2) //设置INT2为边沿触发
| (1 << EXTMODE3);//设置INT3为边沿触发
// EXTMODE &= ~(1 << EXTMODE1);//设置INT1为电平触发(屏蔽此句为了不兜死OS且进行IO测试演示,见任务TaskEint1()内的处理)
VICVectCntl0 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT0;//获取EINT0的IRQ级别
VICVectAddr0 = (long) EINT0IRQ;//取INT0中断服务地址
VICVectCntl1 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT1;//获取EINT1的IRQ级别
VICVectAddr1 = (long)EINT1IRQ;//取INT1中断服务地址
VICVectCntl2 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT2;//获取EINT2的IRQ级别
VICVectAddr2 = (long)EINT2IRQ;//取INT2中断服务地址
VICVectCntl3 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT3;//获取EINT3的IRQ级别
VICVectAddr3 = (long)EINT3IRQ;//取INT3中断服务地址
EXTINT = (1 << EINT0) | (1 << EINT1) | (1 << EINT2) | (1 << EINT3); //清除INT中断标志
VICIntEnable = (1 << VICIntSel_EINT0) //使能EINT0中断
| (1 << VICIntSel_EINT1) //使能EINT1中断
| (1 << VICIntSel_EINT2) //使能EINT2中断
| (1 << VICIntSel_EINT3);//使能EINT3中断
ei();//开irq,fiq中断
os_sys_init (TaskMain);//启动ARTX,此函数并不返回main()
}
答 1: 本帖只是经过软仿真,不知那位"地主"能给硬件调试一番???纸上谈兵确实很乏味...有苦难言!!! 答 2: 多引脚触发中断需要触发方式相同然后读引脚状态即可判断
ARTX菜鸟中断嵌套笔记
代码长度 6660(优化)
HotPower@126.com 2005.9.17 于西安大雁塔村队部
---------------------------------------------------------*/
#include <ARTX.h>
#include <LPC213x.H> // Philips Peripheral Registers
#include <LPC213xDEF.H> //ARM菜鸟HotPower创建定义文件
//本程序共有7个任务,需改写OS_TASK_CNT为7
OS_TID IdTask, IdTask1, IdTask2;
OS_TID IdTaskEint0, IdTaskEint1, IdTaskEint2, IdTaskEint3;
void TaskMain (void) __task;
void Task1 (void) __task;
void Task2 (void) __task;
void TaskEint0 (void) __task;//外部中断Eint0处理任务
void TaskEint1 (void) __task;//外部中断Eint1处理任务
void TaskEint2 (void) __task;//外部中断Eint2处理任务
void TaskEint3 (void) __task;//外部中断Eint3处理任务
volatile unsigned int FCount = 1;
volatile unsigned int Count = 0;
volatile unsigned int Count1 = 0;
volatile unsigned int Count2 = 0;
volatile unsigned int Count10 = 0;
volatile unsigned int Count20 = 0;
volatile unsigned int Sum0 = 0;
volatile unsigned int Sum00 = 0;
volatile unsigned int Sum1 = 0;
volatile unsigned int Sum10 = 0;
volatile unsigned int Sum2 = 0;
volatile unsigned int Sum20 = 0;
volatile unsigned int Sum3 = 0;
volatile unsigned int Sum30 = 0;
unsigned int Eint1Count = 0;
void EINT0IRQ(void) __irq;//声明中断ISR函数
void EINT1IRQ(void) __irq;//声明中断ISR函数
void EINT2IRQ(void) __irq;//声明中断ISR函数
void EINT3IRQ(void) __irq;//声明中断ISR函数
// Macros for Interrupt Nesting
#define IENABLE /* Nested Interrupts Entry */ \
__asm { MRS LR, SPSR } /* Copy SPSR_irq to LR */ \
__asm { STMFD SP!, {LR} } /* Save SPSR_irq */ \
__asm { MSR CPSR_c, #0x1F } /* Enable IRQ (Sys Mode) */ \
__asm { STMFD SP!, {LR} } /* Save LR */ \
#define IDISABLE /* Nested Interrupts Exit */ \
__asm { LDMFD SP!, {LR} } /* Restore LR */ \
__asm { MSR CPSR_c, #0x92 } /* Disable IRQ (IRQ Mode) */ \
__asm { LDMFD SP!, {LR} } /* Restore SPSR_irq to LR */ \
__asm { MSR SPSR_cxsf, LR } /* Copy LR to SPSR_irq */ \
void ei() __ARM __swi(8)
{
__asm
{
STMFD SP,{R0}
MRS R0, SPSR
BIC R0, R0, #0xc0;//打开irq,fiq中断
MSR SPSR_c, R0
LDMFD SP,{R0}
}
}
void di() __ARM __swi(9)
{
__asm
{
STMFD SP,{R0}
MRS R0, SPSR
ORR R0, R0, #0xc0;//关闭irq,fiq中断
MSR SPSR_c, R0
LDMFD SP,{R0}
}
}
void EINT0IRQ (void) __irq{//IRQ中断函数EINT0IRQ被挂接在VICVectCntl0
if (VICIRQStatus & (1 << VICIntSel_EINT0)) {
IOPIN1 ^= (1 << P1_16); //取反P1.16
isr_evt_set (0x1000, IdTaskEint0);//退出中断后立即执行TaskEint0任务
}
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
EXTINT = (1 << EINT1); //清除INT1中断标志
IENABLE;//开放中断嵌套
PINSEL0 &= ~(P0_3_EINT1 << P0_3_PINSEL); //重新选择P0.3为普通IO引脚!!!
while ((IOPIN0 & (1 << P0_3)) == 0);//等待P0.3变为高电平,注意没上句程序将不能测IO引脚电平!!!
PINSEL0 |= (P0_3_EINT1 << P0_3_PINSEL); //重新选择P0.3为INT1外部中断引脚!!!
IDISABLE;//关闭中断嵌套
isr_evt_set (0x2000, IdTaskEint1);//退出中断后立即执行TaskEint1任务
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
isr_evt_set (0x3000, IdTaskEint2);//退出中断后立即执行TaskEint2任务
}
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
isr_evt_set (0x4000, IdTaskEint3);//退出中断后立即执行TaskEint3任务
}
EXTINT = (1 << EINT3); //清除INT3中断标志
VICSoftIntClr = (1 << VICIntSel_EINT3);
VICVectAddr = 0;
}
void TaskMain (void) __task {
IdTask = os_tsk_self ();//取本任务ID
os_tsk_prio_self (13);//任务级别
IdTask1 = os_tsk_create (Task1, 11);//创建Task1任务及级别
IdTask2 = os_tsk_create (Task2, 11);//创建Task2任务及级别
IdTaskEint0 = os_tsk_create (TaskEint0, 100);//创建TaskEint0任务及级别
IdTaskEint1 = os_tsk_create (TaskEint1, 100);//创建TaskEint1任务及级别
IdTaskEint2 = os_tsk_create (TaskEint2, 100);//创建TaskEint2任务及级别
IdTaskEint3 = os_tsk_create (TaskEint3, 100);//创建TaskEint3任务及级别
for (;;) {
Count ++;//TaskMain任务事件计数
if ((Count % 10) == 0) os_evt_set (FCount, IdTask1);//每10次执行Task1任务
else os_evt_set (0x2222, IdTask2);//其他9次执行Task2任务
IOPIN0 ^= (1 << P0_16); //取反P0.16
os_dly_wait (1);//延时10mS并将控制权交还OS
}
}
void Task1 (void) __task {
OS_RESULT result;
unsigned int i;
for (;;) {
result = os_evt_wait_or(0xffff, 0xffff);//等待Task1任务事件发生
if(result == OS_R_EVT) {//未超时
i = os_evt_get();
switch(i) {
case 1: FCount = 2;
break;
case 2: FCount = 3;
break;
case 3: FCount = 4;
break;
case 4: FCount = 1;
break;
}
Count1 ++;//Task1任务事件计数
}
else {
Count10 ++;
}
}
}
void Task2 (void) __task {
OS_RESULT result;
//volatile unsigned int Count2 = 0;
for (;;) {
result = os_evt_wait_and(0x2222, 0xffff);//等待Task2任务事件发生
if(result == OS_R_EVT) {//未超时
Count2 ++;//Task2任务事件计数
}
else {
Count20 ++;
}
}
}
void TaskEint0 (void) __task {
OS_RESULT result;
for (;;) {
result = os_evt_wait_and(0x1000, 0xffff);//等待TaskEint0任务事件发生
if(result == OS_R_EVT) {//未超时
Sum0 ++;//TaskEint0任务事件计数
}
else {
Sum00 ++;
}
}
}
void TaskEint1 (void) __task {
OS_RESULT result;
//unsigned int Eint1Count = 0;
for (;;) {
result = os_evt_wait_and(0x2000, 0xffff);//等待TaskEint1任务事件发生
if(result == OS_R_EVT) {//未超时
Sum1 ++;//TaskEint1任务事件计数
IOSET1 = (1 << P1_23);
Eint1Count = 0;
PINSEL0 &= ~(P0_3_EINT1 << P0_3_PINSEL); //重新选择P0.3为普通IO引脚!!!
while ((IOPIN0 & (1 << P0_3)) == 0) {//等待P0.3变为高电平,注意没上句程序将不能测IO引脚电平!!!
os_dly_wait (1);//延时10mS并将控制权交还OS
Eint1Count ++;
}
PINSEL0 |= (P0_3_EINT1 << P0_3_PINSEL); //重新选择P0.3为INT1外部中断引脚!!!
if (Eint1Count >= 2) {//20mS
if (Eint1Count >= 100) {//1000mS
IOPIN1 |= (1 << P1_22);//可认为长压键
}
else {//大于20mS小于1S
IOPIN1 &= ~(1 << P1_22);//可认为短压键
}
}
else {//认为无键压下
}
IOCLR1 = (1 << P1_23);
}
else {
Sum10 ++;
}
}
}
//以上结论为:非IO配置的引脚不能测试IO引脚,否则只能临时改变IO配置才能正确测试IO引脚!!!
void TaskEint2 (void) __task {
OS_RESULT result;
for (;;) {
result = os_evt_wait_and(0x3000, 0xffff);//等待TaskEint2任务事件发生
if(result == OS_R_EVT) {//未超时
Sum2 ++;//TaskEint2任务事件计数
}
else {
Sum20 ++;
}
}
}
void TaskEint3 (void) __task {
OS_RESULT result;
for (;;) {
result = os_evt_wait_and(0x4000, 0xffff);//等待TaskEint3任务事件发生
if(result == OS_R_EVT) {//未超时
Sum3 ++;//TaskEint3任务事件计数
}
else {
Sum30 ++;
}
}
}
void main (void) {
di();//关irq,fiq中断
IODIR0 = 0;//全部设置为输入方式
IODIR0 |= (1 << P0_16);//设置LED输出方式
IODIR1 = 0;//全部设置为输入方式
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 = 0;//全部选择第1功能
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 = 0;//全部选择第1功能
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仿真不了,非也,原来PINSEL1没初始化!!!)
//以上多引脚配置为中断功能但只有管脚号小的才能引发中断!!!
//即
//Eint0---P0.1(有效),P0.16(无效)
//Eint1---P0.3(有效),P0.14(无效)
//Eint2---P0.7(有效),P0.15(无效)
//Eint3---P0.9(有效),P0.20(无效),P30(无效)
//Eint3---P0.9(有效),P0.20(无效)
//Eint3---P0.9(有效),P30(无效)
//Eint3---P0.20(有效),P30(无效)
//以上只是通过Keil仿真得出,可能有误导之嫌!!!
//不知如何才能让多引脚引发中断???
EXTPOLAR &= ~((1 << EXTPOLAR0) //INT0为低电平有效
| (1 << EXTPOLAR1) //INT1为低电平有效
| (1 << EXTPOLAR2) //INT2为低电平有效
| (1 << EXTPOLAR3));//INT3为低电平有效
EXTPOLAR |= (1 << EXTPOLAR0); //INT0为高电平有效
EXTMODE |= (1 << EXTMODE0) //设置INT0为边沿触发
| (1 << EXTMODE1) //设置INT1为边沿触发(将原来的电平触发改为边沿触发不要兜死OS且进行IO测试演示)
| (1 << EXTMODE2) //设置INT2为边沿触发
| (1 << EXTMODE3);//设置INT3为边沿触发
// EXTMODE &= ~(1 << EXTMODE1);//设置INT1为电平触发(屏蔽此句为了不兜死OS且进行IO测试演示,见任务TaskEint1()内的处理)
VICVectCntl0 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT0;//获取EINT0的IRQ级别
VICVectAddr0 = (long) EINT0IRQ;//取INT0中断服务地址
VICVectCntl1 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT1;//获取EINT1的IRQ级别
VICVectAddr1 = (long)EINT1IRQ;//取INT1中断服务地址
VICVectCntl2 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT2;//获取EINT2的IRQ级别
VICVectAddr2 = (long)EINT2IRQ;//取INT2中断服务地址
VICVectCntl3 = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT3;//获取EINT3的IRQ级别
VICVectAddr3 = (long)EINT3IRQ;//取INT3中断服务地址
EXTINT = (1 << EINT0) | (1 << EINT1) | (1 << EINT2) | (1 << EINT3); //清除INT中断标志
VICIntEnable = (1 << VICIntSel_EINT0) //使能EINT0中断
| (1 << VICIntSel_EINT1) //使能EINT1中断
| (1 << VICIntSel_EINT2) //使能EINT2中断
| (1 << VICIntSel_EINT3);//使能EINT3中断
ei();//开irq,fiq中断
os_sys_init (TaskMain);//启动ARTX,此函数并不返回main()
}
答 1: 本帖只是经过软仿真,不知那位"地主"能给硬件调试一番???纸上谈兵确实很乏味...有苦难言!!! 答 2: 多引脚触发中断需要触发方式相同然后读引脚状态即可判断
共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分 |