Part Number: MSP432P401R
Hello, I have made a code that allows me, by pressing the button P1.4, to change the direction of the H-bridge having that, if you had activated the high transistor of phase B and the low transistor of phase C and you suddenly press the button, they become deactivated and the high transistor of phase C and the low transistor of phase B become activated and each time you press the button again they alternate, activating again the high of B and the low of C and so on. It does it correctly, but sometimes when I press the pushbutton it does not alternate in the direction and the same transistors remain activated when they should have been switched. It may be an effect of the pushbutton debouncing, but if so, how could I modify the code in a 'simple' way to fix it? Thanks a lot!
-
#include "msp.h"
-
#include <stdint.h>
-
#include <stdio.h>
-
-
volatile uint8_t pulsador = 0; //Variable to change the direction on the H-bridge
-
volatile uint8_t contador_ms = 0;
-
volatile uint8_t conteo = 0;
-
uint8_t duty_cycle = 14; // +/- el 50% of Duty Cycle
-
-
void pulsadores(void){ // Use pushbutton S2 (P1.4) to change direction on the H-bridge.
-
P1SEL0 &= ~BIT4; // Function I/O
-
P1SEL1 &= ~BIT4;
-
P1DIR &= ~BIT4;
-
P1REN |= BIT4;
-
P1OUT |= BIT4;
-
P1IES |= BIT4;
-
P1IFG &= ~BIT4;
-
P1IE |= BIT4;
-
}
-
-
void transistors(void){
-
/* TB: P7.5; TC: P7.6
-
* BB: P7.1; BC: P7.2
-
*/
-
-
// Pines Transistores High (PWM)
-
P7SEL0 |= (BIT5 | BIT6); // Set PIN P7.5 and P7.6 for output on Timer
-
P7SEL1 &= ~(BIT5 | BIT6);
-
P7DIR |= (BIT5 | BIT6);
-
-
// Pines Transistores Low (GPIO)
-
P7SEL0 &= ~(BIT1 | BIT2);
-
P7SEL1 &= ~(BIT1 | BIT2);
-
P7DIR |= (BIT1 | BIT2); // output
-
}
-
-
void TimerA0(void){
-
// This timer will be used to change states during the sequence.
-
TA0CCR0 = 374; // (375-1) Tperiode del PWM: 1 ms
-
TA0CTL |= TASSEL_2 | ID_3 | MC_1 | TACLR;
-
}
-
-
void TimerA1_PWM(void){ // Timer to control the 2 PWM pins
-
TA1CCR0 = 29; // (30-1) PWM period: 10 us -> As SMCLK = 3MHz, the counter counts in Up Mode every 1/3MHz = 0.333 us. Therefore, 30 - 0.333us = 10 us
-
TA1CTL |= TASSEL_2 | ID_3 | MC_1 | TACLR;
-
TA1CCTL2 |= OUTMOD_7; // Mode CCR2: Reset/Set
-
TA1CCTL3 |= OUTMOD_7; // Mode CCR3: Reset/Set
-
}
-
-
void TimerA2_Antirebotes(void){
-
TA2CCR0 = 1023; // (1024-1) To obtain 250 ms of anti-rebounds -> The counter counts in Up Mode every 1/(4.096 kHz) = 0.244 ms. Therefore, 1024 - 0.244 ms = 250 ms
-
TA2CTL |= TASSEL_1 | ID_3 | MC_1 | TACLR; // ACLK clock with a frequency of 32.768 kHz and with a frequency divider of 8, Up Mode -> fACLK = 4.096 kHz
-
}
-
-
void delay_ms(uint8_t tiempo){
-
contador_ms = 0;
-
TA0CTL |= MC_1; // up
-
TA0CCTL0 |= CCIE;
-
while(contador_ms < tiempo);
-
TA0CTL &= ~MC_3; // stop timer
-
}
-
-
void init_interrupciones(void){
-
NVIC_EnableIRQ(TA0_0_IRQn);// Enable interrupts in TimerA0_0
-
NVIC_EnableIRQ(TA2_0_IRQn); // Enable interrupts in TimerA2_0
-
NVIC_EnableIRQ(PORT1_IRQn); // enable interr PORT1
-
__enable_irq(); // Enable global interrupt
-
}
-
-
void main(void)
-
{
-
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer
-
pulsadores();
-
transistors();
-
TimerA0();
-
TimerA2_Antirebotes();
-
TimerA1_PWM();
-
init_interrupciones();
-
-
while(1){
-
if(pulsador%2 == 0){
-
if(conteo==1){
-
P7OUT &= ~BIT1; // BB y TC en OFF
-
TA1CCR2 = 0;
-
delay_ms(10);
-
conteo = 0;
-
}
-
else if(conteo==0){
-
P7OUT |= BIT2; // BC en ON
-
TA1CCR3 = duty_cycle; // TB en ON
-
delay_ms(10); // 10 ms en ON
-
P7OUT &= ~BIT2; // BC en OFF
-
TA1CCR3 = 0; // TB en OFF
-
delay_ms(10); // 10 ms en ON
-
}
-
}
-
else if(pulsador%2 != 0){
-
if(conteo==1){
-
P7OUT &= ~BIT2; // TB y BC en OFF
-
TA1CCR3 = 0;
-
delay_ms(10);
-
conteo = 0;
-
}
-
else if(conteo==0){
-
P7OUT |= BIT1; // BB en ON
-
TA1CCR2 = duty_cycle; // TC en ON
-
delay_ms(10); // 10 ms en ON
-
P7OUT &= ~BIT1; // BB en OFF
-
TA1CCR2 = 0; // TC en OFF
-
delay_ms(10); // 10 ms en OFF
-
}
-
}
-
}
-
}
-
-
void TA0_0_IRQHandler(void){ // Interrupt Timer A0
-
TA0CCTL0 &= ~CCIFG;
-
contador_ms++;
-
}
-
-
void TA2_0_IRQHandler(void){ // Interrupt Timer A2
-
TA2CCTL0 &= ~CCIFG;
-
P1IFG &= ~BIT4; // we lower the flag of the pushbutton so that it does not remain depressed
-
P1IE |= BIT4; // We reactivate interruptions on pushbutton P1.4
-
}
-
-
void PORT1_IRQHandler(void) // Interrupt Port P1
-
{
-
P1IE &= ~BIT4; // We deactivate interrupts on pushbutton P1.4
-
pulsador++;
-
conteo++;
-
if(pulsador > 5){ // So that it does not increase indefinitely, and can reach the limit value of 255
-
pulsador = 0;
-
}
-
TA2CCTL0 |= CCIE; // We enable interrupts in the Timer A2_0
-
}