Tinkering TI MSP430F5529
|
Low Power Modes (LPM) and External Interrupt
At present era, the energy consumption of a device is a very important part of its design. Low power consumption along with optimum performance and long endurance are highly preferable aspects one can think of while crafting a new electronic product. With such in mind, MSP430s were developed with low power consumption feature. In terms of power consumption, MSP430s offer six modes of operation with five being low power or sleep modes of different consumption levels. In TI docs, low power modes are often simply referred as LPMs.
External interrupt is an important DIO input mode feature. It can break the continuity of a regular program flow, i.e. the main routine, and perform certain higher priority secondary tasks separately. Interrupts can be also used to wake up micros from low power sleep modes. Combinations of LPMs and external interrupts have many uses. A good example of such combinations is a wireless mouse. Unless moved or its buttons pressed, the mouse remains in dormant/sleep state to conserve precious battery energy. The internal electronics of the mouse fires up otherwise as if it has been triggered by interrupts caused by motion or button presses. Port A (PA) pins of MSP430F5529 micro are all external interrupt capable pins. Shown below is the structure of a P1 port pin with red regions highlighting external interrupt resources:
Apart from external interrupts, other interrupts like timer interrupts can also wake up a MSP430F5529 from LPM states.
There are 5 LPM modes and an Active Mode of operation. The intent of these modes is to change power consumption by suspending certain hardware and clocks. These are as follows:
• Active mode (AM)
- All clocks are active.
• Low-power mode 0 (LPM0)
- CPU and MCLK are disabled.
- FLL loop control, ACLK and SMCLK remain active.
• Low-power mode 1 (LPM1)
- CPU, MCLK and FLL loop control are disabled.
- ACLK and SMCLK remain active.
• Low-power mode 2 (LPM2)
- CPU, MCLK, FLL loop control and DCOCLK are disabled.
- DC generator of the DCO remains enabled.
- ACLK remains active
• Low-power mode 3 (LPM3)
- CPU, MCLK, FLL loop control, DC generator of the DCO and DCOCLK are disabled.
- ACLK remains active.
• Low-power mode 4 (LPM4)
- CPU, ACLK, MCLK, FLL loop control, DC generator of the DCO and DCOCLK are disabled.
- Crystal oscillator is stopped.
- Complete data retention.
• Low-power mode 4.5 (LPM4.5)
- Internal regulator disabled.
- No data retention.
- Wake-up signal from RST or NMI, P1, and P2.
Wake up times from various LPM states also varies but these variations are so tiny in terms of time that they are rarely observed visually.
Code Example
#include "driverlib.h" unsigned char toggle = 0; void GPIO_init(void); #pragma vector = PORT1_VECTOR __interrupt void PORT1_ISR(void) { LPM3_EXIT; if(GPIO_getInterruptStatus(GPIO_PORT_P1, GPIO_PIN1) != 0) { GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN1); toggle = 1; _nop(); } } void main(void) { unsigned char i = 0; unsigned char j = 0; WDT_A_hold(WDT_A_BASE); GPIO_init(); while(1) { for(j = 0; j < 10; j++) { GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); __delay_cycles(1000000); } if(toggle) { for(i = 0; i <= 9; i++) { GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN7); __delay_cycles(100000); } toggle = 0; } LPM3; }; } void GPIO_init(void) { GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); GPIO_setDriveStrength(GPIO_PORT_P1, GPIO_PIN0, GPIO_FULL_OUTPUT_DRIVE_STRENGTH); GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN7); GPIO_setDriveStrength(GPIO_PORT_P4, GPIO_PIN7, GPIO_FULL_OUTPUT_DRIVE_STRENGTH); GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN1); GPIO_selectInterruptEdge(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); __enable_interrupt(); }
Hardware Setup
Explanation
For this demo, on-board P1.1 button, P1.0 and P4.7 LEDs are used. The LEDs are set as in the GPIO example, i.e. as outputs.
P1.1 button pin is set as input pin with pull-up resistor. This pin is also used as the external interrupt pin. At first, any pending interrupt is cleared. We, then, have to set interrupt edge, i.e. polarity sensitivity. Finally, we enable interrupt on the interrupt pin and enable global interrupt.
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN1); GPIO_selectInterruptEdge(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); __enable_interrupt();
Now the button pin is ready to behave like an external interrupt pin rather than a regular input pin. Remember that P1 belongs to PA port and only PA port pins are interrupt capable.
Let’s look at the main loop now. Here, we see that P1.0 LED will be toggled 10 times first. The if-condition will not be initially executed since it is linked with the external interrupt. Thus, the conditional statement will be skipped and LPM3 condition will be set.
Once LPM is applied, everything seems to be suspended. P1.0 LED is supposed to keep flashing but that doesn’t happen.
for(j = 0; j < 10; j++) { GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); __delay_cycles(1000000); } if(toggle) { for(i = 0; i <= 9; i++) { GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN7); __delay_cycles(100000); } toggle = 0; } LPM3;
When the button is pressed, external interrupt kicks in, LPM3 is exited, interrupt flag is cleared and variable toggle is set. Since there is one interrupt vector for the entire P1 port pins, it is needed to be sure which pin caused the interrupt. This is why the state of P1.1 needs to be checked right after interrupt.
#pragma vector = PORT1_VECTOR __interrupt void PORT1_ISR(void) { LPM3_EXIT; if(GPIO_getInterruptStatus(GPIO_PORT_P1, GPIO_PIN1) != 0) { GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN1); toggle = 1; _nop(); } }
Since now the toggle variable is set, P1.0 LED flashes and then P4.7 LED flashes, indicating that an external interrupt has been processed.
Demo
|
Hi,
Im interfacing MSP430F5529 with MAX17055 fuel guage. while reading 16 bit value, the first byte im receiving is 0. so while reading multiple registers continuously the data exchange is happening, but im getting the correct data. Can anyone suggest me what will be the issue? why im getting 0 in first byte?
read16_bit data code:
uint16_t value = 0;
USCI_B_I2C_setslaveaddress(USCI_B1_BASE, slave_address);
USCI_B_I2C_setmode(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_MODE);
USCI_B_I2C_masterSendStart(USCI_B1_BASE);
while (!USCI_B_I2C_masterSendStart(USCI_B1_BASE));
USCI_B_I2C_mastterSendSingleByte(USCI_B1_BASE, reg_address);
USCI_B_I2C_setslaveaddress(USCI_B1_BASE, slave_address);
USCI_B_I2C_setmode(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_MODE);
USCI_B_I2C_masterReceiveMultiByteStart(USCI_B1_BASE);
uint8_t lb = USCI_B_I2C_masterReceiveMultiByteNext(USCI_B1_BASE);
uint8_t hb = USCI_B_I2C_masterReceiveMultiByteFinish(USCI_B1_BASE);
while (USCI_B_I2C_isBusBusy(USCI_B_BASE));
value = lb << 8;
value |= hb;
return value;
In code, after sending reg address, it will be recieve mode. its a type mistake
Hi, im trying to send the command from the terminal view. i can able to send the command and tried to blink p1.0 led in msp430f5529 controller, its working fine. And im using led driver IS31FL3236A interfaced with msp430f5529 controller, i can able to interface im getting the expected output.
now i need to send the command from seriak monitor based on that command i2c communication need to start. both communication are working fine, when it runs separately. its not working when i tried to combine.
any one had any idea, why it is happening or what will be the issue?
It could be due to:
1. conflicts in clock settings
2. hardware conflict like pin mapping
3. code is getting stuck or waiting for one communication line to finish
4. use of polling method instead of interrupt-driven coding
Hi, thank you for the respose.
Do I need to use different clock initialization for I2C and UART communication? if YES, can you explain how to do that?
I mean check which clock has been set for UART and I2C…. Is it SMCLK, MCLK, etc and is it tuned to right frequency required by the respective hardware?
Is there any example on how to implement polling method in uart?
Why go for polling method when it is a blocking method of coding? It is better to use interrupts instead at least for UART receive.
yes!! currently in my code, only for uart im using interrupts to recieve command from serial monitor. Im not using interrupt for I2C communication.
so the issue is must be in clock initialization. right?
For UART, im using USCI_A1_BASE. and for I2C, im using USCI_B1_BASE.
And another thing i need to ask is, in uart when i tried blink led(p1.0) in msp430f5529 by passing command. here, without clock I’m getting output. how it is possible?
And for both i2c and uart i gave SMCLK with 1Mhz
I am surprised and happy to find this tutorial on the F5529 as TI makes a lot of different devices.
Thank you very much for putting in the extra knowledge in each segment, made reading worthwhile.
Good Work!
lovely tutorial but to be honest I don’t think I’d be investing my time on this board to start with it’s not cheap and readily available as the stm32 boards can you please do more tutorials on stm32 board’s and the stc micros thanks
Hello, I try to program MSP430FR6047 but i get error “the debug interface to the device has been secured”. when flashing using uniflash and when program using CCS this happen. can you help me to solve this problem
You can try “On connect, erase user code and unlock the device” option.
Pingback: Tinkering TI MSP430F5529 – gStore
Hello
I am doing project of msp430g2553 interface(using i2c communication) with temp 100(temperature sensor) and try to read the temperature in dispaly(16*2) but didn’t get the out put (using code composer studio) can u share me any example code for this project
Thank you sir,
Which sensor? Did you use pullup resistors for SDA-SCL pins?
Where is lcd_print.h?
All files and docs are here:
https://libstock.mikroe.com/projects/view/3233/tinkering-ti-msp430f5529
You want the truth? TI makes and sell “underpowered micros”, you know? Low everything, not only the power but also peripherals. So the price is not justified.
Otherwise, if I’ll move there, I’ll introduce them to my small hobby projects – there are still some advantages.
I may even make a visual configuration tool of my own for them…
Yeah the prices of TI products are higher than other manufacturers but I don’t think the hardware peripherals are inferior.
Not inferior but in not enough numbers compared to STM32.
True