| I. Carrying on from the previous to the next In the last lecture, we familiarized ourselves with the basic process of developing CC2430 program by IAR through a small experiment of the simplest LED blinking. The knife has at least been sharpened (although I'm not very good at this sharpening stone), and now it's time to start butchering bugs :). Next, let's learn a few basic CC2430 experiments. Each small experiments, divided into "experimental introduction", "program flow chart", "experimental source code and analysis" three parts of the description. This article explains the external interrupt. Second, the external interrupt(1) Introduction to the experiment Interrupt is a real-time microcontroller to deal with internal or external events, an internal mechanism. When some kind of internal or external events, the microcontroller interrupt system will force the CPU to pause the program being executed, but to go to the interrupt event processing, interrupt processing is complete, and then return to the program was interrupted, continue to execute. Interrupts are divided into external interrupts and internal interrupts, CC2430 contains a total of 18 interrupt sources (specific interrupt description and interrupt vector definition, you can refer to the " CC2430 Chinese Manual "). Now let's take a look at the circuit diagram of this development board:
The development board has been connected to the S1 button and P0.1, the effect that this experiment wants to achieve is to trigger the interrupt of P0.1 by pressing the key S1, and then control the LED1 bright/extinguish in the interrupt service subroutine. (2) Experimental principle and flow chart The flowchart of the experiment is as follows:
(3) Experimental source code// header file #include
// delay subfunction #define led1 P1_0 #define led2 P1_1 #define led3 P1_2 #define led4 P1_3
void Delay( unsigned n) { & nbsp; unsigned tt; for (tt = 0;tt<n;tt++); for (tt = 0;tt<n;tt++); for (tt = 0;tt<n;tt++); & nbsp; for (tt = 0;tt<n;tt++); for (tt = 0;tt<n;tt++); }
//32M crystal initialization void xtal_init( void ) { SLEEP &= ~0x04; & nbsp; //all power up while (! (SLEEP & 0x40 )); //crystal oscillator on and stable CLKCON &= ~0x47; & nbsp; //Select 32MHz crystal oscillator SLEEP |= 0x04; }
//LED initialization void led_init( void ) { P1SEL = 0x00;   ; //P1 is a normal I/O port P1DIR |= 0x0F; //P1.0 P1.1 P1.2 P1.3 Output led1 = 0; led2 = 0; led3 = 0; led4 = 0; }
//io and external interrupt initialization void io_init( void ) { P0INP &= ~0X02; //P0.1 has pull-up and pull-down
EA = 1; //Total interrupt enable P0IE = 1; & nbsp; //P0 interrupt enable PICTL |= 0X09; //P0.1 port interrupt enable, falling edge trigger P0IFG &= ~0x02; //P0.1 interrupt flag clear 0 };
//main function void main( void ) { xtal_init(); led_init(); io_init();
while ( 1 ); //wait for interrupt }
//interrupt service subroutine #pragma vector = P0INT_VECTOR __interrupt void P0_ISR( void ) { EA = 0; // turn off interrupt
Delay ( 10000 ); Delay( 10000 ); Delay( 10000 ); Delay( 10000 ); Delay( 10000 );
& nbsp; if ((P0IFG & 0x02 ) >0 ) //key interrupt { P0IFG &= ~0x02; & nbsp; //P0.1 interrupt flag clear 0 led1 = !led1; } P0IF = 0; & nbsp; //P0 interrupt flag clear 0
EA = 1; & nbsp; // turn on interrupt } First initialize the Unity Clock: choose 32MHz crystal oscillator. Then initialize the LEDs: set P1 as the general-purpose I/O port, set P1.0 ~ P1.3 direction as the output, and then turn off the 4 LEDs. Then configure the relevant SFR registers for external interrupts and turn on the interrupt enable at all levels, involving 3 SFRs: EA, IEN1, PICTL (for detailed description of each SFR, please refer to the CC2430 Chinese Manual ): EA -- total interrupt enable; IEN1.5 -- P0 interrupt enable; PICTL.3 -- P0.1 port interrupt enable; PICTL.0 -- set P0.1 port input falling edge to cause interrupt trigger. Then use while(1) in the main function to wait for the interrupt. CC2430 Tips(1) Bit Assignment Syntax Summary Very often, we need to assign a value (0 or 1) to a bit in a single-byte SFR to precisely control a hardware device. Some SFRs support bit addressing, such as TCON, P0, etc., at this time, the assignment of the bit is very simple, just query the ioCC2430.h header file in the SFR Bit Access part of the bit definition can be: P0_0 = 0; // P0 the first bit of the assignment of the value of 0 P0_0 = 1; / / / P0 the first bit of the assignment of the value of 1
However, there are SFRs do not support bit addressing, as in the case of the first bit of P0 . However, some SFRs do not support bit addressing, such as the PICTL in this experiment, when you want to assign a value to one of the bits, the syntax is as follows: PICTL &= ~0x01; //assign a value of 0 to the first bit PICTL |= 0x01; //assign a value of 1 to the first bit
You can remember that & amp;= ~, |= ~, |= ~, |= P0_0 = 1; //assign a value of 1 to the first bit of P0 . amp;= ~, |= these two common bit assignment syntax. (2) Interrupt Enablement Summary When an interrupt is involved in a program, the interrupt must be enabled before it is triggered. C51 interrupt enable system, its hierarchical structure is very obvious: interrupt boss: EA is the boss, responsible for the total interrupt enable: EA = 1;
interrupt detachment captain: the next step is for each functional component (such as P0, timer 1, etc.) of the enablement control, this type of SFR is generally bit-addressable, naming the general contains IE (Interrupt Enable): P0IE = 1; the interrupt team members: detachment, but due to the interruption of the program, it is necessary to enable the interrupt before triggering the interrupt.
each interrupt team members: team but because each functional component also contains multiple interrupts, so the last level is for each of these interrupt enable control, such SFRs are generally not bit-addressable, naming generally contains IE (Interrupt Enable) or IM (Interrupt Mask): PICTL | = 0x01;
do not need to memorize interrupt SFRs It is not necessary to memorize the interrupt SFR, as long as you understand the hierarchy, and then use the manual or header file can be queried. (3) Interrupt Program Writing Using interrupts in a program generally consists of two parts: the writing of interrupt service subroutines and the opening of interrupt enable. Interrupt enable has been introduced above, the following is a brief introduction to the preparation of interrupt service subroutine: First of all, specify the interrupt vector, can be in the ioCC2430.h header file in the Interrupt Vectors part of the query, the syntax is as follows: # pragma vector = Interrupt Vectors
and then followed by the preparation of interrupt handler, the structure is as follows: ___ interrupt void Function Name (___) interrupt void function name(void) { //on interrupt //interrupt handling //interrupt flag clear 0 //off interrupt }
III. Conclusion This article introduces a simple external interrupt implementation method based on CC2430, with the basis of the interrupt, then we introduce another very important module - timer. CC2430 has a total of four timers, which can be divided into three categories: timer 1, timer 2, timer 3/4 (3 and 4 of the use of the basic). the same). </n;tt++). </n;tt++). </n;tt++). </n;tt++); </n;tt++); </n;tt++); </n;tt++). </n;tt++). |