Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

22
PIC 16F873 CONVERSIÓN A/D Y TRANSMISIÓN POR PUERTO SERIE Alvaro Fernández Casaní

Transcript of Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

Page 1: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873CONVERSIÓN A/D Y

TRANSMISIÓN POR PUERTO SERIE

• Alvaro Fernández Casaní

Page 2: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

OBJETIVOS

• Utilizar PIC para la adquisición de datos analógicos y conversión a digital

• Transmisión por puerto serie de los datos

• Posterior análisis de datos en el PC

Page 3: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

MEDIOS A UTILIZAR

• Microchip 16F873 – convertidor A/D– controlador Puerto Serie

• PCB diseñado para alojar el 16F873 y módulos requeridos

• código diseñado para conseguir los objetivos, PC y conexiones

Page 4: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873• CPU RISC• juego de 35 instrucciones• 28 pins• FLASH: 8K x 14 words• RAM: 368 x 8 bytes• EEPROM: 256 x 8 bytes• Conversor A/D de 10 bits

multicanal• Puerto Serie

multifuncional

Page 5: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873 - Conversor A/D

• Hasta 5 canales de entrada

• Conversión por método de aproximaciones sucesivas

• 10 bits de resolución

• Voltaje alto y bajo de referencia seleccionable por software

• Posibilidad de ejecución en modo SLEEP

Page 6: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873 - Conversor A/D

• 4 registros básicos:– 2 registros configuración:

• ADCON0

• ADCON1

– 2 registros datos: ADRESH y ADRESL

Page 7: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

• ADQUISICION DE DATOS:– 1) Programación del conversor A/D:

• Programar Frecuencia de Adquisición (ADCON0 - bits ADCS0 y ADCS1):

Fosc/2 (00)Fosc/8 (01)

Fosc/32 (10)FRC (11)

• Seleccionar canal de entrada (ADCON0 - bits CHS0, CHS1, CHS2)

– Canal 0 (000) ... Canal 7 (111)

PIC 16F873 - Conversor A/D

Page 8: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

• Configurar Pines, voltaje referencia, ... (ADCON1 - bits PCFG0, PCFG1,

PCFG2, PCFG3):

• Configurar bit de Resultado (ADCON1 - bit ADFM )

• Habilitar el modulo conversor (ADCON0 - bit ADON )

PIC 16F873 - Conversor A/D

Page 9: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873 - Conversor A/D

• 2) Para cada dato a adquirir:

• Empezar la conversion (ADCON0 - bit GO-DONE)

• Comprobar la conversion: – por polling (comprobar ADCON0 - bit GO-DONE)

Page 10: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873 - Interfaz Serie

• Posibilidad de configuración para comunicación:– full-duplex asíncrona.– Sincrona como Master– Síncrona como Slave

• Utilizaremos el modo asíncrono

Page 11: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873 - Interfaz Serie

• MODO ASINCRONO:– codificación standard NRZ– formato standard de 8 bits ( configurable )– se transmite primero el bit LSB– paridad no soportada por HW pero puede

calcularse por SW y almacenarse en bit 9

Page 12: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873 - Interfaz Serie

DIAGRAMA DEL BLOQUE DE TRANSMISION

Page 13: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

• PROGRAMACION:– 1) Inicializar registro del Generador de baudios

(SPBRG) y el bit de alta velocidad si necesario (BRGH)

PIC 16F873 - Interfaz Serie

Page 14: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873 - Interfaz Serie

– 2) Modo Asíncrono• Clear bit SYNC

– 3) Habilitar puerto serie• Set bit SPEN

– 4) Interrupciones habilitadas• Set bit TXIE

– 5) Si se quiere 9º bit de datos• Set bit TX9

Page 15: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

PIC 16F873 - Interfaz Serie

– 6 ) Habilitar transmision• Set bit TXEN (habilita el bit TXIF)

– 7) Si se ha seleccionado 9º bit• Cargar bit en TX9D

– 8) Cargar el registro TXREG con los datos:• empieza automáticamente la transmisión

Page 16: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

CODIGO PIC - MAIN

// Programa principal

main(){

// Configurar modulo AD

initialice_ad();

// Configurar comunicacion serie

serial_port_configure();

while(1){

//Empezar conversion

begin_conversion();

//mandar datos

send_data();

}

PROGRAMA PRINCIPAL

Page 17: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

CODIGO PIC - INITIALICE_ADinitialice_ad(){

// Configuracion del modulo AD

//ADCON0 (bank 0)

//set_bit( ADCS0,1); // Frecuencia de adquisicion

//set_bit( ADCS1,0);

asm bsf ADCON0,ADCS0

asm bcf ADCON0,ADCS1

//set_bit( ADFM,0); // Canal de entrada

//set_bit( ADFM,0);

//set_bit( ADFM,0);

asm bcf ADCON0,CHS2

asm bcf ADCON0,CHS1

asm bcf ADCON0,CHS0

//ADCON1

//Pasamos al banco 1 (01)

asm bcf STATUS, RP1

asm bsf STATUS, RP0

//TRISA asm bsf TRISA,7 // Configuracion de los pines//set_bit( PCFG3,0); //set_bit( PCFG2,0); //set_bit( PCFG1,0); //set_bit( PCFG0,1); //Utilizar 0000 (V+ = Vdd; V- = Vss) asm bcf ADCON1,PCFG3 asm bcf ADCON1,PCFG2 asm bcf ADCON1,PCFG1 asm bcf ADCON1,PCFG0 //set_bit( ADFM,1); // datos en los 10 bits de menos peso asm bsf ADCON1,ADFM // Finalmente Habilitamos modulo AD //Pasamos al banco 0 (00) asm bcf STATUS, RP0 asm bcf STATUS, RP1 //Habilitamos asm bsf ADCON0, ADON }

Page 18: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

CODIGO PIC - SERIAL_PORTvoid serial_port_configure(){

//Pasamos al banco 1 (01)

asm bcf STATUS, RP1

asm bsf STATUS, RP0

//configure pins 6,7

asm bsf TRISC,6

asm bsf TRISC,7

// Baud generator (9600) on

//I suppose fosc=4Mhz

// fosc=4Mhz --> SPBRG=25

// fosc=20Mhz --> SPBRG=129

// y BRGH=1

asm movlw D'25'

asm movwf SPBRG

asm bsf TXSTA,BRGH

//asyncronous modeasm bcf TXSTA,SYNC

//Serial port enable//Pasamos al banco 0 (00)asm bcf STATUS, RP1asm bcf STATUS, RP0asm bsf RCSTA,SPEN

//enable trasnmit//Pasamos al banco 1 (01)asm bcf STATUS, RP1asm bsf STATUS, RP0asm bsf TXSTA,TXEN

}

Page 19: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

CODIGO PIC - BEGIN_CONVERSION

begin_conversion(){

//Pasamos al banco 0 (00)

asm bcf STATUS, RP0

asm bcf STATUS, RP1

//empezamos la conversion

asm bsf ADCON0, GO_DONE

//tenemos que esperar a que se haya acabado la conversion

//while (ADCON0 & 0x04) bit GO/DONE

//b=0x04;

asm movf ADCON0, W

asm movwf _b

while ((b & 0x04) == 0x04 ){

asm movf ADCON0, W

asm movwf _b

}

}

Page 20: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

CODIGO PIC - SEND_DATA

void send_data(){

// load register with data

//Pasamos al banco 0 (00)

asm bcf STATUS, RP1

asm bcf STATUS, RP0

// Inicio de los datos

// transmitimos una "v" ( decimal ->118)

asm movlw D'118'

asm movwf TXREG

delay_ms(10);

//transmitimos primero el byte alto y después el bajo

//Pasamos al banco 0 (00)

asm bcf STATUS, RP1

asm bcf STATUS, RP0

asm movf ADRESH, W

asm movwf TXREG

//wait until transmitteddelay_ms(10);

//Pasamos al banco 1 (01)asm bcf STATUS, RP1asm bsf STATUS, RP0 asm movf ADRESL, W

//Pasamos al banco 0 (00)asm bcf STATUS, RP1asm bcf STATUS, RP0asm movwf TXREG

//wait until transmitteddelay_ms(10);

}

Page 21: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

CODIGO PC - PROGRAMA PRINCIPALvoid main(){

int i,j;

char recibido;

unsigned char alta,baja;

int dato;

int v_low, v_high;

Inicializa_Comunicaciones(1,9600);

printf("Introduce Referencia V- :");

scanf("%d",&v_low);

printf("Introduce Referencia V+ :");

scanf("%d",&v_high);

printf("introducida V- = %d\n",v_low);

printf("introducida V+ = %d\n",v_high);

if (v_low>v_high){

printf("ERROR: Valores incorrectos\n");

return;

}

printf("Preparado para recibir datos...\n");

while(1){

recibido = Recibe_un_caracter();

if (recibido == 'v'){//Recibimos parte altaalta = Recibe_un_caracter();baja = Recibe_un_caracter();

dato = ((alta) << 8 ) + baja;printf("Dato recibido = %d \n",dato);printf("Dato convertido = %f \n",

convierte_dato(dato, v_low, v_high));

}

}//while

}//main

Page 22: Pic16f873 - Conversion Ad y Transmision Por Puerto Serie

CODIGO PC - CONVERTIDOR

float convierte_dato(int dato, float low, float high){

float intervalo,margen;

float result;

intervalo = high - low;

//printf("convierte: intervalo=%f\n",intervalo);

// 2^10 = 1024

margen = (intervalo / (1024));

//printf("convierte: margen=%f\n",margen);

result = low + margen*dato;

//printf("convierte: resultado=%f\n",result);

return result;

}