Briefly understand the interrupt of MSP430 (taking IO and timer as an example)

I feel that there should be many people who have just learned single-chip microcomputers, like me, who had great doubts about interrupts at first. Today, I will briefly write about my current understanding of interrupts.
1. Basic
So what is an interruption? We can think of it as letting go of the thing A we are currently doing, and doing another thing B, and then come back and continue doing A after finishing B. For example, if we want to write a program, we need to drink water when we are thirsty in the middle, and we will continue to write the program after drinking the water. Stopping writing programs is equivalent to interrupting, and drinking water is equivalent to interrupting what is done in it. What is done in the interrupt is the interrupt function. ,
by analogy to a function, writing a program is equivalent to the main function, then going to drink water is equivalent to an interrupt function.
Some of the IOs in the 430, timers, USCI, etc. all have interrupt functions.
2. Various interrupts (in fact, only IO and timers)
1. Interrupts in IO.
There are multiple IO ports in F5529, but only P1 and P2 have interrupt function, and only P1P2 has interrupt function in g2553, which can be found in the IO part of user's guide.
The judgment condition of the IO interrupt is the upper and lower edges of the input/output level change, and the upper or lower edge can be configured.
The principle is the input/output level, that is, changing the input level can trigger an interrupt, and setting the port as an output and then changing the output level can also trigger an interrupt!
Not much to say, a test program I wrote when I was studying last time
//

#include <msp430.h> 
///用来测试2.0的中断功能
/*
 * main.c
 */
#define CPU_F          ((double)8000000)
#define delay_us(x)     __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x)     __delay_cycles((long)(CPU_F*(double)x/1000.0))
int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
	P4DIR|=BIT0+BIT3;             //4.3	4.0为输出检测口
	P4OUT|=BIT0;				//初始状态P4.0为高电平
	P4OUT&=~BIT3;				//初始状态P4.3为低电平
	P2DIR&=~BIT0;				//2.0为中断测试口
	P2IES|=BIT0;//设置为下降沿触发,即检测到4.0的高电平变成了低电平从而出发中断
	P2IFG=0;	//清除中断IFG标志
P2IE|=BIT0;//中断使能添加
	delay_ms(1000);
	P4OUT&=~BIT0;				//P4.0变为低电平
	_EINT();					//启用总中断
	
}
#pragma vector = PORT2_VECTOR
__interrupt void PORT2_ISR(void)
{
	//-----启用Port2事件检测函数-----
	 	 	 	 	 	 	 	 	 	 	 	 	 //检测通过,则会调用事件处理函数
	if(P2IFG&BIT0)
		P4OUT|=BIT3;
  	P2IFG=0;                            			//退出中断前必须手动清除IO口中断标志
}

//
This program can roughly understand the interruption of P2.0.
Set P2.0 as input and p4.0 as output. Connect P4.0 and P2.0 with a DuPont line. The initial state of P4.0 is high level, and after one second, P4.0 outputs low level. A change in the output of P4.3 can be observed. In order to make the phenomenon more intuitive, you can replace 4.3 with an LED, so that you can observe the on and off of the LED.
The configuration process is roughly as follows:
(1) Configure the upper and lower edge PxIES triggered by the interrupt
(2) Clear IFG (in fact, IFG will be cleared by the program after PUC, but you can still write it)
(3) Add interrupt enable PxIE
general This is placed at the end of the port configuration
(4) _EINT() to enable the general interrupt. This is to enable the general switch. If you don’t write it, any interrupt will be useless. The
basic writing method of the interrupt function
(1) #pragma vector = PORT2_VECTOR
in different Different vectors are used for interrupts. What needs to be changed is only the part after the equal sign.
This can be found in the header file of ccs. Hold down ctrl and click on something like BIT0 to enter the header file, and then in this part.
insert image description here
A vector representation of all interrupts can be found.
(2) __interrupt void PORT2_ISR(void)
{ } The interrupt function, just like any function in C, writes the things to be done in the interrupt. 2. Interruption of the timer In the previous article, it was written that the timer is actually an interruption. Now let's briefly talk about interrupts using comparators.




The condition for the interrupt in the comparator is that the value in the counter is compared with the CCR. In UP mode, when the value of the counter is greater than CCR, an interrupt will be triggered. And in UP mode, CCR0 is the end point of counting. When counting to CCR0, the counter will become 0 and start counting again. And CCR1 and so on will not affect the count.
And the counter is not counted by the CPU, that is to say, when the CPU executes the program, the counter will count independently, which is why the counter is important!
Get on the program now! (It's just a test program I wrote when I was practicing and wondering if I could use CCR2 to change the value of CCR1)
//

#include <msp430.h> 
//用TA0里面的CCR2来控制CCR1;
/*
 * main.c
 */
unsigned int t;
int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    UCSCTL5=DIVS__2 ;			//现在SMCLK为500 000HZ
    t=600;
    P4DIR|=BIT2;
    P4OUT|=BIT2;
    P4DIR|=BIT3;
P4OUT|=BIT3;				//配置IO

	TA0CTL=TASSEL__SMCLK+MC__UP+ID__8+TACLR;
//配置定时器,时钟选择SMCLK,UP模式,八分频
	TA0CCR0=10000;		//CCR0设置为10000,也就是说,当以500000/8的周期计数记//到10000的时候,重新计数
	TA0CCR1=t;			//CCR1为t
	TA0CCR2=5000;		//CCR2为5000
	TA0CCTL0 = CCIE;
	TA0CCTL1 = CCIE;
	TA0CCTL2 = CCIE;
//开启每一个捕获器的中断使能
	_EINT();			//开启总中断
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIME0_A0_ISR(void)
{
	P4OUT|=BIT2;
	P4OUT|=BIT3;

}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIME0_A1_ISR(void)
{
	{
	    switch(TA0IV)
	    {
	        case 2:
	        	{
	        		P4OUT &= ~BIT2;
	        		break;
	        	}
	        case 4:
	        	{
	        		P4OUT &= ~BIT3;
	        		if(t<8000)
	        			t=t+100;
	        		else
	        			t=600;
	        		TA0CCR1=t;		//当CCR2产生中断的时候改变CCR1的值
	     	break;
	        	}
	        case 10:break;
	    }
	}
}

/
The program is not very good, but you can still briefly talk about the basic configuration process
(1) TAxCTL configuration
(2) TAxCCR configuration
CCR0 is the most important of all CCRs
(3) TA0CCTL0 = CCIE;
interrupt the comparator that needs to be interrupted Enable open
(4) _EINT(); enable total interrupt
(5) interrupt function
#pragma vector=TIMER0_A0_VECTOR
#pragma vector=TIMER0_A1_VECTOR
The timer interrupt vectors of CCR0 and CCR1 in the timer are different, CCR0 is one, and CCR1 To the other is another. This can also highlight the importance of CCR0.
As mentioned in the previous article, CCR1 needs to judge TAxIV in the future CCR write interrupt function. It is also reflected in the given program.

//
Probably like this. As for other interrupts, it's much the same. Still optimistic about the user's guide is the most important. Beginner 430, please correct me if there are mistakes.

Guess you like

Origin blog.csdn.net/PolypolyA/article/details/100835685