在做实验之前我们先来了解一下cc2530的51内核的外部中断的基本信息,同样我们去datasheet里面找找这些中断的说明文字:
Interrupts
The CPU has 18 interrupt sources. Each source has its own request flag located in a set of interrupt flag
SFR registers. Each interrupt requested by the corresponding flag can be individually enabled or disabled.
The definitions of the interrupt sources and the interrupt vectors are given in Table 2-5 .
就是说cc2530的51内核有18个中断源,每个中断源都有自己的中断标志SFR寄存器,每个中断源都可以开启或者关闭,具体的这18个中断源如下:
在上面我们可以看到这18个中断源的基本情况,以及他们被分开了三个中断控制小分队长寄存器IENX,以及对应关系
当然,这么多中断我不可能一一说明,所以这里我选择了一个最简单的,基本的io中断来做一个实验,来说明这些中断的初始化以及处理,其实讲中断主要是为了下面做休眠实验做准备。
好了,我现在不用上一节说的佳杰的板子了,直接用我们公司自己画的板子,因为我们做的板子就只有一块很小的板子,io口全是裸露出来的,我想怎么弄就怎么弄,为了方便我的按键也没有加上拉电阻,字节是从cpu的io口出来,然后接按键的一个脚,然后按键的另外一个脚接在了GND,就这么简单,当然,这肯定是不行的,你还得加该加的东西,我这里只是为了试验而已,并不是真正的产品。而且我不是硬件工程师,也不会这些东西。
因为以前是学嵌入式linux的,还有就是大学的时候深受java编程的影响,一切都喜欢封装,来到了单片机这里,同样喜欢把不同的代码放在不同的代码实现文件中,不喜欢全部放在一个.c文件。我把led的操作和宏定义定义在了hal_led.h和hal_led.c中。
hal_led.h
#include
CC2530.h> #define LED_NUM_1 0x00
#define LED_NUM_2 0x01
#define LED_NUM_3 0x02
#define LED_NUM_4 0x03
#define LED_MODE_ON 0x00
#define LED_MODE_OFF 0x01
void hal_init_led(void);
void hal_set_led_mode(unsigned char led,unsigned char mode);
hal_led.c
#include "hal_led.h"
#define LED1 P1_2
#define LED2 P1_3
#define LED3 P1_5
#define LED4 P1_6
void hal_init_led(void)
{
P1SEL &= ~0x6C; //01101100
P1DIR |= 0x6C;
LED1 = LED_MODE_OFF;
LED2 = LED_MODE_OFF;
LED3 = LED_MODE_OFF;
LED4 = LED_MODE_OFF;
}
void hal_set_led_mode(unsigned char led,unsigned char mode)
{
mode = !!mode;
switch(led){
case LED_NUM_1:
LED1 = mode;
break;
case LED_NUM_2:
LED2 = mode;
break;
case LED_NUM_3:
LED3 = mode;
break;
case LED_NUM_4:
LED4 = mode;
break;
default:
break;
}
return;
}
这部分代码在之前的IO实验中已经解析过,只是修改了LED的io而已,就根据datasheet修改就行了,就不解析了。
下面上按键部分代码,这部分代码就只有初始化和一个中断处理函数而已
void hal_init_key(void)
{
P1SEL &= ~0x01;
P1DIR |= 0X01;
P1IEN |= 0X01; //P10设置为中断方式
PICTL |= 0X02; //下降沿触发
EA = 1;
IEN2 |= 0x10;
P1IFG = 0;
}
先来解析这个初始化代码先,其实思路很简单,初始化IO口为普通io并且设置io口模式为输入模式--->设置P1.0端口为中断模式并且是下降沿触发然后开中断
上面设置io的那部分就不解析了,因为和之前的设置是一样的,只是之前设置为输出,现在设置为输入而已,来看看中断设置这部分:
老办法,我们先来datasheet找找P1IEN这个寄存器,可以找到这么一段:
The SFR registers used for interrupts are described later in this section. The registers are summarized as follows:
• P0IEN : P0 interrupt enables
• P1IEN : P1 interrupt enables
• P2IEN : P2 interrupt enables
• PICTL : P0, P1, and P2 edge configuration
• P0IFG : P0 interrupt flags
• P1IFG : P1 interrupt flags
• P2IFG : P2 interrupt flags
意思就是说pxIEN是设置中断源的使能的,同样我们找这个P1IEN的table看看
这里可以看到这个寄存器的0-7bit是设置p1.0-p1.7的中断使能的,P1IEN |= 0X01;就是使能p1.0的中断
同样的办法找PICTL的解析和table,其实PICTL的解析就在上面:PICTL : P0, P1, and P2 edge configuration
这个寄存器是设置p0,p1,p2的触发模式的,上他的table
因为我们是P1.0所以我们看p1的,我么可以看到P1ICONL和P1ICONH这两个bit,第一个是设置p1.3-p1.0的,第二个是设置p1.7-p1.4的,那么PICTL |= 0X02;刚好设置的就是p1.0的
EA是中断的总开关,就算我们一栋楼里的总闸一样,IEN2是中断的小分队长,就像我们出租屋里的自己那个房子的总闸一样,因为我们用到的是p1,我们通过上面的中断源的那个table可以找到p1的开关是IEN2,当然,如果你用别的io,必须改用别的寄存器,我们看看IEN2的table
至于为什么是IEN2 |= 0x10;我就不说了,再说就废话了。到此初始化工作到此结束。
下面就看看中断处理函数,因为我只是为了得到这个中断而已,所以没多按钮做太多处理,实际应用请自己加上
#pragma vector = P1INT_VECTOR
__interrupt void P1_ISR(void)
{
if(P1IFG>0)
{
if(P1IFG == 0x01)
{
hal_set_led_mode(LED_NUM_1,ledStatus);
ledStatus = !ledStatus;
}
P1IFG = 0;
}
P1IF = 0;
}
这没什么好说的,我这里的处理就是按下按键,然后取反LED灯而已。
好了,上main函数,结束这篇笔记
int ledStatus = 0;
void main(void)
{
initxsta();
hal_init_led();
hal_init_key();
while(1);
}
到此,对于p1_0这个io端口的中断我弄完了,也就结束了我的外部中断的实验。
上一篇:51单片机系列知识14--1206LCD(2)
下一篇:cc2530裸机编程系列笔记5--中断
推荐阅读最新更新时间:2024-11-09 21:49
设计资源 培训 开发板 精华推荐
- DER-815 - 使用 InnoSwitch3-CP 的 45 W 24 V 输出隔离反激式电源,适用于智能扬声器和管状电机
- ADP165CP-EVALZ,ADP165 TSOT LDO 线性稳压器评估板
- LT8607IMSE 超低 EMI、5V、1.5A 降压型稳压器的典型应用电路
- 使用 NXP Semiconductors 的 AD1848 的参考设计
- DC1861A,使用 LTC5567 300MHz 至 4GHz 有源下变频混频器和宽带 IF 的演示板
- SP6133同步降压控制器典型应用电路
- AM1/4S-0518SZ 18V 0.25 瓦 DC-DC 转换器的典型应用
- LT3430 高电压降压稳压器为 FireWire 外设提供高电流、薄型电源解决方案
- LT3663IMS8E-3.3 5V 降压转换器的典型应用
- AD9852/PCB,用于评估 AD9852 300-MSPS DDS 数字合成器的评估板