PIC 16F873 CONVERSI�N A/D Y TRANSMISI�N POR PUERTO SERIE by HC120104164428

VIEWS: 118 PAGES: 22

									      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      (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
 • 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
                                                    // Configuracion de los pines
                                                    //set_bit( PCFG3,0);
//ADCON0 (bank 0)
                                                    //set_bit( PCFG2,0);
                                                    //set_bit( PCFG1,0);
//set_bit( ADCS0,1); // Frecuencia de adquisicion   //set_bit( PCFG0,1);
//set_bit( ADCS1,0);
asm bsf ADCON0,ADCS0                                //Utilizar 0000 (V+ = Vdd; V- = Vss)
                                                    asm bcf ADCON1,PCFG3
asm bcf ADCON0,ADCS1
                                                    asm bcf ADCON1,PCFG2
                                                    asm bcf ADCON1,PCFG1
//set_bit( ADFM,0); // Canal de entrada             asm bcf ADCON1,PCFG0
//set_bit( ADFM,0);
//set_bit( ADFM,0);                                 //set_bit( ADFM,1); // datos en los 10 bits de menos
                                                    peso
asm bcf ADCON0,CHS2
                                                    asm bsf ADCON1,ADFM
asm bcf ADCON0,CHS1
asm bcf ADCON0,CHS0
                                                    // Finalmente Habilitamos modulo AD
//ADCON1                                            //Pasamos al banco 0 (00)
                                                    asm bcf STATUS, RP0
//Pasamos al banco 1 (01)
                                                    asm bcf STATUS, RP1
asm bcf STATUS, RP1                                 //Habilitamos
asm bsf STATUS, RP0                                 asm bsf ADCON0, ADON              }
              CODIGO PIC - SERIAL_PORT
void serial_port_configure(){

//Pasamos al banco 1 (01)       //asyncronous mode
                                asm bcf TXSTA,SYNC
asm bcf STATUS, RP1
asm bsf STATUS, RP0             //Serial port enable
                                //Pasamos al banco 0 (00)
//configure pins 6,7            asm bcf STATUS, RP1
asm bsf TRISC,6                 asm bcf STATUS, RP0
                                asm bsf RCSTA,SPEN
asm bsf TRISC,7
                                //enable trasnmit
// Baud generator (9600) on     //Pasamos al banco 1 (01)
//I suppose fosc=4Mhz           asm bcf STATUS, RP1
// fosc=4Mhz --> SPBRG=25       asm bsf STATUS, RP0
                                asm bsf TXSTA,TXEN
// fosc=20Mhz --> SPBRG=129
// y BRGH=1
asm movlw D'25'                 }
asm movwf SPBRG
asm bsf TXSTA,BRGH
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)                               //wait until transmitted
                                                        delay_ms(10);
asm bcf STATUS, RP1
asm bcf STATUS, RP0                                     //Pasamos al banco 1 (01)
                                                        asm bcf STATUS, RP1
// Inicio de los datos                                  asm bsf STATUS, RP0
// transmitimos una "v" ( decimal ->118)                asm movf ADRESL, W
asm movlw D'118'
                                                        //Pasamos al banco 0 (00)
asm movwf TXREG                                         asm bcf STATUS, RP1
delay_ms(10);                                           asm bcf STATUS, RP0
                                                        asm movwf TXREG
//transmitimos primero el byte alto y después el bajo
                                                        //wait until transmitted
//Pasamos al banco 0 (00)
                                                        delay_ms(10);
asm bcf STATUS, RP1
asm bcf STATUS, RP0
asm movf ADRESH, W                                      }
asm movwf TXREG
     CODIGO PC - PROGRAMA PRINCIPAL
void main(){
int i,j;
char recibido;
unsigned char alta,baja;
int dato;                                       while(1){
int v_low, v_high;
                                                recibido = Recibe_un_caracter();

Inicializa_Comunicaciones(1,9600);              if (recibido == 'v'){
                                                                //Recibimos parte alta
printf("Introduce Referencia V- :");                            alta = Recibe_un_caracter();
                                                                baja = Recibe_un_caracter();
scanf("%d",&v_low);
printf("Introduce Referencia V+ :");                          dato = ((alta) << 8 ) + baja;
scanf("%d",&v_high);                                          printf("Dato recibido = %d \n",dato);
printf("introducida V- = %d\n",v_low);                        printf("Dato convertido = %f \n",
printf("introducida V+ = %d\n",v_high);                                       convierte_dato(dato, v_low, v_high));


if (v_low>v_high){                                            }
      printf("ERROR: Valores incorrectos\n");
      return;                                   }//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;

   }

								
To top