Part of the content is my self-recognition and is for reference only. Please add if there is any deficiency.
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . ---------------------The first step --------------------- . . . .
. . . . ——————Introduction of related registers——————. . .
. . . . ---------------------The second step --------------------- . . . .
. . . . ——Introduce part of the content after the overall code is split—— . . .
. . . . ---------------------The third step --------------------- . . . .
. . . . —————— Present the overall code——————. . . .
. . . . --------------------- Fourth step --------------------- . . . .
. . . . --------to sum up--------. . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
————Go directly to the case to explain the interruption————
Task: Long press or short press button 1 to control LED6 and LED4 (using port 1 interrupt and timer 1 interrupt to achieve)
Related registers related to LED
P1SEL (Port 1 set level)——Port 1 function register
P1DIR (Port 1 direction register) -Port 1 direction register
P1 (Port 1)——Port 1
Store status information of P1_0 to P1_7.
Related registers related to port 1 interrupt
PICTL (Port input communication trigger level) -port input signal
P1IFG (Port 1 interrupt flag group) -P1 port status flag register
P1IEN (Port 1 interrupt enable)——P1 port interrupt enable
IEN0 (Interrupt enable 0)-Interrupt enable register 0
IEN2 (Interrupt enable 2)-Interrupt enable register 2
Related registers related to timer 1 interrupt
T1CCTLx (Time1 Capture Control)——port input signal
Use channel 0 as the timer channel
IEN1 (Interrupt enable 1)-Interrupt enable register 1
T1STAT (Time1 State Thoroughfare)-P1 port status flag register
Use channel 0 as the timer channel
Simple delay part
Since it takes time for the CPU to execute an instruction, making the CPU full of instruction bars can achieve a visual delay
void HAL_Delay(uint32_t num)
{
for(uint32_t x=0;x<=num;x++)
for(uint32_t y=0;y<=535;y++);
}
Initialize the LED part
The corresponding object of the pin
P1_1 ==> light 4
P1_4 ==> light 6
void Init_Port()
{
P1SEL &=~ 0x1b; //设置P1_0、P1_1、P1_3、P1_4为通用I/O功能。
P1DIR |= 0x1b; //设置P1_0、P1_1、P1_3、P1_4的传输方向为输出。
P1 &=~ 0x1b; //设置P1_0、P1_1、P1_3、P1_4为0(D3、D4、D5、D6关闭)
}
Initialize the interrupt part of port 1
void Init_P1INT()
{
IEN2 |= 0x10; //设置端口1中断使能为1
P1IEN |= 0x04; //设置端口P1_2中断使能
PICTL |= 0x02; //设置端口P1_3到P1_0中断触发方式为下降沿触发
}
Initialize the part of timer 1 interrupt
void Init_T1()
{
EA = 1;
T1IE = 1;
T1CCTL0 |= 0x04; //设置通道0为定时器1的
T1CC0L = 0xd4; //设置T1CC0的初始值
T1CC0H = 0x30;
}
Timer interrupt service function part
#pragma vector = T1_VECTOR //定义中断向量
__interrupt void T1_Serivce(void) //设置中断服务函数名
{
if((P1_Flag == 1) && (count != 65535)) //防止count溢出
count++;
}
Timer interrupt service function part
#pragma vector = P1INT_VECTOR //定义中断向量
__interrupt void P1INT_Serivce(void) //设置中断服务函数名
{
if((P1IFG & 0x04) == 0x04) //是否检测到下降沿产生的中断标志
{
P1IFG = 0;
P1IF = 0;
IP0 |= 0x02; //提高定时器1优先级
T1CTL |= 0x0e; //开启定时器1
PICTL &= ~0x02; //切换端口1为上升沿触发
P1_Flag = 1;
while((P1IFG & 0x04) != 0x04); //等待按键松开
P1IFG = 0;
P1IF = 0;
P1_Flag = 0;
PICTL |= 0x02; //切换端口1为下降沿触发
T1CTL = 0; //关闭定时器1
if(count <= 5)
D4 = ~D4;
else
D6 = ~D6;
count = 0;
}
}
Overall code
#include<iocc2530.h>
#define uint32_t unsigned int
#define uint8_t unsigned char
#define D4 P1_1
#define D5 P1_3
#define D6 P1_4
/**************************************************************
函数名称:HAL_Delay
功 能:软件延时
入口参数:延时循环执行次数
出口参数:无
返 回 值:无
**************************************************************/
void HAL_Delay(uint32_t num)
{
for(uint32_t x=0;x<=num;x++)
for(uint32_t y=0;y<=535;y++);
}
/**************************************************************
函数名称:Init_Port
功 能:初始化端口
入口参数:无
出口参数:无
返 回 值:无
**************************************************************/
void Init_Port()
{
P1SEL &= ~0x1b;
P1DIR |= 0x1b;
P1 &= ~0x1b;
}
/**************************************************************
函数名称:Init_T1
功 能:定时器初始化,不启动定时器
入口参数:无
出口参数:无
返 回 值:无
**************************************************************/
void Init_T1()
{
EA = 1;
T1IE = 1;
T1CCTL0 |= 0x04;
T1CC0L = 0xd4;
T1CC0H = 0x30;
}
/**************************************************************
函数名称:Init_P1INT()
功 能:端口1中断初始化
入口参数:无
出口参数:无
返 回 值:无
**************************************************************/
void Init_P1INT()
{
IEN2 |= 0x10;
P1IEN |= 0x04;
PICTL |= 0x02;
}
/**************************************************************
函数名称:main
功 能:程序主函数
入口参数:无
出口参数:无
返 回 值:无
**************************************************************/
void main()
{
Init_Port();
Init_T1();
Init_P1INT();
while(1)
{
}
}
uint8_t P1_Flag = 0; //按键当前状态
uint32_t count = 0; //定时器计数
/**************************************************************
函数名称:P1INT_Serivce
功 能:中断服务函数,切换LED状态
入口参数:无
出口参数:无
返 回 值:无
**************************************************************/
#pragma vector = P1INT_VECTOR
__interrupt void P1INT_Serivce(void)
{
if((P1IFG & 0x04) == 0x04)
{
P1IFG = 0;
P1IF = 0;
IP0 |= 0x02; //提高定时器优先级
T1CTL |= 0x0e; //开启定时器
PICTL &= ~0x02; //切换端口1为上升沿触发
P1_Flag = 1;
while((P1IFG & 0x04) != 0x04); //等待按键松开
P1IFG = 0;
P1IF = 0;
P1_Flag = 0;
PICTL |= 0x02; //切换端口1为下降沿触发
T1CTL = 0; //关闭定时器
if(count <= 5)
D4 = ~D4;
else
D6 = ~D6;
count = 0;
}
}
/**************************************************************
函数名称:T1_Serivce
功 能:0.1s计时
入口参数:无
出口参数:无
返 回 值:无
**************************************************************/
#pragma vector = T1_VECTOR
__interrupt void T1_Serivce(void)
{
if((P1_Flag == 1) && (count != 65535))
count++;
}
to sum up
The difficulty is that after entering the port 1 interrupt, the priority needs to be increased when the button is pressed before entering the timer 1 interrupt