MSP430 working notes 1 (transferred)

Publisher:SparklingRiverLatest update time:2016-08-23 Source: eefocusKeywords:msp430 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
1. Functional modules of MSP430G2553 microcontroller

  (a), IO port module,

  1. The MSP430G2553 we use has two groups of IO ports, P1 and P2.

  2. The registers of the IO port are: direction selection register PxDIR, output register PxOUT, input register PxIN, IO port internal pull-up or pull-down resistor enable register PxREN, IO port function selection registers PxSEL and PxSEL2, IO port interrupt enable register PxIE, interrupt edge selection register PxIES, IO port interrupt flag register PxIFG.

  3. All IOs have interrupts, among which all P1 ports share one interrupt vector, and all P2 ports share one interrupt vector. Therefore, when using interrupts, after entering the interrupt, it is also necessary to determine which IO port generated the interrupt. The determination method can be to determine the level of each IO port.

   4. The interrupt flag PxIFG needs to be cleared by software, but can also be set by software to trigger an interrupt.

Note: When setting PxIESx, the corresponding PxIFGx may be set according to PxINx (see the user guide for details), so after initializing the IO port interrupt, the corresponding PxIFGx must be cleared before officially using the IO interrupt. The procedure is as follows:

void IO_interrupt_init() //IO interrupt initialization function

{

  P1REN |= BIT4+BIT5+BIT6+BIT7; // pullup internal pull-up resistor enabled

  //When using interrupts, enable the internal pull-up resistor so that when the pin is left floating, the level will not jump, to prevent the level from jumping and constantly triggering interrupts when it is left floating

  P1OUT = BIT4+BIT5+BIT6+BIT7; // When the pull-up or pull-down resistor on the pin is enabled, PxOUT selects whether to pull up or down

          //0: pull down, 1: pull up

 

  P1IE |= BIT4+BIT5+BIT6+BIT7; // interrupt enabled P13 interrupt enabled

  P1IES |= BIT4+BIT5+BIT6+BIT7; // Hi/lo edge falling edge interrupt

  //P1IES &= ~BIT3; //Rising edge triggers interrupt

  P1IFG &= ~(BIT4+BIT5+BIT6+BIT7); // Clear interrupt flag

 

}

 

5. PxOUT: If the pin selects the internal pull-up or pull-down resistor to be enabled, PxOUT sets the resistor to be pull-up or pull-down, 0: pull-down, 1: pull-up

6. When the IO port is not used, it is best not to set it as input and to float (this is the default state of the IO port), because when the input is floating, the input voltage may be between VIL and VIH, which will produce breakdown current. Therefore, the unused IO port can be set as output, or set as input but connected to VCC or GND through peripheral circuits, or connected to a pull-up/pull-down resistor.

7. When using the IO port of msp430g2553, please pay attention to the operation of the IO port register of g2553, unlike 51, it cannot operate on a single bit, but must operate on the entire register. So unlike 51, g2553 cannot define bit-type data. So when using the IO port of msp, please pay attention to the operation of the required bit, and do not affect other irrelevant bits. You can use symbols such as | & ^ for bitwise operations. When using IO to control other peripheral modules, you must also pay attention to the definition of the IO port to be used. You can use the following definition method:

#define CLR_RS P2OUT&=~BIT0; //RS = P2.0

#define SET_RS P2OUT|=BIT0;

#define CLR_RW P2OUT&=~BIT1; //RW = P2.1

#define SET_RW P2OUT|=BIT1;

#define CLR_EN P2OUT&=~BIT2; //EN = P2.2

#define SET_EN P2OUT|=BIT2;

 

#define DataPort P1OUT

 

8. The P27 and P26 pins of g2553 are connected to the output and input pins XOUT and XIN of the external crystal respectively. By default, they are automatically set to the crystal oscillator pin function. However, if you want to use them as ordinary IO, you can also set the corresponding SEL to ordinary IO, as follows:

P2DIR |= BIT6+BIT7; //Configure P26 and P27 as common IO and output pins. The default is the input and output pins of the crystal oscillator.

    P2SEL &= ~(BIT6+BIT7); //cs and wr control terminals

    P2SEL2 &= ~(BIT6+BIT7);

 

 

 

(ii) Clock system

     1. The ultra-low power consumption of msp430 is largely due to the reasonable clock module. However, the powerful clock module is relatively complicated to set up.

     2. The clock sources of msp430 are:

(1) External low-frequency crystal oscillator LFXT1CLK: low-frequency mode connects to watch crystal 32768Hz, high-frequency mode 450KHz~8MHz;

(2) External high-speed crystal oscillator XT2CLK: 8MHz;

(3) Internal digital controlled oscillator DCO: It is a controllable RC oscillator with a frequency of 0~16MHz;

(4) Ultra-low power low frequency oscillator VLO: uncontrollable, 4~20KHz, typical value is 12KHz;

     3. Clock module: The clock modules of 430 include MCLK SMCLK ACLK:

(1) Main system clock MCLK: The CPU clock provided to MSP430. It can come from LFXT1CLK XT2CLK DCO VLO is optional, and the default is DCO.

(2) Subsystem clock SMCLK: Provided to high-speed peripherals. Can come from LFXT1CLK XT2CLK DCO VLO optional, default is DCO.

(3) Auxiliary system clock ACLK: Provided to low-speed peripherals. Can come from LFXT1CLK VLO. 

     4. The clock frequency provided by the internal oscillators DCO and VLO is not very accurate and varies greatly with the external environment.

The default frequency of DCO is about 800KHz, but I observed it with an oscilloscope and it was about 1.086MHz. When the DCO is set too high, the waveform is no longer a square wave, but a sine wave. DCO can be set relatively accurately using the macro definition provided by CCS, as follows:

DCOCTL = CALDCO_12MHZ; //DCO is set to 12MHz. This method is more accurate in setting the DCO frequency. The actual measured value is about 12.08MHz. Sine wave

BCSCTL1 = CALBC1_12MHZ;

This method can be used to set 1, 8, 12, 16MHz

The macro definition is as follows:

#ifndef __DisableCalData

 

SFR_8BIT(CALDCO_16MHZ);                       

SFR_8BIT(CALBC1_16MHZ);                       

SFR_8BIT(CALDCO_12MHZ);                       

SFR_8BIT(CALBC1_12MHZ);                       

SFR_8BIT(CALDCO_8MHZ);                        

SFR_8BIT(CALBC1_8MHZ);                        

SFR_8BIT(CALDCO_1MHZ);                        

SFR_8BIT(CALBC1_1MHZ);                        

 

#endif 

 

5. Using ultra-low power low frequency oscillator VLO can greatly reduce system power consumption. The following example sets ACLK to VLO and MCLK to 8 divided by VLO:

#include

 

//1 delay

//#define CPU_F ((double)16000000)//cpu frequency16000000

#define CPU_F ((double)1630) //cpu frequency1630 //The actual MCLK of the CPU is about 13.05/8=1.63KHz

#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))

 

 

void main(void)

{

  volatile unsigned int i; // Volatile to prevent removal

  WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

 

  BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO Low frequency clock is selected as VLO ACLK is selected as VLO

 

  IFG1 &= ~OFIFG; // Clear OSCFault flag Clear oscillator error interrupt flag

 

  __bis_SR_register(SCG1 + SCG0); // Stop DCO SCG1 disables SMCLK SCG0 disables DCO

 

  BCSCTL2 |= SELM_3 + DIVM_3; // MCLK = LFXT1/8

  //Since LFXT1 = VLO has been selected before, MCLK is selected as VLO 8-division, so the CPU's MCLK is about 1.5KHz

 

  P1DIR = 0xFF; // All P1.x outputs

  P1OUT = 0; // All P1.x reset

  P2DIR = 0xFF; // All P2.x outputs

  P2OUT = 0; // All P2.x reset

 

  P1SEL |= BIT0+BIT4; // P10 P14options function selection is peripheral module

  //p10 outputs ACLK, which comes from VLO, and p14 outputs SMCLK. Because SMCLK is disabled, there is no waveform output on the P14 pin

  //The typical value of VLO is 12KHz. The actual value measured by oscilloscope is: 13.05KHz.

  //So the actual MCLK of the CPU is about 13.05/8=1.63KHz

 

 

  for (;;)

  {

    P1OUT ^= BIT6; // P1.6 flashes

    delay_ms(1000);

  }

}

 

  6. As shown in the above program, the delay function uses that method, using the system delay cycle function __delay_cycles(int n); to achieve a more accurate delay, as follows:

 

//more_

//1 delay

//#define CPU_F ((double)16000000)//cpu frequency16000000

#define CPU_F ((double)12000000)//cpu frequency12000000

#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))

//2 empty function

#define nop() _NOP();

 

   7. After the system is powered on, the DCO clock is used by default. The default frequency of DCO is about 800KHz, but I observed it with an oscilloscope and it was about 1.086MHz. When the DCO is set too high, you can see with an oscilloscope that the waveform is no longer a square wave, but a sine wave.

 

 

 

 (III) Timer_A

   1. MSP430g2553 has two 16-bit timers: Timer0_A and Timer1_A. Each has three capture/compare registers, with input capture and output compare functions. It can generate timing interrupts and PWM.

   2. Generate PWM, the example is as follows:

 

#include

 

 void Timer_A0_1_init() //TA0.1 outputs PWM

{

TACTL|= TASSEL_1+MC_1; //ACLK, count up

CCTL1=OUTMOD_7; //Output mode is reset/set

CCR0=328; //Clock frequency is 32768HZ, 100HZ

//CCR1=164; //Clock frequency is 32768HZ, duty cycle CCR1/CCR0=50%

CCR1=109; //Duty cycle CCR1/CCR0=1/3 TA0.1 is output by P1.2 P1.6

}

 

 void Timer_A1_2_init() //TA1.2 outputs PWM

{

TA1CTL|= TASSEL_1+MC_1; //ACLK, count up

TA1CCTL2=OUTMOD_7; //Output mode is reset/set, note that CCTL2 should be written as TA1CCTL2

 

TA1CCR0=164; //Clock frequency is 32768HZ, waveform 32768/CCR0=199HZ

TA1CCR2=41; //Duty cycle CCR2/CCR0=1/4, note that CCR2 should be written as TA1CCR2 TA1.2 is output by P2.4 P2.5

 

}

 

 void Timer_A1_1_init() //TA1.1 outputs PWM

 {

 TA1CCTL1=OUTMOD_7;

 TA1CCR1=123; //Duty cycle CCR1/CCR0=3/4, note that CCR1 should be written as TA1CCR1 TA1.1 is output by P2.1 P2.2

 }

 

 void IO_init()

 {

 P1SEL|=BIT2+BIT6;

 P1DIR|=BIT2+BIT6; //P1.2 P1.6 output TA0.1 OUT1

 

 P2SEL|=BIT4+BIT5;

 P2DIR|=BIT4+BIT5; //P2.4 P2.5 output TA1.2 OUT2

 

 P2SEL|=BIT1+BIT2;

 P2DIR|=BIT1+BIT2; //P2.1 P2.2 output TA1.1 OUT1

 }

 

void main(void) {

WDTCTL=WDTPW+WDTHOLD;

 

    IO_init();

 

Timer_A0_1_init();

Timer_A1_2_init();

Timer_A1_1_init();

 

 

_BIS_SR(CPUOFF); // Enter LPM0 Enter low power mode 0 SMCLK ON, ACLK ON

}

 

  3. Timer_A capture/compare register

The TAR register is the 16-bit count register of Timer_A. TACCRx is the capture/compare register of Timer_A. When in capture mode: when capture occurs, the value of TAR is loaded into TACCRx. When in compare mode: TACCRx is loaded with the value to be compared with the TAR register.

   4. Capture Mode

Capture the rising edge or falling edge or both the rising and falling edges of the external input signal. When the capture occurs, the value of TAR is loaded into TACCRx. At the same time, the interrupt can be entered to perform the corresponding operation. In this way, by capturing the rising edge or falling edge, the period of the external input signal can be calculated to obtain the frequency. By capturing the rising edge and falling edge, the duration of the high or low level of the input signal can be obtained. The duty cycle can also be calculated. The following is an example of the program for capturing and initializing Timer_A:

void timer_init() //When using Timer1_A, pay special attention to the writing of each register, because the registers of Timer0_A are abbreviated, so when writing

//When reading the registers of Timer1_A, pay special attention to the differences from Timer0_A

{

P1SEL |= BIT2; //Select P12 as the capture input terminal Timer0_A

 //TACCTL1 |=CM_3+SCS+CAP+CCIE; //Both rising and falling edges trigger capture, used to measure pulse width, synchronous mode, and time interrupt CCI1A

TACCTL1 |=CM_1+SCS+CAP+CCIE; //Rising edge trigger capture, synchronous mode, time interrupt CCI1A

    TACTL |= TASSEL1+MC_2; //Select SMCLK clock as the counting clock source, without frequency division. The increment counting mode is not possible, and the continuous counting mode is required.

 

  P2SEL |= BIT1; //Select P21 as the capture input terminal Timer1_A

  //TA1CCTL1 |=CM_3+SCS+CAP+CCIE; //Both rising and falling edges trigger capture, used to measure pulse width, synchronous mode, and time interrupt CCI1A

  TA1CCTL1 |=CM_1+SCS+CAP+CCIE; // rising edge trigger capture, synchronous mode, time interrupt CCI1A

  TA1CTL |= TASSEL1+MC_2; //Select SMCLK clock as the counting clock source, without frequency division. The increment counting mode is not possible, and the continuous counting mode must be used.

 

}

 

 

The corresponding interrupt functions are as follows:

 

#pragma vector=TIMER0_A1_VECTOR //Timer0_A CC1 interrupt vector

__interrupt void Timer_A(void)

{

 

// The capture compare register used by CCI0A is TA0CCR0, which is allocated to a

    //Interrupt vector TIMER1_A0_VECTOR, so after entering the interrupt, it is directly the interrupt generated by Timer0_A CC0, without going through similar

   //The following method determines the interrupt source.

//Timer0_A CC1-4, TA0 share an interrupt vector TIMER0_A1_VECTOR, so after entering the interrupt, you need to use the following

    //Method to determine which interrupt source caused the interrupt

  switch(TAIV) //If it is an interrupt generated by Timer0_A CC1

  {

  case 2:

   {

   flag=1;

   LPM1_EXIT; //Exit low power mode

  // _BIC_SR_IRQ(LPM1_bits);

   //_bic_SR_register_on_exit(LPM1_bits);

   break;

   }

  case 4: break;

  case 10:break;

  }

}

 

 

#pragma vector=TIMER1_A1_VECTOR //Timer1_A CC1 interrupt vector

__interrupt void Timer_A1(void)

{

 

// P1OUT|=BIT0; //For LED debugging

// LPM1_EXIT; // Exit low power mode Because CCI0A is used, the capture compare register used is TA1CCR0, which is allocated to a separate

                //Interrupt vector TIMER1_A0_VECTOR, so after entering the interrupt, it is directly the interrupt generated by Timer1_A CC0, without going through similar

               //The method commented out below is used for judgment.

               //Timer1_A CC1-4, TA1 share an interrupt vector TIMER1_A1_VECTOR, so after entering the interrupt, you need to use the following

       //Method to determine which interrupt source caused the interrupt

  switch(TA1IV) //If it is an interrupt generated by Timer1_A CC1

  {

  case 2:

   {

   flag=2;

   LPM1_EXIT; //Exit low power mode

 

  // _BIC_SR_IRQ(LPM1_bits);

   //_bic_SR_register_on_exit(LPM1_bits);

   break;

   }

  case 4:break;

  case 10:break;

  }

}

 

//If you want to measure a lower frequency signal, you can determine the number of overflow interrupts in the interrupt, so that you can get the number of overflows and measure a higher frequency signal.

//Low frequency signal

 

  5. Counting mode of Timer_A

The counting modes include: up counting mode, continuous counting mode and up/down counting mode. For detailed explanation of each mode, please refer to the user guide.

   6. Timer interrupt

When using the timer's timing interrupt, pay attention to the selection of the timer counting mode. When using the interrupt, pay attention to the use of the interrupt vector and the judgment of the interrupt source. Here is an example with detailed comments:

#include

 

unsigned int t=0;

 

void main(void)

{

  WDTCTL = WDTPW + WDTHOLD; // Stop WDT

  P1DIR |= 0x01; // P1.0 output

 

  CCTL0 = CCIE; // CCTLx is the capture/compare control register interrupt enabled CCIE=0x0010 enables timer A interrupt

 

  CCR0 = 50000; //Capture/compare register Set the initial value of counter CCR0 16-bit register, the maximum value is 65535

                //The default SMCLK uses DCO, the default DCO is about 800KHz, and CCR0=50000, so the frequency of interrupt generation is about 16Hz

  TACTL = TASSEL_2 + MC_2; // SMCLK, contmode continuous counting mode from 0 to 0FFFFh

  //TACTL = TASSEL_2 + MC_1; // SMCLK, upmode count up mode from 0 to CCR0

 

  _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt Enter low power mode 0, enable interrupts

}

 

// Timer A0 interrupt service routine

#pragma vector=TIMER0_A0_VECTOR

__interrupt void Timer_A (void) //After the CCIFG interrupt is responded, this flag is automatically cleared

 

{

  //P1OUT ^= 0x01; // Toggle P1.0

t++;

if(t==5)

{

P1OUT ^= BIT0; // Toggle P1.0

t=0;

}

 

  CCR0 += 50000; // Add Offset to CCR0

 

   

  //The timer always counts up from 0 until it is full and then starts again from 0. In continuous counting mode, when the timer value is equal to CCR0, an interrupt is generated.

  //Increase CCR0 by 50000 in the interrupt, so that the interval from the current value to the next moment when the timer is equal to CCR0 again is 50000, constant

  //This way the time intervals between interrupts are equal

 //So in the continuous counting mode, if you want to make the interrupt time interval constant, you need to have CCR0 += n;

                                              //CCR0 does not need to be reassigned during interruption, which is different from 51

}

 

Note on the use of interrupts: Let's take an example:

#include

 

void main(void)

{

  WDTCTL = WDTPW + WDTHOLD; // Stop WDT

  P1DIR |= 0x01; // P1.0 output

  TACTL = TASSEL_2 + MC_2 + TAIE; // SMCLK, contmode, interrupt TAIE enables timer overflow interrupt

 

  _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt GIE enables interrupt

}

 

// Timer_A3 Interrupt Vector (TA0IV) handler

#pragma vector=TIMER0_A1_VECTOR

__interrupt void Timer_A(void)

{

 switch(TA0IV) //TAIV interrupt vector register used for

 {

   case 2: break; // CCR1 not used Capture/Comparator 1

   case 4: break; // CCR2 not used Capture/Comparator 2

   case 10: P1OUT ^= 0x01; // overflow timer overflow

            break;

 }

}

 

 

 

  7. Note: The clock of timer Timer0_A can be selected as external clock input TACLK (P10), so when an external signal is connected, timer Timer0_A is equivalent to a counter. In this way, you can use Timer0_A to connect to external signals, and Timer1_A to connect to standard clocks such as 32768Hz crystal oscillators, and you can achieve equal precision frequency measurement. In fact, the clock of Timer1_A can also be external, but there is no external pin (P37) in g2553, so you can only choose the normal clock.

The setting of the external clock input TACLK (P10) of Timer0_A is as follows: The following is the initialization procedure of the two timers when I implement equal-precision frequency measurement:

void timer0_init()

{

TACTL |= TASSEL_0+MC_2+TACLR; //Select TACLK clock as the counting clock source, no frequency division, must be continuous counting mode

 

P1SEL |= BIT0; //P10 is the clock TACLK input of Timer0_A, which is connected to the external signal to be tested, so that Timer0_A can be used as a counter

}

//Timer1_A uses ACLK as the clock source for counting, so ACLK is equivalent to a standard signal, so both timers are equivalent to working in counter mode.

//ACLK 32768Hz is used as the standard signal, so that the frequency measurement with equal accuracy can be achieved

void timer1_init()

{

 

TA1CCTL0 = CCIE;

TA1CCR0 = 32768; //1s timing

 

TA1CTL |= TASSEL_1+MC_2+TACLR; //Select ACLK clock as the counting clock source, no frequency division, must be continuous counting mode

 

}

8. DAC can be realized using timers and comparators

   Serial communication can also be achieved using a timer

Keywords:msp430 Reference address:MSP430 working notes 1 (transferred)

Previous article:msp430 working notes 2
Next article:Wind-solar inverter grid-connected system based on MCU-FPGA architecture

Recommended ReadingLatest update time:2024-11-15 15:22

MSP430 (F149) study notes - infrared reception
It is easier to use MSP430 (F149) to receive infrared than to send it. The infrared sensor I use is HS0038B. This component outputs a low level when receiving 38K infrared, otherwise it outputs a high level. Therefore, we can start writing the program from this point. Since there are many circuit diagrams of HS0038B, I
[Microcontroller]
MSP430 internal clock (DCO) frequency measurement
Clock Circuit - Digital Oscillator (DCO)   Circuits can be divided into digital and analog according to signal form. Digital circuits process digital signals. Digital circuits can be divided into combinational logic circuits and sequential logic circuits. Sequential circuits can complete the functions of combinati
[Microcontroller]
Design of serial port communication between MSP430 microcontroller and PC based on VB6.0
  1 Introduction   With the continuous development of computer technology, computer applications have gradually formed two major branches in its development process. One is general-purpose computers, represented by PCs, which focus on high-speed numerical calculations and data processing, but have weak real-time mea
[Microcontroller]
Design of serial port communication between MSP430 microcontroller and PC based on VB6.0
MSP430 vs. MSP432, who is the strongest?
MSP430 is a legend in the MCU world. It is the benchmark of the lowest power consumption of 16-bit MCU in the world. It has never been surpassed in the past 20 years and is the well-deserved king of low power consumption in the eyes of engineers. In the early years, TI launched the 32-bit low-power MCU product based o
[Microcontroller]
MSP430 vs. MSP432, who is the strongest?
MSP430 Learning Bits—IAR5.30
1: Add header file in IAR settings When programming in IAR, you often use your own header files. At this time, you need to set the path to add the included header files. The common method is to right-click on the project and select options, and load your header file path in the preprocessor in the c/c++ compiler s
[Microcontroller]
MSP430 Learning Bits—IAR5.30
MSP430 ADC12 sampling analysis
         The AD part mainly configures the clock, reference source, sampling channel, sampling mode, storage and sample-and-hold of the ADC12 module.      I'll take it one part at a time.      The first is the clock of the ADC12 module. This is the clock when the module is running. It is different from the sampling ti
[Microcontroller]
MSP430 ADC12 sampling analysis
MSP430F149 IO port
1 Overview MSP430F149 has 6 groups of IO ports, each with 8 bits. The settings of IO ports include setting IO function, direction, and initial value of input and output registers. If no settings are made for IO ports, the default setting is the first function, input mode. 2 Commonly used registers PxDIR 0 input, 1
[Microcontroller]
Question about MSP430 Timer_A
I am using CCR1 continuous counting mode   This CCR1 needs to be assigned a value every time during the timer.   I found a strange phenomenon today. I blocked the CCR1 += 10000 in the timer interrupt, and the LED light was also on and off evenly . After you block the statement, the program runs
[Microcontroller]
Question about MSP430 Timer_A
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号