MSP430 - Traffic light with a buzzer

Thread Starter

Alejofnb

Joined Dec 24, 2019
20
Hi, i want to control a traffic light in that way:
Firstly i have to say that orange colour is when leds green and red are ON at same time.
At first place traffic light will be with green led ON. Then, when someone press the botton S2 of the launchpad (P1.1), green led blinks with a period of 1/8 second. After one second, traffic light change its colour to orange without blinking (as i said before both green and red are ON now) during 2 seconds. After that, traffic light change its colour to Red for 3 seconds and, when these 3 seconds finish, it starts to blink in red colour at period of 1/16 seconds during 1 last second. After this sequence, it starts over by changing traffic light colour again to Green without blinking and waiting for someone to push the button again.
A bit 'extra' is that i wanna count the number of people that pressed the button with a variable --> numero_peatones. And also i want to add a buzzer (perhaps a passive one) which i can control with a PWM signal. So, for example, when is near to finish one state and begin next one (such as changing colour green to orange), i want to increase PWM signal in order to increase the sound it goes off the buzzer to warn the person, who has the intention to cross the street, that has to hurry up.
My problem is related to the buzzer (leds changing and the delays between them work well), because i want to connect it to the pin P3.6 of microcontroller MSP430F5529 by a NPN transistor, that has a 1k resistor in its base. As it seems when i saw the MSP430F5529 datasheet, pin P3.6 has TB0.6 associated to it. So i made a function of TimerB_PWM that sets a period of 0,25 ms (or 4 kHz) and a initial duty cycle of 0%. Then, when red or green leds blink i want to increase the value of the Duty Cycle of the TimerB0 to increase the PWM of the buzzer. That's my idea of monitoring the volume of the buffer as time passes.

I paste my code here:
C:
#include <msp430.h>
#include <stdint.h>

uint8_t numero_peatones = 0;
uint16_t volatile contador_segundos;
uint8_t volatile conteo_pulsador = 0;

void Inicializacion_Relojes(void) //  SMCLK at 1 MHz
{
    __bis_SR_register(SCG0); // Disable the FLL control loop
    UCSCTL0 = 0x0000; // Ponemos el DCOx y MODx al minimo posible
    UCSCTL1 = DCORSEL_5; // Seleccionamos un rango de operación del DCO range de 16MHz
    UCSCTL2 = FLLD_0 | 487;  // Poniendo FLLD_0 hacemos tomamos como 1 el divisor de la frecuencia de entrada del cristal de cuarzo y 487 es el valor multiplicador de FLLN
                             // (N + 1) * (FLLRef/n) = Fdcomsp430
                             // (487 + 1) * (32768/1) = 16MHz
    UCSCTL3 = 0; // FLL SELREF = XT1CLK y divisor de FLL = 1 (FLLREFDIV = FLLREFCLK/1)
    UCSCTL4 |= SELA_0 | SELS_4 | SELM_4;  // Tomamos ACLK = XT1CLK (Cuarzo externo de 2^15 bits); SMCLK = MCLK = DCOCLKDIV (DCO interno de 16 MHz)
    UCSCTL5 |= DIVA_0 | DIVS_4; // Divisor para SMCLK = f(SMCLK)/16; ACLK = f(ACLK)/1
    __bic_SR_register(SCG0); // Enable the FLL control loop
}

void inicializacion_pulsador(void)
{
    P1SEL = 0x00; // GPIO pins
    P1DIR &= ~BIT1;  // input P1.1
    P1REN |= BIT1; // enable Pull up/down
    P1OUT |= BIT1; // Pull-up interna en pin 1.1
    P1IES |= BIT1;
    P1IE |= BIT1;
    P1IFG &= ~BIT1;
}

void inicializacion_LEDs(void)
{
    P1SEL &= ~BIT0; // LED1 of Launchpad as GPIO
    P1DIR |= BIT0; // LED1 as output
    P1OUT &= ~BIT0;  // RED LED off at first place
    P4SEL &= ~BIT7;
    P4DIR |= BIT7; // LED2 as output
    P4OUT |= BIT7; // GREEN LED on at first place
}

void pin_buzzer(void){
    P3SEL |= BIT6; // P3.6 as alternative function (for Timer TB0.6 --> see datasheet MSP430F5529)
    P3DIR |= BIT6; // Pin as output connected to buzzer
}

void delay_segundos(uint8_t segundos) // Function for delay sec --> Reloj ACLK
{
    contador_segundos = 0;
    TA2CTL |= MC_1; // UP MODE
    TA2CCTL0 |= CCIE;
    while(contador_segundos < segundos);
    TA2CTL &= ~MC_3; // stop timer
}

void TimerA0(void) // Timer to count 1/8 sec
{
    TA0CCR0 = 15624; // f(SMCLK)/8 = 125kHz --> want to count 1/8 sec --> TA0CCR0 = (125kHz/8) - 1 = 15624.
    TA0CTL |= TASSEL_2 | ID_3 | MC_0; // TASSEL_2: SMCLK; ID_3: Divisor freq --> f(SMCLK)/8; MC_0: Stop Mode
}

void TimerA1(void) // Timer to count 1/16 seconds
{
    TA1CCR0 = 15624; // f(SMCLK)/4 = 250kHz --> want to count 1/16 sec --> TA1CCR0 = (250kHz/16) - 1 = 15624. 
    TA1CTL |= TASSEL_2 | ID_2 | MC_1; // TASSEL_2: SMCLK; ID_2: Divisor freq --> f(SMCLK)/4; MC_1: Up Mode
}

void TimerA2(void) // Timer for seconds
{
    TA2CCR0 = 8191; // f(ACLK)/4 = 8192Hz
    TA2CTL |= TASSEL_1 | ID_2 | MC_0; // TASSEL_2: ACLK; ID_2: Divisor freq --> f(ACLK)/4; MC_0: Stop Mode
}

void TimerB0_PWM(void) // Timer for monitoring PWM of a buzzer
{
    TB0CCR0 = 999; // Periode of PWM: 1000 pulses --> 4kHz (o 0,25 ms)
    TB0CCTL1 |= OUTMOD_3; // Mode CCR1: PWM set/reset
    TB0CCR1 = 0; // Duty Cycle initial: 0 %
    TB0CLT |= TASSEL_2 | ID_2 | MC_1 | TACLR; // TASSEL_2: SMCLK; ID_2: Divisor freq --> f(SMCLK)/4; MC_1: Up Mode
}

void main()
{
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
    Inicializacion_Relojes();
    inicializacion_pulsador();
    inicializacion_LEDs();
    pin_buzzer();
    TimerA0();
    TimerA1();
    TimerA2();
    TimerB0_PWM();
    __enable_interrupt(); // Para poder usar las ISR
    while(1){
        if(conteo_pulsador == 1)
        {
            delay_segundos(1);
            TA0CCTL0 &= ~CCIE; // disable Timer A0
            conteo_pulsador = 0;
            TB0CCR1 = 0; // reset in value
            P4OUT |= BIT7; // ORANGE LED --> both led ON
            P1OUT |= BIT0;
            delay_segundos(2);
            P4OUT &= ~BIT7; // GREEN LED off
            delay_segundos(3);
            TA1CCTL0 |= CCIE; // enable ISR RED LED--> 1/16 sec
            delay_segundos(1);
            TA1CCTL0 &= ~CCIE; // disable Timer A1
            TB0CCR1 = 0; // reset in value
            P4OUT |= BIT7; // GREEN LED on
            P1OUT &= ~BIT0; // RED LED off
            P1IE |= BIT1; // reenable interrupts in button
        }
    }
}


#pragma vector=TIMER0_A0_VECTOR
__interrupt void timerA0_0_isr(void)
{
    P4OUT ^= BIT7; // GREEN LED blinking
    TB0CCR1 += 125; // increase the tone frequency of the buzzer every time it goes into that ISR
    TA0CCTL0 &= ~CCIFG;
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void timerA1_0_isr(void)
{
    P1OUT ^= BIT0; // RED LED blinking
    TB0CCR1 += 125; // increase the tone frequency of the buzzer every time it goes into that ISR
    TA1CCTL0 &= ~CCIFG;
}

#pragma vector=TIMER2_A0_VECTOR
__interrupt void timer2_A0_ISR(void)  // ISR of Timer for counting seconds to delay
{
    contador_segundos++; // Increase the variable that counts the seconds
    TA2CCTL0 &= ~CCIFG;
}


#pragma vector=PORT1_VECTOR // ISR del pulsador P1.1 (S2)
__interrupt void port1_ISR(void)
{
    if(P1IFG & BIT1){ // when the button is pressed --> GREEN LED blinks to 1/8 sec
        numero_peatones++;
        P1IE &= ~BIT1; // disable temporaly interrupts on the button
        TA0CTL |= MC_1; // MC_1: Up Mode 
        TA0CCTL0 |= CCIE;
        P1IFG &= ~BIT1;
        conteo_pulsador++;
    }
}
Moderators note : used code tags
 
Last edited by a moderator:
Top