在cc2530的中断控制器,共有18个中断源:
其中P0INT, P1INT, P2INT分别是P0, P1, P2组IO口的中断号.
外部中断其实就是指GPIO口的中断功能, 也就是当一个IO口的电平发生变化时自动产生一个硬件信号,自动暂停当前程序的执行,触发调用一个处理函数.
一个IO口的电平状态有: 高电平, 低电平, 下降沿, 上升沿, 双边沿
CC2530外部中断线只能捕捉:下降沿/上升沿
注意下, P0INT表示只要是属于P0组任意一个IO口的中断, 都需要使能此中断号的中断功能.
外部中断相关的配置寄存器:
上图寄存器的第7位是关于中断功能总开关的使能。只有设1, cc2530的中断功能才会工作.
/
上图的第5位是设置P0组的IO口中断功能是否打开. 设1打开P0组中断功能.
///
上图寄存器的第4位设置P1组IO口的中断功能, 第1位设置P2组IO口的中断功能
//
PxIEN寄存器用于设置组内的具体哪些IO口的中断功能打开,第几位就是表示相应的第几个IO口功能打开.
//
上图寄存器用于指定外部中断的是上升沿还是下降沿时触发中断信号.
///
中断触发后,需要清除中断标志,否则中断控制器会一直产生相应的中断信号,直到清除相应的中断标志为止。相应的位写0清除中断.
外部中断相关的清中断寄存器:
上图寄存器的第5位清除P0组IO口的中断信号。写’0’清除.
上图寄存器的第3位用于清除P1组IO口的中断信号, 第0位用于清除P2组IO口的中断信号.
PxIFG用于清除组内具体哪一个IO口的中断信号.
指定处理哪种中断的中断处理函数:
在iocc2530.h头文件里:
#define RFERR_VECTOR VECT( 0, 0x03 ) /* RF TX FIFO Underflow and RX FIFO Overflow */
#define ADC_VECTOR VECT( 1, 0x0B ) /* ADC End of Conversion */
#define URX0_VECTOR VECT( 2, 0x13 ) /* USART0 RX Complete */
#define URX1_VECTOR VECT( 3, 0x1B ) /* USART1 RX Complete */
#define ENC_VECTOR VECT( 4, 0x23 ) /* AES Encryption/Decryption Complete */
#define ST_VECTOR VECT( 5, 0x2B ) /* Sleep Timer Compare */
#define P2INT_VECTOR VECT( 6, 0x33 ) /* Port 2 Inputs */
#define UTX0_VECTOR VECT( 7, 0x3B ) /* USART0 TX Complete */
#define DMA_VECTOR VECT( 8, 0x43 ) /* DMA Transfer Complete */
#define T1_VECTOR VECT( 9, 0x4B ) /* Timer 1 (16-bit) Capture/Compare/Overflow */
#define T2_VECTOR VECT( 10, 0x53 ) /* Timer 2 (MAC Timer) */
#define T3_VECTOR VECT( 11, 0x5B ) /* Timer 3 (8-bit) Capture/Compare/Overflow */
#define T4_VECTOR VECT( 12, 0x63 ) /* Timer 4 (8-bit) Capture/Compare/Overflow */
#define P0INT_VECTOR VECT( 13, 0x6B ) /* Port 0 Inputs */
#define UTX1_VECTOR VECT( 14, 0x73 ) /* USART1 TX Complete */
#define P1INT_VECTOR VECT( 15, 0x7B ) /* Port 1 Inputs */
#define RF_VECTOR VECT( 16, 0x83 ) /* RF General Interrupts */
#define WDT_VECTOR VECT( 17, 0x8B ) /* Watchdog Overflow in Timer Mode */
#pragma vector = P0INT_VECTOR //这里指定中断函数处理哪种中断信号, 这里指定P0组的中断
__interrupt void irq_func(void)
{
...
//清除中断
}
///
实验, cc2530的P0_5外接一个光敏电阻模块。当模块感应到足够的光时,输出低电平。当感应不到足够的光时,输出高电平。
当从低到高电平的转变过程中,就有上升沿了。所以可以捕捉P0_5的上升沿中断来判断是否天黑等环境因素的改变。
main.c
#include <string.h>
#include <iocc2530.h>
void delayms(int ms);
void uart_init(void);
void putchar(char ch);
void puts(char *line);
char getchar(void);
int gets(char *line);
void leds_on();
void leds_off();
void main(void)
{
uart_init();
char chs[100];
// 光敏电阻模块的数据脚接在P0_5引脚
// 模块感应到足够的光时,处于低电平状态, 当感应不到足够的光时,变为高电平状态(从低电平到高电平的过程中有上升沿)
IRCON &= ~(1<<5); //清除P0组的中断信号
P0IFG &= ~(1<<5); //清除P0组里的第5个IO口的中断信号
P0IEN |= 1<<5; //使能P0组里的第5个IO口的中断功能
PICTL &= ~1; // 设置P0组的IO口在上升沿电平变化时产生中断信号
IEN1 |= 1<<5; //打开P0组IO口的中断功能
IEN0 |= 1<<7; //中断功能总开关打开
///
puts("\033[2J");
puts("#################################\n");
puts("# #\n");
puts("# my zigbee center #\n");
puts("# #\n");
puts("#################################\n\n");
while (1)
{
puts("\nmyshell # ");
gets(chs);
puts(chs);
}
}
#pragma vector = P0INT_VECTOR
__interrupt void int_func(void)
{
if (P0 & (1<<5))
{
puts("no light\n");
leds_off();
}
else
{
puts("light up\n");
leds_on();
}
P0IFG &= ~(1<<5); //清除P0组里的第5个IO口的中断信号
IRCON &= ~(1<<5); //清除P0组的中断信号
}
void leds_on()
{
P1 &= ~3;
puts("leds on .....\n");
}
void leds_off()
{
P1 |= 3;
puts("leds off ....\n");
}
int gets(char *line)
{
char *p = line;
while (1)
{
*p = getchar();
if (*p == '\n')
break;
p++;
}
*p = 0;
return p - line;
}
char getchar()
{
char tmp;
while (!(U0CSR & (1<<2)))
;
tmp = U0DBUF;
if (tmp == '\r') // mincom 鏀跺埌'\n' --> '\r'
tmp = '\n';
putchar(tmp);
return tmp;
}
void puts(char *line)
{
while (*line)
putchar(*line++);
}
void putchar(char ch)
{
U0CSR &= ~(1<<1); // clear tx status
U0DBUF = ch;
while (!(U0CSR & (1<<1)))
;
if (ch == '\n')
putchar('\r');
}
void uart_init(void)
{
// 16Mhz --> 32Mhz
CLKCONCMD &= ~(1<<6); // OSC: 32Mhz
while (CLKCONSTA & (1<<6))
;
CLKCONCMD &= ~7; //32Mhz
P0SEL |= (1<<2)|(1<<3); //P0_2, P0_3 as uart0_rx/tx
PERCFG &= ~1; //uart0 alt1(p0_2, P0_3)
U0CSR = (1<<7)|(1<<6); // uart mode, uart rx enable
U0UCR = 0; //8N1
//115200
// U0GCR = 11;
// U0BAUD = 216;
// 9600
U0GCR = 8;
U0BAUD = 59;
}
void delayms(int ms)
{
int i, j;
for (i = 0; i < ms*2; i++)
for (j = 0; j < 535; j++)
;
}