Hola a todos de nuevo, esta práctica que os voy a mostrar a
continuación es realmente parte de una práctica anterior, se trata de crear un
conversor AD, así como cuando hicimos el LCD gráfico, sin embargo esta vez tengo
que diseñar la placa, mediante el soporte que nos deja proteus llamado “ARES”.
Lo que haremos será, mediante el PIC18F4550 (tenéis su
datasheet en la biblioteca) conectar un conversor AD, concretamente el MCP3204
(también en biblioteca) mediante el SPI.
Para el
control del MCP3204 haremos como con los LCD, utilizaremos una Librería ya
creada, la cual os adjunto aquí, también vamos a usar un LCD alfanumérico, así
que también os adjunto la librería de éste:
Librería
del MCP3204:
////////////////// 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
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
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.00;
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';
}
Seguidamente la librería para el
control del LCD:
//
flex_lcd.c
// These
pins are for the Microchip PicDem2-Plus board,
// which is
what I used to test the driver. Change
these
// pins to
fit your own board.
#define
LCD_DB4 PIN_D4
#define
LCD_DB5 PIN_D5
#define
LCD_DB6 PIN_D6
#define
LCD_DB7 PIN_D7
//
#define
LCD_RS PIN_D0
#define
LCD_RW PIN_D1
#define
LCD_E PIN_D2
// If you
only want a 6-pin interface to your LCD, then
// connect
the R/W pin on the LCD to ground, and comment
// out the
following line.
#define
USE_LCD_RW 1
//========================================
#define
lcd_type 2 // 0=5x7, 1=5x10, 2=2
lines
#define
lcd_line_two 0x40 // LCD RAM address for the 2nd line
int8 const
LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set:
4-bit, 2 lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void
lcd_send_nibble(int8 nibble)
{
//
Note: !! converts an integer expression
// to a
boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//-----------------------------------
// This
sub-routine is only called by lcd_read_byte().
// It's not
a stand-alone routine. For example, the
// R/W
signal is set high by lcd_read_byte() before
// this
routine is called.
#ifdef
USE_LCD_RW
int8
lcd_read_nibble(void)
{
int8
retval;
// Create
bit variables so that we can easily set
//
individual bits in the retval variable.
#bit
retval_0 = retval.0
#bit
retval_1 = retval.1
#bit
retval_2 = retval.2
#bit
retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_cycles(1);
retval_0 =
input(LCD_DB4);
retval_1 =
input(LCD_DB5);
retval_2 =
input(LCD_DB6);
retval_3 =
input(LCD_DB7);
output_low(LCD_E);
return(retval);
}
#endif
//---------------------------------------
// Read a
byte from the LCD and return it.
#ifdef
USE_LCD_RW
int8
lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high =
lcd_read_nibble();
low =
lcd_read_nibble();
return(
(high<<4) | low);
}
#endif
//----------------------------------------
// Send a
byte to the LCD.
void
lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef
USE_LCD_RW
while(bit_test(lcd_read_byte(),7))
;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef
USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n
>> 4);
lcd_send_nibble(n
& 0xf);
}
//----------------------------
void
lcd_init(void)
{
int8 i;
output_low(LCD_RS);
#ifdef
USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15);
for(i=0 ;i
< 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i
< sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}
}
//----------------------------
void
lcd_gotoxy(int8 x, int8 y)
{
int8
address;
if(y != 1)
address = lcd_line_two;
else
address=0;
address +=
x-1;
lcd_send_byte(0,
0x80 | address);
}
//-----------------------------
void
lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1,2);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef
USE_LCD_RW
char
lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait
until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value =
lcd_read_byte();
output_low(lcd_RS);
return(value);
}
#endif
void
lcd_setcursor_vb(short visible, short blink) {
lcd_send_byte(0,
0xC|(visible<<1)|blink);
}
Este sería el programa principal
Este sería el programa principal
////////////////////////////////////////////////////////////////////////////////////
// AUTOR: GABI ENERO/2012
////////////////////////////////////////////////////////////////////////////////////
// PROGRAMA: Conversor AD CON MCP3204 VERSIÓN: 1.0
// DISPOSITIVO: PIC 18F4550 COMPILADOR: CCSC
// Entorno IDE: MPLAB SIMULADOR: Proteus 7
// TARJETA DE APLICACIÓN: ___ DEBUGGER: ICD3
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//
//
// CREAR UN Conversor ad, mediante una conexión con MCP3204 y proyecto en ares. ///////
//
//////////////////////////////////////////////////////////////////////////////////
#include
#fuses INTHS //oscilador interno
//#FUSES HS //no usamos oscilador externo
#FUSES MCLR //Master clear activado
#use delay(internal=4000000hz) // Selecciona la velocidad del oscilador interno
#include
#include
////////////////////////////////////////////////////////////////////////////////////
// VARIABLES GLOBALES //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
float voltios;
char cad[6];
float val;
////////////////////////////////////////////////////////////////////////////////////
// PRINCIPAL ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void main()
{
lcd_init(); //iniciamos el LCD y el cAD
adc_init();
for(;;)
{
val=read_analog(0); //lectura del AD
DELAY_MS(50);
lcd_gotoxy(1,1); //centramos el LCD
convert_to_volts( val,cad ); //hacemos la conver
printf(lcd_putc," %s Voltios",string);
lcd_gotoxy(1,2);
printf(lcd_putc,"Gabi");
DELAY_MS(150);
}
}
Como ya os dije al principio, la cosa no acaba aquí, ahora es el momento de crear una "maqueta 3D", mediante el soporte de ARES. Para eso primero tenemos que realizar un proyecto en isis que debe contener lo siguiente
Una vez tengamos todos estos componentes bien colocados,
será el momento de pasar al ARES, para eso tendremos que ir a la aprte superior
del soporte, en la ventana que os adjunto aquí.
Entonces nos tendrá que salir un entorno como este.
Es la primera vez que uso ARES, parece un soporte bastante
más sencillo que el Layout de capturo, de hecho se parece bastante. Precisamente
por eso voy a procurar “resumir” todo en los pasos más importantes.
Una vez entremos en el entorno, empezaremos por colocar el
borde de nuestro proyecto. Es muy sencillo, solo tenemos que irnos a “2d
graphics box mod” en la parte izquierda, como os muestro en la imagen.
Importante, teneis que tener en cuente en qué capa estáis
trabajando, nosotros necesitamos hacerlo en “board edge”, para seleccionarla
tenemos que, tras haber dado al 2d graphics, abajo a la izquierda nos saldrá
una ventana con las capas. Necesitamos seleccionar “board edge” que está en
amarillo.
Tras esto
trazaremos nuestro borde.
El segundo paso será coger los componentes, esto es igual
que con el proteus, primero vamos a la parte izquierda en la barra de
herramientas y pulsamos éste botón.
Entonces nos irá pidiendo el nombre del componente, y sus
encapsulados, recordad que tendréis que haberlos metido antes de pasar al ares,
desde proteus. Sino no os saldrán.
Este sería un boceto de la colocación de los componentes.
Ahora vamos a una de las cuestiones más importantes, las
medidas de las nets y los drills, esto que nos dio grandes quebraderos de
cabeza en layout. Aunque he de decir que en ARES está todo más concurrido y
bastante más claro, resulta más “casual” por decirlo de alguna manera.
Para eso tenemos que irnos a la función de la barra superior
de herramientas que dice “design rule manager”. Que os muestro a continuación.
Nos saldrá una ventana como esta.
Por consejo de mis amigos lo he dejado tal y como está, al
parecer “T40” significa una broca de
1mm.
Y por otro lado, es importante saber que vamos a utilizar
dos capas, la top (superior) y la bottton( inferior), podemos elegir el color
de cada una etc. Una vez terminado esto, le daremos a OK y ya estaremos listos
para comenzar a rutar.
Como pasaba con el Layout, existían 2 maneras de hacer los
ruteos, por un lado de manera automática y por el otro de manera manual, cada
uno tiene sus desventajas y ventajas, nosotros vamos a optar por la automática,
ya que no queremos hacer un proyecto final, sino una práctica. Para eso nos
vamos a la parte superior de la barra de herramientas y le damos a “Auto –
router”.
Este sería el trabajo finalizado.
Ya para ultimar el proyecto es importante añadir un plano de
masa, es muy sencillo, tan solo tenemos que irnos a “tools/ power plane
Generator”, seleccionamos el color y demás y ya la tenemos colocada.
Ares también tiene una función de 3D, para eso solo tenemos
que ir a “output/ 3d visualization”, y ahí nos aparecería nuestro layout en 3
dimensiones, podemos mover la cámara con el ratón, y hacer zoom con la rueda. Aquí os pongo un vídeo para que lo veais mejor.
Espero que os haya gustado esta entrada, un saludo y nos
vemos!
DESCARGAR PROYECTO AQUÍ
No hay comentarios:
Publicar un comentario