2012.08.21
ADC en la familia de µC S08
resumen adc (sh8) – slides (rev.09.2013 v.1.3)
Ejemplos de uso del ADC:
1. ejemplo con bandgap
/* PTA5/IRQ/TCLK/RESET (1) (20) PTA0/PIA0/TPM1CH0/ADP0/ACMP+ PTA4/ACMPO/BKGD/MS (2) (19) PTA1/PIA1/TPM2CH0/ADP1/ACMP- VDD (3) (18) PTA2/PIA2/SDA/ADP2 VSS (4) (17) PTA3/PIA3/SCL/ADP3 PTB7/SCL/EXTAL (5) (16) PTB0/PIB0/RxD/ADP4 PTB6/SDA/XTAL (6) (15) PTB1/PIB1/TxD/ADP5 PTB5/TPM1CH1/SS (7) (14) PTB2/PIB2/SPSCK/ADP6 PTB4/TPM2CH1/MISO (8) (13) PTB3/PIB3/MOSI/ADP7 PTC3/ADP11 (9) (12) PTC0/TPM1CH0/ADP8 PTC2/ADP10 (10) (11) PTC1/TPM1CH1/ADP9 */ /* * ejemplo de ADC en 9S08 (SH8) * utilizandop bandgap + máquina estados * * Si la tensión medida en pata 11 (AD9) * es mayor a 1V se enciende el LED * * Usa bandgap para independizar la medición * de la tensión de alimentación * * */ /* --- estados --- */ #define INICIO_BG 1 #define ESPERO_COCO_BG 3 #define INICIO_VI 5 #define ESPERO_COCO_VI 7 /* --- GPIO --- */ #define LED PTAD_PTAD0 #define _LED PTADD_PTADD0 void main() { unsigned int vref, vin, valor SOPT1 &= 0x3F; // habilita el uso del bandgap SPMSC1_BGBE = 1; /* --- Pin del LED como salida --- */ _LED = 1; ADCCFG = 0b01101000; // fadc = fbus / 8 = 1 MHz; 10 bits ADCSC2 = 0; APCTL2_ADPC9 = 1; // pin 9 Analógico for { switch( e ) { case INICIO_BG: // inicio conversión simple de canal 27 (bandgap) ADCSC1 = 0b00011011; e = ESPERO_COCO_BG; break; case ESPERO_COCO_BG: // si conversión completa guardo el resultado // y paso de estado if (ADCSC1_COCO == 1) { e = INICIO_VI; vref = ADCR; } break; case INICIO_VI: // inicio conversión simple de canal 9 (ADP9, pin 11) ADCSC1 = 0b00001001; e = ESPERO_COCO_VI; break; case ESPERO_COCO_VI: // si conversión completa guardo el resultado // y paso de estado if (ADCSC1_COCO == 1) { e = INICIO_BG; vi = ADCR; // calculo la tension // vref corresponde al valor de conversión resultante // de medir la referencia interna (bandgap) de 1.2V // vin corresponde al valor de conversión resultante // de medir la pata de entrada (pin 11) // // Si: // vref ------ 1.2V // vin ------ ???? // // valor = 1.2 / vref * vin; // // Para usar solo enteros, calculo en mV valor = (1200 * vin) / vref; } break; } } }
2. ejemplo de adquisición de dos variables analógicas
/* * ejemplo de ADC en 9S08 (SH8) * * Si la tensión ViA presente en pata 9 (ADP11) es mayor que la ViB en * pata 17 (ADP3) se enciende un LED verde conectado en pata 16 (PTB0) * En caso contrario se enciende un LED rojo conectado en pata 15 (PTB1) * */ /* PTA5/IRQ/TCLK/RESET (1) (20) PTA0/PIA0/TPM1CH0/ADP0/ACMP+ PTA4/ACMPO/BKGD/MS (2) (19) PTA1/PIA1/TPM2CH0/ADP1/ACMP- VDD (3) (18) PTA2/PIA2/SDA/ADP2 VSS (4) (17) PTA3/PIA3/SCL/ADP3 <-- ViB PTB7/SCL/EXTAL (5) (16) PTB0/PIB0/RxD/ADP4 --> LED Verde PTB6/SDA/XTAL (6) (15) PTB1/PIB1/TxD/ADP5 --> LED Rojo PTB5/TPM1CH1/SS (7) (14) PTB2/PIB2/SPSCK/ADP6 PTB4/TPM2CH1/MISO (8) (13) PTB3/PIB3/MOSI/ADP7 ViA ---> PTC3/ADP11 (9) (12) PTC0/TPM1CH0/ADP8 PTC2/ADP10 (10) (11) PTC1/TPM1CH1/ADP9 */ #define SALIDA 1 #define ENCENDIDO 1 /* --- estados --- */ #define INICIO_ViA 1 #define ESPERO_COCO_ViA 3 #define INICIO_ViB 5 #define ESPERO_COCO_ViB 7 #define LEDS 9 /* --- LEDS --- */ #define LED_VERDE PTBD_PTBD0 #define _LED_VERDE PTBDD_PTDD0 #define LED_ROJO PTBD_PTBD1 #define _LED_ROJO PTBDD_PTBDD1 unsigned int resultado_ViA, resultado_ViB; void main() { /* --- Pin del LED como salida --- */ _LED_VERDE = SALIDA; _LED_ROJO = SALIDA; /* --- configuracion del ADC --- */ ADCCFG = 0b01101000; // fadc = fbus / 8 = 1 MHz; 10 bits ADCSC2 = 0; APCTL2_ADPC11 = 1; // pin 9 Analógico (ADP11) APCTL1_ADPC3 = 1; // pin 17 Analógico (ADP3) for { switch( e ) { case INICIO_ViA: // inicio conversión simple ViA (ADP11, pin 9) ADCSC1 = 0b00001011; e = ESPERO_COCO_ViA; break; case ESPERO_COCO_ViA: // si conversión completa guardo el resultado // y paso de estado if (ADCSC1_COCO == 1) { resultado_ViA = ADCR; e = INICIO_ViB; } break; case INICIO_ViB: // inicio conversión simple ViB (ADP3, pin 17) ADCSC1 = 0b00000011; e = ESPERO_COCO_ViB; break; case ESPERO_COCO_ViB: // si conversión completa guardo el resultado // y paso de estado if (ADCSC1_COCO == 1) { resultado_ViB = ADCR; e = LEDS; } break; case LEDS: if (resultado_ViA > resultado_ViB) { LED_VERDE = ENCENDIDO; LED_ROJO = !ENCENDIDO; } else { LED_ROJO = ENCENDIDO; LED_VERDE = !ENCENDIDO; } e = INICIO_ViA; } } }