Inicio > PIC > Comunicacion SPI entre un CAD MCP3204 y un pic 18F4550

Comunicacion SPI entre un CAD MCP3204 y un pic 18F4550

En este ejercicio vamos a realizar un estudio de comunicacion SPI entre un Convertidor Analogico/Digital MCP3204 y el pic 18F4550.


Para comprender el funcionamiento del periferico lo primero que debemos  hacer es mirar el libro de caracteristicas del MCP3204. Como podemos observar en el documento nuestro componente cuenta con 14 patillas a diferencia del 3208 que tiene 16 para no confundirnos.

Diagrama de Bloques Funcional

Para programar el MCP3204 utilice una plantilla. Esta se encuentra en las librerías de CCS con el nombre de MCP3204.C . Este es el código necesario para controlar el MCP3204 con los pines del SPI ya definidos para funcionar en un 18F4550.

Mirando un poco en la hoja de caracteristicas podemos ver que el dispositivo puede trabajar en modo diferencia o individual, esto quiere decir que si configuramos el dispositivo para trabajar en modo diferencial tendriamos que utilizar los 4 canales y si lo hacemos en modo individual elegiriamos uno de los 4, en este caso voy a trabajar en modo individual.

La plantilla del dispositivo MCP3204 cuenta con sus propias funciones para ser controlado por el microcontrolador.

////////////////// Driver for MCP3204 A/D Converter ////////////////////////
////                                                                     ////
////  adc_init()                                                          ////
////      Call after power up                                             ////
////                                                                       ////
////  value = read_analog_mcp( channel, mode )                             ////
////      Read an analog channel                                            ////
////      0 through 3 and select                                          ////
////      differential (0) or                                             ////
////      single (1) mode                                                  ////
////                                                                       ////
////  value = read_analog( channel )                                      ////
////      Read an analog channel                                           ////
////      0 through 7 in   single mode                                        ////
////                                                                       ////
////  convert_to_volts( value,  string )                                 ////
////      Fills in string with                                             ////
////      the true voltage in                                             ////
////      the form 0.000                                                   ////
////                                                                      ////
////////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services            ////
//// This source code may only be used by licensed users of the CCS C   ////
//// compiler.  This source code may only be distributed to other       ////
//// licensed users of the CCS C compiler.  No other use, reproduction  ////
//// or distribution is permitted without written permission.           ////
//// Derivative programs created using this software in object code     ////
//// form are not restricted in any way.                                ////
////////////////////////////////////////////////////////////////////////////

#ifndef MCP3204_CS
#define MCP3204_CLK  PIN_B1
#define MCP3204_DOUT PIN_C7
#define MCP3204_DIN  PIN_B0
#define MCP3204_CS   PIN_A0
#endif

void adc_init() {
 output_high(MCP3204_CS);
}

void write_adc_byte(BYTE data_byte, BYTE number_of_bits) {
 BYTE i;

 delay_us(2);
 for(i=0; i<number_of_bits; ++i) {
 output_low(MCP3204_CLK);
 if((data_byte & 1)==0)
 output_low(MCP3204_DIN);
 else
 output_high(MCP3204_DIN);
 data_byte=data_byte>>1;
 delay_us(50);
 output_high(MCP3204_CLK);
 delay_us(50);
 }
}

BYTE read_adc_byte(BYTE number_of_bits) {
 BYTE i,data;

 data=0;
 for(i=0;i<number_of_bits;++i) {
 output_low(MCP3204_CLK);
 delay_us(50);
 shift_left(&data,1,input(MCP3204_DOUT));
 output_high(MCP3204_CLK);
 delay_us(50);
 }
 return(data);
}

long int read_analog_mcp(BYTE channel, BYTE mode) {
 int l;
 long int h;
 BYTE ctrl_bits;

 delay_us(200);

 if(mode!=0)
 mode=1;

 output_low(MCP3204_CLK);
 output_high(MCP3204_DIN);
 output_low(MCP3204_CS);

 if(channel==1)               // Change so MSB of channel #
 ctrl_bits=4;            //      is in LSB place
 else if(channel==3)
 ctrl_bits=6;
 else if(channel==4)
 ctrl_bits=1;
 else if(channel==6)
 ctrl_bits=3;
 else
 ctrl_bits=channel;

 ctrl_bits=ctrl_bits<<1;

 if(mode==1)                  // In single mode
 ctrl_bits |= 1;
 else                        // In differential mode
 ctrl_bits &= 0xfe;

 ctrl_bits=ctrl_bits<<1;      // Shift so LSB is start bit
 ctrl_bits |= 1;

 write_adc_byte( ctrl_bits, 7);   // Send the control bits

 h=read_adc_byte(4);
 l=read_adc_byte(8);

 output_high(MCP3204_CS);

 return((h<<8)|l);
}

long int read_analog( BYTE channel )   // Auto specifies single mode
{
 long int temp;

 if(channel<4)
 temp=read_analog_mcp( channel, 1);
 else
 temp=0;

 return temp;
}

void convert_to_volts( long int data, char volts[6]) {
 BYTE i, d, div_h, div_l;
 long int temp,div;

 div=4095/5;

 if(data>=4090)
 data=4095;

 for(i=0;i<=4;i++) {
 temp=data/div;

 volts[i]=(BYTE)temp+'0';

 if(i==0) {
 volts[1]='.';
 i++;
 }
 temp=div*(BYTE)temp;
 data=data-temp;
 div=div/10;
 }
 volts[i]='\0';
}

Teniendo la libreria y el patillaje del componente lo siguiente es programarlo. Utilizando lenguaje C para PIC’s y haciendo llamadas a la librería del MCP3204.

////////////////////////////////////////////////////////////////////////////////////
//   AUTOR: Trujillo Alcocer Jesus Fernando                        Febrero 2011
////////////////////////////////////////////////////////////////////////////////////
//   PROGRAMA:                                          VERSIÓN:    1.0
//   DISPOSITIVO: PIC18F4550                            COMPILADOR: CCS vs4.088
//   Entorno IDE:                                       SIMULADOR:  Proteus 7.7 sp2
//   TARJETA DE APLICACIÓN:                             DEBUGGER:
////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////
//          Comunicacion SPI entre un CAD MCP3204 y un pic 18F4550            //
////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////
// CABECERA ////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
#include <18F4550.h>
#fuses INTHS
#use delay(internal=8Mhz)
#include <LCD_flexible.c>
#include <personal_mcp3204.c>
////////////////////////////////////////////////////////////////////////////////////
// VARIABLES GLOBALES //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
long int value;
////////////////////////////////////////////////////////////////////////////////////
// FUNCIONES ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void display_data(long int data)
{
 float v;
 char volt_string[6];
 convert_to_volts(data,volt_string);
 v=data*5.0/(4096.0);
 printf(lcd_putc,"\r\r\rCAD-MCP3204 \n\r\rCanal_0: %f",v);
}
////////////////////////////////////////////////////////////////////////////////////
// PRINCIPAL ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void main()
{
 lcd_init();
 adc_init();
 while(true)
 {
 value=read_analog(0);
 display_data(value);
 }
}

 

Bits de Configuracion del MCP3204

Como podemos ver al final de la tabla, el bit de control D2 no le vamos a dar importancia en la configuracion.


Una vez terminado el diseño con proteus, lo siguiente es pasar con Ares.  Colocamos los componentes y cuando tengamos definido las medidas con las que vamos a trabajar, que caras vamos a usar, que en nuestro caso solo seran dos, la top y la bottom; Una vez definido estos puntos solo nos quedaria hacer el autorutado de las pistas y ver como queda todo el diseño en 3D.

Para programar el potenciómetro me base en una plantilla ya existente. Esta se encuentra en las librerías de CCS con el nombre de MCP41010.C en mi caso para no modificar la original la copie en otro lugar la cambie el nombre. Este es el código necesario para controlar el MCP41 con los pines del SPI ya definidos para funcionar en un 18F4550. Como se puede ver con dos simples comandos se controla el potenciómetro.
Anuncios
Categorías:PIC
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: