MSP430 5438 MCU Study Notes

Publisher:Harmonious88Latest update time:2015-11-10 Source: eefocusKeywords:MSP430  MCU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
I encountered many problems and gained a lot through the one-year study of 430. The following are some of the problems I encountered during the study and their solutions. There are still many things that have not been sorted out, and I am slowly sorting them out. . . .

1. Multiple-source interrupt problem
#pragma vector = PORT2_VECTOR
__interrupt void port2(void)
{
    switch(P2IV)
   {
        case P2IV_P2IFG6:
          P2IFG &=~BIT6;
          P1OUT ^= BIT0;break;           //LED1 on and off
        case P2IV_P2IFG7:
          P2IFG &=~BIT7;
          P1OUT ^= BIT1;break;           //LED2 on and off
        default  :break;
     }

}


#pragma vector = PORT2_VECTOR
__interrupt void port2(void)
 
    if(P1IFG&BIT6){
         P2IFG &=~BIT6;
    }
    if(P1IFG&BIT7){
         P2IFG &=~BIT7;
     

}

Are there any differences between these two methods? The above method uses the vector interrupt number to make the judgment, while the following method uses the interrupt flag to make the judgment. In the above judgment, is it necessary to clear the interrupt flag to 0 by software?

2. About flash block erase
void Seg_Erase(void){
    _DINT();
    WDTCTL = WDTPW + WDTHOLD;
    char *flase_erase;
    flase_erase = (char *)0x8000;                  //Point to the segment address to be erased
    while(FCTL3&BUSY);
    FCTL3 = FWKEY;                                 //Clear LOCK
    FCTL1 = FWKEY +ERASE;                         //Segment erase
    *flase_erase = 0;                              //Null write writes 0 to 1
    FCTL3 = FWKEY + LOCK;                          //LOCK set to 1
    _EINT();
}
When erasing a FLASH segment, does calling this function erase only one byte? When erasing the entire segment, do you use the for statement to call this function 128 times?
Or do you call this function once to erase all 128 bytes at once?

3. _root problem
   When the compiler encounters this instruction, it compiles it.

4. About the interrupt nesting and priority issues of MSP430?

5. MSP430 does not have its own EEPROM, but the four blocks of information ABCD are equivalent to EEPROM in the 5 series. Their addresses are
A: 001800H~00187fH
B: 001880H~0018FFH
C: 001900H~00197FH
D: 001980H~0019FFH

6. Hardware multiplier
MPY = 125;                            
OP2 = 125;
result = RESHI;
result = (result<<16)|RESLO;

result=125*125;

Which of these two compilations is more efficient? Will the compiler directly compile result = 125*125 into
MPY = 125;                            
OP2 = 125;
result = RESHI;
result = (result<<16)|RESLO;
and use the hardware multiplier to calculate this value?

7. Memory Issues
When I use the MSP5438 chip to calculate the 1024-point FFT, I define
float dataR[1024]={0};
float dataI[1024]={0}; in the RAN area

Define the sine and cosine table in the flash program memory
const  float sin_tab[1024]={.....};
const  float cos_tab[1024]={.....};
It can be calculated when doing software simulation, but it cannot be calculated when downloading to the chip using JTAG. When observing the RAM area, it is found that the data defined as const  float sin_tab[1024]
and const  float cos_tab[1024], which should be in the flash area, appear in the RAM area? As a result, the simulation cannot be performed.
After compiling, the resources consumed here should be acceptable. 
892 bytes of CODE  memory
8194 bytes of CONST memory
8194 bytes of DATA  memory
This is the first time I use the 430 chip. I don’t understand some of the questions. I hope you can give me some advice. Thank you. [page]

int __low_level_init(void)
{
 float dataR[1024]={0};
 float dataI[1024]={0};
 const  float sin_tab[1024]={.....};
 const  float cos_tab[1024]={.....};
 return (1);
}
Then in
__low_level_init();
void main(void)
.....
Is this how it should be used? Please advise!
Solution:
//Prevent the dog from resetting during compilation__low_level_init
(){
WDTCTL = WDTPW + WDTHOLD;
}
VIII. CCP capture problemvoid
 
Init_Ta0(void){
     P11DIR |= BIT0 + BIT1 + BIT2;                    // ACLK, MCLK, sMCLK  output directionP11SEL
     |= BIT0 + BIT1 + BIT2;
     P1DIR |= BIT0;
     P2DIR   &= ~BIT1;
     P2SEL   |=  BIT1;                          //Configure the second function of the input pinccr0 captureTA0CCTL0
     =~(CCIS0+CCIS1);                //CCIXA captureTA0CCTL0
     |= CM_3 + SCS + CAP;              //Capture on both the rising and falling edges, synchronous signal capture, capture mode

     TA0CTL   TASSEL_2;                       //SMCLK,
     //TA0CTL  |=  ID_3;                           //Input signal divisionTA0CTL
     MC_2;                           //Timer starts counting (continuous counting mode 0~0xFFFF)
     TA0CTL  |=  TACLR;                          //Counter clearTA0CCTL0
     |= CCIE;
     _EINT();

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void){
  if(TA0CCTL0 & CM1)                        //Capture falling edge
    {
      TA0CTL  |= TACLR;                     //Clear timerTA0CCTL0
      =(TA0CCTL0&(~CM1))| CM0;    //Change to rising edge capture: CM1 is set to zero, CM0 is set to one

    }
  else if(TA0CCTL0 & CM_0)                    //Capture the rising edge
    {
      width  = TA0CCR0;                  //Record the end time
      TA0CCTL0=(TA0CCTL0&(~CM0))| CM1;   //Change to falling edge capture: CM0 is set to zero, CM1 is set to one
    }

}

void main(void){
    WDTCTL = WDTPW + WDTHOLD;                      //Turn off watchdog
    P7SEL   |= 0x03;                                   // XT1 starts oscillating
    UCSCTL1 |= DCORSEL_2;                             // Select DCO frequency range
    UCSCTL3 |= SELREF__REFOCLK;                             // Select Fll reference frequency REFO
    UCSCTL4 = SELM__DCOCLK + SELA__XT1CLK + SELS__DCOCLKDIV;              // Configure MCLK = DCOC, SMCLK = DCODIV, ACLK=XT1
    while (SFRIFG1 & OFIFG)                          //Clear OFIFG,and  XT1OFFG ,DCOFFG
    {
          UCSCTL7 &= ~(XT1LFOFFG + DCOFFG);
          SFRIFG1 &= ~OFIFG;
    }
    while(1){
     P1OUT ^= BIT0;                            //LED flashes, indicating that there is no crystal failure
    for(unsigned  int i=60000;i>0;i--);       // delay
    }
}

I use the P2.1 port of MSP5438 to do a capture test. I think the program is OK. I input 8HZ square wave, but the program just doesn't enter the interrupt. It's very strange. Can you help me find the above problem?
Answer: The setting is wrong.

9. About interrupts
Since the project requires the use of MSP430 microcontrollers for the first time, after half a month of study, with the help of friends, I have some experience. Today, let's talk about interrupts. I hope to discuss with you. Please point out if I am wrong.
Comparison of MSP430 interrupts and 51, PIC16 series
MSP430:
Priority is considered only when there are multiple interrupts at the same time (the priority order can be viewed in the vector table) It has been defined in the header file
After the interrupt response, the general interrupt is automatically turned off. At this time, even if a higher priority interrupt comes, it will not be responded
If you want to nest interrupts, you must turn on the general interrupt in the interrupt.
In the instructions of msp430, DINT and EINT refer to turning off and on all interrupts respectively.
 
The following points should be noted when implementing interrupt nesting:
1. 430 defaults to closing interrupt nesting, unless you open the general interrupt EINT again in an interrupt program, of course, each request permission flag must be set;
2. When entering the interrupt program, as long as you do not open the interrupt again in the interrupt, the general interrupt is closed. At this time, the interrupt will not be executed regardless of whether it is higher or lower than the current interrupt priority;
3. If the general interrupt is opened in interrupt A, you can respond to the subsequent interrupt B (regardless of whether B has a higher or lower priority than A), and continue to execute A after B is executed. Note: After entering interrupt B, the general interrupt will also be closed.
If the interrupt program B needs to respond to interrupt C, the general interrupt must also be opened at this time. If the interrupt does not need to be responded to, the interrupt does not need to be opened. After B is executed, when the interrupt program jumps out and enters the A program, the general interrupt will be automatically opened;
4. If the general interrupt is opened in the interrupt, and there are multiple subsequent interrupts at the same time, they will be executed according to priority, that is, the interrupt priority will only work when multiple interrupts arrive at the same time! Interrupt service does not implement the preemptive principle.
5. For single-source interrupts, as long as the interrupt is responded, the system hardware automatically clears the interrupt flag. For the comparison/capture interrupt of the TA/TB timer, as long as the TAIV/TBIV is accessed, the flag is automatically cleared.
For multi-source interrupts, the flag must be manually cleared. For example, for P1/P2 port interrupts, the corresponding flag must be manually cleared. If you use "EINT();" to open the interrupt in this type of interrupt, and do not clear the flag before opening the interrupt, the same
interrupt will be embedded continuously, causing the stack overflow to cause a reset. Therefore, in this type of interrupt, the flag must be cleared before the interrupt switch is opened.
However, I don't quite understand the use of vectors for multi-source interrupts. There is such an example in the routine.
Example 1: #pragma vector = PORT2_VECTOR
__interrupt void port2(void)
{
    switch(P2IV)
   {
        case P2IV_P2IFG6:
          P1OUT ^= BIT0;break;           //LED1 on and off
        case P2IV_P2IFG7:
          P1OUT ^= BIT1;break;           //LED2 on and off
        default  :break;
     }

}
Example 2: #pragma vector = PORT2_VECTOR
__interrupt void port2(void)
 
    if(P1IFG&BIT6){
         P2IFG &=~BIT6;
    }
    if(P1IFG&BIT7){
         P2IFG &=~BIT7;
     

}
When using the vector method, the interrupt flag is not cleared by software in Example 1. Is it cleared by hardware using the vector method? Will turning on the general interrupt affect the program stack overflow? I have not verified this.
But it is clear in Example 2, and we can know that we can turn on the mid-segment nesting in it.

PIC:
The interrupt entry address of the low-end PIC microcontroller is only one, 0004H. When there are multiple interrupt sources, it enters from the entry address 0004H, and then the software determines the priority. The priority of each maskable
interrupt of PIC16 is the same. In the interrupt, only the software can determine the priority. When entering the interrupt, turn off the interrupt like 430 (this step is turned off by hardware). When there are other interrupts at this time

When the source comes, set the flag to 1, and respond to new interrupt requests after the current service program is finished.
51:
51 supports interrupt nesting like 430, and the interrupt priority can be set through a special register. As long as the stack does not overflow, it can be nested. The difference between 430 and 430 is that 430 can be nested by interrupts of lower priority level
, while 51 cannot be nested by interrupts of lower priority level than itself. 51 must clear the flag bit by software.

This post only expresses my personal opinion. I hope the questions I raise can be answered. I still hope to get more guidance from you experts.

10. Solve the bootload problem
Use function pointers to implement address jumps in the program. There will be problems using the nested assembly jump method
typedef void (*pfunction)(void);
pfunction pMyreset=(pfunction) 0x453d2;
       pMyreset();

11. Questions about fft
I would like to ask you, when I simulate fft transformation with software, I do this, but the analyzed data is put into Re, the result is Re[0]=1299, Re[1]=0,
when Re[8]=199, how can the fundamental component run to Re[8], and the result produced by the hardware also runs to the high position of the array. I don’t quite understand why
the position changes when switching from a single cycle to multiple cycles. When making hardware, there should be no problem with continuous sampling of 8 cycles. The core code below
is written by Quanquan, and the result produced by the section I wrote myself is also the same. Yesterday I thought my program was wrong.
 for(uint16 j=0;j<1024;j++){
  dataR[j]=200*cos(6.28/128*j)+1300;
 }
 FftInput(dataR);       //Bit reverse order
 FftExe(dataR,Re,Im);   //Do FFT operation
 Re[0]=(LEN_TYPE)Re[0]/1024;
 for (i=1;i<1024;i++) {
   Re[i]=(LEN_TYPE )(sqrt((Re[i]>>9)*(Re[i]>>9)+(Im[i]>>9)*(Im[i]>>9)));

/////////////////////////All rights reserved. Please indicate the source if you need to reprint. Fish-flavored eggplant///////////////////////////////////////

Keywords:MSP430  MCU Reference address:MSP430 5438 MCU Study Notes

Previous article:A program that stores the numeric characters in a string separately from other characters
Next article:Meaning of P3DIR|=BIT0, P3OUT&=~BIT0

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
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号