PIC 16F873
CONVERSIÓN A/D Y
TRANSMISIÓN POR PUERTO
SERIE
• Alvaro Fernández Casaní
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
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
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
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
PIC 16F873 - Conversor A/D
• 4 registros básicos:
– 2 registros configuración:
• ADCON0
• ADCON1
– 2 registros datos: ADRESH y ADRESL
PIC 16F873 - Conversor A/D
• ADQUISICION DE DATOS:
– 1) Programación del conversor A/D:
• Programar Frecuencia de Adquisición (ADCON0 - bits ADCS0 y ADCS1):
Fosc/2
Fosc/8
Fosc/32
FRC
(00)
(01)
(10)
(11)
• Seleccionar canal de entrada (ADCON0 - bits CHS0, CHS1, CHS2)
– Canal 0 (000) ... Canal 7 (111)
PIC 16F873 - Conversor A/D
• 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
• 2) Para cada dato a adquirir:
• Empezar la conversion (ADCON0 - bit GO-DONE)
• Comprobar la conversion:
– por polling (comprobar ADCON0 - bit GO-DONE)
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
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
PIC 16F873 - Interfaz Serie
DIAGRAMA DEL BLOQUE DE TRANSMISION
PIC 16F873 - Interfaz Serie
• PROGRAMACION:
– 1) Inicializar registro del Generador de baudios
(SPBRG) y el bit de alta velocidad si necesario
(BRGH)
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
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
CODIGO PIC - MAIN
PROGRAMA PRINCIPAL
// Programa principal
main(){
// Configurar modulo AD
initialice_ad();
// Configurar comunicacion serie
serial_port_configure();
while(1){
//Empezar conversion
begin_conversion();
//mandar datos
send_data();
}
CODIGO PIC - INITIALICE_AD
initialice_ad(){
//TRISA
asm bsf TRISA,7
// 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
// 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
}
CODIGO PIC - SERIAL_PORT
void 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 mode
asm bcf TXSTA,SYNC
//Serial port enable
//Pasamos al banco 0 (00)
asm bcf STATUS, RP1
asm bcf STATUS, RP0
asm bsf RCSTA,SPEN
//enable trasnmit
//Pasamos al banco 1 (01)
asm bcf STATUS, RP1
asm bsf STATUS, RP0
asm bsf TXSTA,TXEN
}
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
}
}
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 transmitted
delay_ms(10);
//Pasamos al banco 1 (01)
asm bcf STATUS, RP1
asm bsf STATUS, RP0
asm movf ADRESL, W
//Pasamos al banco 0 (00)
asm bcf STATUS, RP1
asm bcf STATUS, RP0
asm movwf TXREG
//wait until transmitted
delay_ms(10);
}
CODIGO PC - PROGRAMA PRINCIPAL
void 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;
}
while(1){
recibido = Recibe_un_caracter();
if (recibido == 'v'){
//Recibimos parte alta
alta = 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
printf("Preparado para recibir datos...\n");
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;
}
Descargar

PIC 16F873 CONVERSIÓN A/D Y TRANSMISIÓN POR PUERTO