CC2530 button long press and short press to control LED

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

PxSEL-Port Function Register

P1DIR (Port 1 direction register) -Port 1 direction register

PxDIR-port 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

PICTL-port input signal

P1IFG (Port 1 interrupt flag group) -P1 port status flag register

P1IFG-P1 Port Status Flag Register

P1IEN (Port 1 interrupt enable)——P1 port interrupt enable

P1IEN-P1 port interrupt enable

IEN0 (Interrupt enable 0)-Interrupt enable register 0

IEN0-Interrupt Enable Register 0

IEN2 (Interrupt enable 2)-Interrupt enable register 2

IEN2-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
T1CCTLx timer 1 channel capture control register

IEN1 (Interrupt enable 1)-Interrupt enable register 1

IEN1-interrupt enable register 1

T1STAT (Time1 State Thoroughfare)-P1 port status flag register

Use channel 0 as the timer channel
T1STAT-Timer Status Register

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

Guess you like

Origin blog.csdn.net/weixin_44222591/article/details/114999263