Untitled

 avatar
unknown
plain_text
a month ago
5.5 kB
2
Indexable
#include "msp430.h"
#include "scheduler.h"
#include "pin_def.h"

#include <stdint.h>

/*****************************************
*   DEFINES
*****************************************/
#define VREF 3.3
/*****************************************
*   PIN and Variable Definitions
*****************************************/
PinConfig rgbPins[3] = 
{
    {.dir = &P2DIR, .sel = &P2SEL, .ccr = &TA1CCR1, .pin = BIT0}, // P2.0 -> TA1.1 (R)
    {.dir = &P2DIR, .sel = &P2SEL, .ccr = &TA2CCR1, .pin = BIT4}, // P2.4 -> TA2.1 (G)
    {.dir = &P2DIR, .sel = &P2SEL, .ccr = &TA2CCR2, .pin = BIT5}  // P2.5 -> TA2.2 (B)
};

tCB taskList[TASK_COUNT];

uint32_t danger_level = 0;
float distance = 0;

/*****************************************
*   FUNCTION PROTOTYPES
*****************************************/
void init();

void configure_timers();
void configure_adc();
void configureUART();
float convert_to_distance(float voltage);

/*****************************************
*   TASK PROTOTYPES
*****************************************/
void pwm_sweep_Task();
void adc_read_Task();
void calculate_danger_level_Task();
void send_msg_Task();

/*****************************************
*   MAIN
*****************************************/
void main(void) 
{
    init();

    while (1) 
    {
        scheduler();
        __delay_cycles(1000);
    }
}

/*****************************************
*   IMPLEMENTATIONS
*****************************************/
void init() 
{
    WDTCTL = WDTPW | WDTHOLD;  // Stop watchdog timer


    int i;

    // Configure RGB pins for PWM output
    for (i = 0; i < 3; i++) 
    {
        *rgbPins[i].dir |= rgbPins[i].pin;  // Set PWM pin as output
        *rgbPins[i].sel |= rgbPins[i].pin;  // Select Timer_A function for the PWM pin
    }

    configure_timers();
    configure_adc();
    configureUART();

    *rgbPins[0].ccr = 0;
    *rgbPins[1].ccr = 0;
    *rgbPins[2].ccr = 0;

    taskList[0] = initTask(pwm_sweep_Task, 1, 0, true);
    taskList[1] = initTask(adc_read_Task, 5, 0, true);
    taskList[2] = initTask(calculate_danger_level_Task, 10, 0, true);
    taskList[3] = initTask(send_msg_Task, 20, 0, true);
}

void configure_timers()
{
    TA1CCR0 = 2000 - 1;         
    TA1CCTL1 = OUTMOD_7;       
    TA1CTL = TASSEL_2 | MC_1;   

    TA2CCR0 = 2000 - 1;       
    TA2CCTL1 = OUTMOD_7;        
    TA2CCTL2 = OUTMOD_7;        
    TA2CTL = TASSEL_2 | MC_1;
}

void configure_adc() 
{
    P6SEL |= BIT0;  // Set P6.0 to ADC function

    ADC12CTL0 = ADC12SHT0_2 | ADC12ON;
    ADC12CTL1 = ADC12SHP;        
    ADC12MCTL0 = ADC12INCH_0;    
    ADC12CTL0 |= ADC12ENC;       
}

void configureUART() 
{
    P4SEL |= BIT4 | BIT5;

    UCA1CTL1 |= UCSWRST;

    UCA1CTL1 |= UCSSEL_2;  

    UCA1BR0 = 104;         // Divider for 9600 baud
    UCA1BR1 = 0;
    UCA1MCTL = UCBRS_1 | UCBRF_0;

    UCA1CTL1 &= ~UCSWRST;  // Release from reset
}


float convert_to_distance(float voltage) 
{
    float dist = 4.160 * ((7.8535 / voltage) - 1);
    if (dist > 40) 
    {
        dist = 80;
    }
    return dist;
}

/*****************************************
*   TASK IMPLEMENTATIONS
*****************************************/
void pwm_sweep_Task() 
{
    *rgbPins[1].ccr = danger_level;               
    *rgbPins[0].ccr = TA2CCR0 - danger_level;
}

void adc_read_Task() 
{
    static float last_distance;
    unsigned int adcResult = 0;
    float voltage = 0;

    ADC12CTL0 |= ADC12SC;         
    while (ADC12CTL1 & ADC12BUSY); 

    adcResult = ADC12MEM0;         
    voltage = (adcResult / 4095.0) * VREF; 

    distance = convert_to_distance(voltage);
    distance = distance * 0.85 + 0.15 * last_distance;
    last_distance = distance;
}

void calculate_danger_level_Task() 
{
    static uint32_t prev_danger_level;
    float danger = 0;

    danger = 1349 - 33.53 * distance;
    danger_level = (uint32_t)danger;

    prev_danger_level = (prev_danger_level * 0.9) + (danger_level * 0.1);

    if (danger_level > 1042) 
    {
        danger_level = 1042;
    }
}

void send_msg_Task() 
{
    const char *prefix = "Distance: ";
    const char *newline = "\n";

    // Send the prefix
    while (*prefix != '\0') 
    {
        while (!(UCA1IFG & UCTXIFG)); // Wait for TX buffer to be ready
        UCA1TXBUF = *prefix++;
    }
    int intPart = (int)distance;                 
    int fracPart = (int)((distance - intPart) * 100); 

    if (fracPart < 0) fracPart *= -1;

    if (intPart == 0) 
    {
        while (!(UCA1IFG & UCTXIFG));
        UCA1TXBUF = '0';
    } 
    else 
    {
        char buffer[10];
        int index = 0;

        while (intPart > 0) 
        {
            buffer[index++] = (intPart % 10) + '0';
            intPart /= 10;
        }

        while (index > 0) 
        {
            while (!(UCA1IFG & UCTXIFG));
            UCA1TXBUF = buffer[--index];
        }
    }

    while (!(UCA1IFG & UCTXIFG));
    UCA1TXBUF = '.';

    char fracBuffer[3]; 
    fracBuffer[0] = (fracPart / 10) + '0';
    fracBuffer[1] = (fracPart % 10) + '0';
    fracBuffer[2] = '\0';

    const char *fracPtr = fracBuffer;
    while (*fracPtr != '\0') 
    {
        while (!(UCA1IFG & UCTXIFG));
        UCA1TXBUF = *fracPtr++;
    }

    while (*newline != '\0') 
    {
        while (!(UCA1IFG & UCTXIFG)); 
        UCA1TXBUF = *newline++;
    }
}

Leave a Comment