Hello everyone. I'm fairly new to microcontrollers, but not very new to circuits in general. I'm working with the MSP430 by TI, and am trying to get a demo of varying period PWM as well as varying duty cycle. The duty cycle currently just increases and decreases in a triangle-wave form, so that the output LED pulsates. I am attempting to get the period of oscillation to be controlled through the time between two button presses on the development board, so this is not a PWM problem as much as it is a timing problem. My code may be sloppy, as I am new to programming microcontrollers (not used to all these defines, they're all over the place), so please bear with me. I am trying to use the port 1 interrupt to catch the button press, although it seems that nothing is happening when I press the button multiple consecutive times. Any guidance on this would be appreciated, as I have been trying to get this to work for a while, and can't seem to find a good resource for examples of programs that do more than just one function (such as only pwm or only interrupt on button press). Thank you.
Rich (BB code):
#include "msp430g2231.h"
#include <signal.h>
#define LED_BIT (BIT0 | BIT6) // both LEDs
#define LED_DIR P1DIR
#define LED_OUT P1OUT
#define SWITCH_BIT BIT3
#define SWITCH_DIR P1DIR
#define SWITCH_IE P1IE // interrupt enable
#define SWITCH_ES P1IES // interrupt edge select
static volatile int ticks = 0; // tick counter
static volatile int lastPressTicks = 0; // tick count of last button press
static volatile int ledPeriodTicks = 0; // number of ticks between LED flashes
static volatile int ledTimer = 0; // LED flash downcounter (ledPeriodTicks to 0)
static volatile int period = 500;
void triangleWave();
void delay ( unsigned int );
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= BIT6; // Set P1.6 to output direction
P1SEL |= BIT6; // P1.6 to TA0.1
CCR0 = period-1; // PWM Period
CCTL1 = OUTMOD_7; // CCR1 reset/set
CCR1 = 0; // CCR1 PWM duty cycle
TACTL = TASSEL_2 + MC_1; // SMCLK, up mode
P1IE |= BIT3; // P1.3 interrupt enabled
P1IES |= BIT3; // P1.3 Hi/lo edge
P1IFG &= ~BIT3; // P1.3 IFG cleared
_BIS_SR(LPM0_bits + LPM4_bits + GIE); // Enter LPM4 w/interrupt
triangleWave();
}
void triangleWave(){
int upDown = 1;
while(1){
CCR0 = period-1;
if (upDown == 1){
CCR1 = (CCR1 + 1) % period;
if (CCR1 == period-1) {
upDown = 0;
}
delay(1);
}
else {
CCR1 = (CCR1 - 1) % period;
if (CCR1 == 0) {
upDown = 1;
}
delay(1);
}
}
}
void delay(unsigned int ms)
{
while (ms--)
{
__delay_cycles(1000); // set for 16Mhz change it to 1000 for 1 Mhz
}
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if((P1IFG & BIT3) == SWITCH_BIT) // switch pressed
{
if (lastPressTicks == 0) // first press
{
lastPressTicks = ticks;
//LED_OUT |= LED_BIT; // Turn on LED
}
else
{
ledPeriodTicks = (ticks - lastPressTicks);
ledTimer = ledPeriodTicks;
period = ledPeriodTicks;
lastPressTicks = 0;
//LED_OUT &= ~LED_BIT; // Turn off LED
}
}
P1IFG = 0x00; // clear interrupt flags
}