Advertisement
Guest User

Untitled

a guest
May 12th, 2020
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.82 KB | None | 0 0
  1. #include <msp430.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4.  
  5. uint16_t adc_A0[8] = {0}; // Array para to store a total of 8 values initialized to zero for A0
  6. uint16_t adc_A1[8] = {0}; // Array para to store a total of 8 values initialized to zero for A1
  7. uint8_t buffer_lleno = 0;
  8. volatile uint8_t end_conversion = 1; // variable to determine wether the conversion has finished or not yet
  9. uint16_t valor_promedio_A0 = 0; // Variable that stores the average value of A0 channel
  10. uint16_t valor_promedio_A1 = 0; // Variable that stores the average value of A1 channel
  11.  
  12. void Inicializacion_Relojes(void){
  13.  
  14. __bis_SR_register(SCG0); // Disable the FLL control loop
  15. UCSCTL0 = 0x0000; // Ponemos el DCOx y MODx al minimo posible
  16. UCSCTL1 = DCORSEL_5; // Seleccionamos un rango de operación del DCO range de 16MHz
  17. 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
  18. // (N + 1) * (FLLRef/n) = Fdco
  19. // (487 + 1) * (32768/1) = 16MHz
  20. UCSCTL3 = 0; // FLL SELREF = XT1CLK y divisor de FLL = 1 (FLLREFDIV = FLLREFCLK/1)
  21. UCSCTL4 |= SELA_0 | SELS_4 | SELM_4; // Tomamos ACLK = XT1CLK (Cuarzo externo de 2^15 bits); SMCLK = MCLK = DCOCLKDIV (DCO interno de 16 MHz)
  22. // UCSCTL5 |= DIVA_0 | DIVS_0; // Divisor para SMCLK = f(SMCLK)/1; ACLK = f(ACLK)/1 --- NO ES NECESARIA PORQUE SON LOS VALORES POR DEFECTO
  23. __bic_SR_register(SCG0); // Enable the FLL control loop
  24. }
  25.  
  26. void Inicializacion_Leds(void){
  27. P1SEL |= (BIT2 | BIT3); // alternative function for leds
  28. P1DIR |= (BIT2 | BIT3); // LEDs as outputs
  29. }
  30.  
  31. void TimerA0_PWM(void){
  32. TA0CCR0 = 2000-1; // Tperíodo del PWM: 2000 milisegundos
  33. TA0CCTL1 |= OUTMOD_3; // Modo CCR1: Set/Reset.
  34. TA0CCR1 = 0; // Duty Cycle inicial: 0%
  35. TA0CCTL2 |= OUTMOD_3; // Modo CCR1: Set/Reset.
  36. TA0CCR2 = 0; // Duty Cycle inicial: 0%
  37. TA0CTL |= TASSEL_2 | ID_3 | MC_1 | TACLR; // Reloj SMCLK, Frecuencia: 16 MHz. Modo Up. Preescalador: 8
  38. }
  39.  
  40. // Funcion para configurar el ADC:
  41.  
  42. void ConfiguracionADC(void){
  43. P6SEL |= BIT0 | BIT1; // to use P6.0 y P6.1 as entries of channel A0 and A1
  44. ADC12CTL0 |= ADC12SHT0_5 | ADC12MSC | ADC12ON; // ADC12ON: Activamos el ADC; ADC12SHT0_5: 64 ciclos de muestreo del S & H
  45. ADC12CTL1 |= ADC12SSEL_3 | ADC12DIV_7 | ADC12CONSEQ_3 | ADC12SHP; // ADC12SSEL_3: SMCLK; ADC12DIV_7: Preescalador de 8; ADC12CONSEQ_3: Multiples samples in multiple channels
  46. ADC12MCTL0 |= ADC12SREF_0 | ADC12INCH_0; // ADC12SREF_0: VR+ = AVcc+ and VR- = AVss ; ADC12INCH_0: Channel A0
  47. ADC12MCTL1 |= ADC12SREF_0 | ADC12INCH_1 | ADC12EOS; // ADC12INCH_1: Channel A1; ADC12EOS: end of sequence
  48. __delay_cycles(30); // wait for stabilize of voltage reference
  49. ADC12CTL0 |= ADC12ENC; // ADC12ENC: enable conversion
  50. ADC12IE |= BIT1; // enable ADC12IFG.1
  51. }
  52.  
  53. void main(void){
  54. uint8_t cont; // Variable to iterate in the array
  55. uint16_t value1,value2;
  56. WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
  57. Inicializacion_Relojes();
  58. Inicializacion_Leds();
  59. TimerA0_PWM();
  60. ConfiguracionADC();
  61. __enable_interrupt();
  62. while(1){
  63. if(end_conversion == 1){ // if the conversion has finished
  64. ADC12CTL0 |= ADC12SC; // ADC12SC: you can start over another conversion
  65. end_conversion = 0;
  66. }
  67. if (buffer_lleno == 1){
  68. for(cont=0; cont<8; cont++){
  69. valor_promedio_A0 += adc_A0[cont];
  70. valor_promedio_A1 += adc_A1[cont];
  71. }
  72. valor_promedio_A0 >>= 3; // to divide by 8 (3 bits shift to the right)
  73. valor_promedio_A1 >>= 3;
  74. value1 = (TA0CCR0*(valor_promedio_A0))/(4096);
  75. TA0CCR1 = value1;
  76. value2 = (TA0CCR0*(valor_promedio_A1))/(4096);
  77. TA0CCR2 = value2;
  78. valor_promedio_A0 = 0; // Reset value of A0
  79. valor_promedio_A1 = 0; // Reset value of A0
  80. buffer_lleno = 0;
  81. end_conversion = 1;
  82. }
  83. }
  84. }
  85.  
  86. #pragma vector = ADC12_VECTOR
  87. __interrupt void ADC12_ISR (void)
  88. {
  89. static unsigned int index = 0;
  90. switch(__even_in_range(ADC12IV,34))
  91. {
  92. case 0: break; // Vector 0: No interrupt
  93. case 2: break; // Vector 2: ADC overflow
  94. case 4: break; // Vector 4: ADC timing overflow
  95. case 6: break;
  96. case 8: // Vector 8: ADC12IFG1
  97. adc_A0[index] = ADC12MEM0;
  98. adc_A1[index] = ADC12MEM1;
  99. index++;
  100. if (index == 8){
  101. buffer_lleno = 1;
  102. index = 0;
  103. ADC12CTL0 &= ~ADC12SC;
  104. end_conversion = 0;
  105. }
  106. else{
  107. end_conversion = 1;
  108. }
  109.  
  110. case 10: break; // Vector 10: ADC12IFG2
  111. case 12: break; // Vector 12: ADC12IFG3
  112. case 14: break; // Vector 14: ADC12IFG4
  113. case 16: break; // Vector 16: ADC12IFG5
  114. case 18: break; // Vector 18: ADC12IFG6
  115. case 20: break; // Vector 20: ADC12IFG7
  116. case 22: break; // Vector 22: ADC12IFG8
  117. case 24: break; // Vector 24: ADC12IFG9
  118. case 26: break; // Vector 26: ADC12IFG10
  119. case 28: break; // Vector 28: ADC12IFG11
  120. case 30: break; // Vector 30: ADC12IFG12
  121. case 32: break; // Vector 32: ADC12IFG13
  122. case 34: break; // Vector 34: ADC12IFG14
  123. default: break;
  124. }
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement