ARTX菜鸟外部中断笔记
hotpower 发表于 2005-8-21 13:36:21 Philips ARM ←返回版面
/*--------------------------------------------------------
ARTX菜鸟外部中断笔记
代码长度 6048
HotPower@126.com 2005.8.21 于西安大雁塔村队部
---------------------------------------------------------*/
#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 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;
void EINT0IRQ(void) __irq;//声明中断ISR函数
void EINT1IRQ(void) __irq;//声明中断ISR函数
void EINT2IRQ(void) __irq;//声明中断ISR函数
void EINT3IRQ(void) __irq;//声明中断ISR函数
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
isr_evt_set (0x2000, IdTaskEint1);//退出中断后立即执行TaskEint1任务
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
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 {
//volatile unsigned int Count = 0;
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 (0x1111, IdTask1);//每10次执行Task1任务
else os_evt_set (0x2222, IdTask2);//其他9次执行Task2任务
os_dly_wait (1);//延时10mS并将控制权交还OS
}
}
void Task1 (void) __task {
OS_RESULT result;
//volatile unsigned int Count1 = 0;
for (;;) {
result = os_evt_wait_and(0x1111, 0xffff);//等待Task1任务事件发生
if(result == OS_R_EVT) {//未超时
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;
for (;;) {
result = os_evt_wait_and(0x2000, 0xffff);//等待TaskEint1任务事件发生
if(result == OS_R_EVT) {//未超时
Sum1 ++;//TaskEint1任务事件计数
}
else {
Sum10 ++;
}
}
}
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) {
IODIR0 |= (1 << P0_16);//设置LED输出方式
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 = (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中断
os_sys_init (TaskMain);//启动ARTX,此函数并不返回main()
}
|