Tool/software: Code Composer Studio
Hi, i've made two voltage dividers supplied by an external voltage of 3.3V and made of a LDR connected in series to a resistor. I have also used LEDs to show the change of the internal resistor of the LDR. My purpose is, by changing the light applied to LDRs, change the PWM duty cycle that goes to the LEDs associated to each LDR with timers. So, for example, if i have a situation of absence of light two LEDs (one for each LDR) will light so much to compensate this absence of light.
I paste my code here. If anyone see any problem, i would be grateful for any suggestion. Thanks btw!
To read it in a better way with identations and all that stuff i paste also the same code with pastebin here: https://pastebin.com/htjSHBX9
#include <msp430.h>
#include <stdint.h>
#include <stdio.h>
uint16_t adc_A0[8] = {0}; // Array para to store a total of 8 values initialized to zero for A0
uint16_t adc_A1[8] = {0}; // Array para to store a total of 8 values initialized to zero for A1
uint8_t buffer_lleno = 0;
volatile uint8_t end_conversion = 1; // variable to determine wether the conversion has finished or not yet
uint16_t valor_promedio_A0 = 0; // Variable that stores the average value of A0 channel
uint16_t valor_promedio_A1 = 0; // Variable that stores the average value of A1 channel
void Inicializacion_Relojes(void){
__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) = Fdco
// (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_0; // Divisor para SMCLK = f(SMCLK)/1; ACLK = f(ACLK)/1 --- NO ES NECESARIA PORQUE SON LOS VALORES POR DEFECTO
__bic_SR_register(SCG0); // Enable the FLL control loop
}
void Inicializacion_Leds(void){
P1SEL |= (BIT2 | BIT3); // alternative function for leds
P1DIR |= (BIT2 | BIT3); // LEDs as outputs
}
void TimerA0_PWM(void){
TA0CCR0 = 2000-1; // Tperíodo del PWM: 2000 milisegundos
TA0CCTL1 |= OUTMOD_3; // Modo CCR1: Set/Reset.
TA0CCR1 = 0; // Duty Cycle inicial: 0%
TA0CCTL2 |= OUTMOD_3; // Modo CCR1: Set/Reset.
TA0CCR2 = 0; // Duty Cycle inicial: 0%
TA0CTL |= TASSEL_2 | ID_3 | MC_1 | TACLR; // Reloj SMCLK, Frecuencia: 16 MHz. Modo Up. Preescalador: 8
}
// Funcion para configurar el ADC:
void ConfiguracionADC(void){
P6SEL |= BIT0 | BIT1; // to use P6.0 y P6.1 as entries of channel A0 and A1
ADC12CTL0 |= ADC12SHT0_5 | ADC12MSC | ADC12ON; // ADC12ON: Activamos el ADC; ADC12SHT0_5: 64 ciclos de muestreo del S & H
ADC12CTL1 |= ADC12SSEL_3 | ADC12DIV_7 | ADC12CONSEQ_3 | ADC12SHP; // ADC12SSEL_3: SMCLK; ADC12DIV_7: Preescalador de 8; ADC12CONSEQ_3: Multiples samples in multiple channels
ADC12MCTL0 |= ADC12SREF_0 | ADC12INCH_0; // ADC12SREF_0: VR+ = AVcc+ and VR- = AVss ; ADC12INCH_0: Channel A0
ADC12MCTL1 |= ADC12SREF_0 | ADC12INCH_1 | ADC12EOS; // ADC12INCH_1: Channel A1; ADC12EOS: end of sequence
__delay_cycles(30); // wait for stabilize of voltage reference
ADC12CTL0 |= ADC12ENC; // ADC12ENC: enable conversion
ADC12IE |= BIT1; // enable ADC12IFG.1
}
void main(void){
uint8_t cont; // Variable to iterate in the array
uint16_t value1,value2;
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
Inicializacion_Relojes();
Inicializacion_Leds();
TimerA0_PWM();
ConfiguracionADC();
__enable_interrupt();
while(1){
if(end_conversion == 1){ // if the conversion has finished
ADC12CTL0 |= ADC12SC; // ADC12SC: you can start over another conversion
end_conversion = 0;
}
if (buffer_lleno == 1){
for(cont=0; cont<8; cont++){
valor_promedio_A0 += adc_A0[cont];
valor_promedio_A1 += adc_A1[cont];
}
valor_promedio_A0 >>= 3; // to divide by 8 (3 bits shift to the right)
valor_promedio_A1 >>= 3;
value1 = (TA0CCR0*(valor_promedio_A0))/(4096);
TA0CCR1 = value1;
value2 = (TA0CCR0*(valor_promedio_A1))/(4096);
TA0CCR2 = value2;
valor_promedio_A0 = 0; // Reset value of A0
valor_promedio_A1 = 0; // Reset value of A0
buffer_lleno = 0;
end_conversion = 1;
}
}
}
#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR (void)
{
static unsigned int index = 0;
switch(__even_in_range(ADC12IV,34))
{
case 0: break; // Vector 0: No interrupt
case 2: break; // Vector 2: ADC overflow
case 4: break; // Vector 4: ADC timing overflow
case 6: break;
case 8: // Vector 8: ADC12IFG1
adc_A0[index] = ADC12MEM0;
adc_A1[index] = ADC12MEM1;
index++;
if (index == 8){
buffer_lleno = 1;
index = 0;
ADC12CTL0 &= ~ADC12SC;
end_conversion = 0;
}
else{
end_conversion = 1;
}
case 10: break; // Vector 10: ADC12IFG2
case 12: break; // Vector 12: ADC12IFG3
case 14: break; // Vector 14: ADC12IFG4
case 16: break; // Vector 16: ADC12IFG5
case 18: break; // Vector 18: ADC12IFG6
case 20: break; // Vector 20: ADC12IFG7
case 22: break; // Vector 22: ADC12IFG8
case 24: break; // Vector 24: ADC12IFG9
case 26: break; // Vector 26: ADC12IFG10
case 28: break; // Vector 28: ADC12IFG11
case 30: break; // Vector 30: ADC12IFG12
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}
}