TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: PabloFiscella en 28 de Noviembre de 2003, 14:18:00
-
Hola a todos:
Tenia la idea de hacer una especie de voltimetro tomando un dato del exterior.
Y solo me muestra 0 o 5 como si no hiciera la conversion.
Si por ejemplo le mando 1,5v o 3v muestra en el display 5
Me podrian decir si hay algo mal en el codigo.
Muchas gracias.
Pablo
#include <16F874.h>
byte CONST Display[] = {0xC0,0x79,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
#use delay(clock=4000000)
#fuses XT,NOWDT
void main(void) {
int value;
set_tris_a(0xFF);
set_tris_b(0x0);
output_b(Display[0]);
delay_ms(500);
setup_adc_ports( ALL_ANALOG );
setup_adc(ADC_CLOCK_INTERNAL );
set_adc_channel(0);
for(;
{
value = read_adc();
if((value<=1)) {
output_b(Display[0]);
}else if((value>1) && (value<2)) {
output_b(Display[1]);
}else if((value>=2) && (value<3)) {
output_b(Display[2]);
}else if((value>=3) && (value<4)) {
output_b(Display[3]);
}else if((value>=4) && (value<5)) {
output_b(Display[4]);
}else if(value>=5) {
output_b(Display[5]);
}
delay_ms(10);
}
}
-
Hay un "for" por ahí con un careto al lado. Esto ¿no debiera ser un while?
Para mandar caracteres a la LCD te recomiendo la función printf(LCD_PUTC,...)
En ejemplos para simular del subforo SIMULADORES habían varios ejemplos de manejo de LCD en lenguaje C.
Un saludo
-
Tu fallo está en las comparaciones del registro value.
El 874 tiene el ADC de 10bits. Estuve mirando en CCS lo de configurar el ADC y no encontré nada de eso de justificar los registro de salida a la izquierda o a la derecha. Bueno supongamos que la salida que te dá es de 8bits. Pues entonces tienes 256 combinaciones. La "00000000B" sería para 0 voltios y "11111111B" sería para 5v (más bien para 5-1LSB para una Vref=5V). Ahora debes calcular lo que corresponde con cada valor que quieres mostrar.
Mas o menos es:
Para 0-> 0
Para 1->51
Para 2->102
Para 3->153
Para 4->204
Para 5->255 (en realidad son 4,98... por lo que te comenté antes)
Lo he simulado en proteus y por lo que veo el CCS da una resolución de 8bits. Me equivico?? Y si quiero los 10 bits que?
Aquí está todo:
http://miarroba.com/foros/ver.php?foroid=132139&temaid=1260114
Saludos!
-
Mil gracias.
El Lunes lo pruebo y te comento.
Saludos.
Pablo
-
Si quieres leer los 10 bits debes bajar los dos bytes del ADC, el alto y el bajo.
No vi la rutina del conversor A/D del CCS, pero es asi en assembler.
Si pones aqui la rutina la desculamos...
-
Ya...
El problema es que en el CCS no están disponibles esas librerías (ADC, timer, Comparadores, I2C...) Las genera el propio programa. Sólo se dispone de las cabeceras de estas explicandote los parametros a meter y los que devuelve. Por lo que no se pueden modificar.
Al menos eso creo... Busqué en su día la de I2C no la encontré.
Saludos!
-
A ver, vamos por partes, como dijo Jack...
Aqui esta el list del ejemplo ex_admm
CCS PCM C Compiler, Version 3.147, 15174
Filename: c:archivos de programapiccexamplesex_admm.LST
ROM used: 213 (5%)
Largest free fragment is 2048
RAM used: 11 (6%) at main() level
13 (7%) worst case
Stack: 1 locations
*
0000: MOVLW 00
0001: MOVWF 0A
0002: GOTO 064
0003: NOP
.................... /////////////////////////////////////////////////////////////////////////
.................... //// EX_ADMM.C ////
.................... //// ////
.................... //// This program displays the min and max of 30 A/D samples over ////
.................... //// the RS-232 interface. The process is repeated forever. ////
.................... //// ////
.................... //// Configure the CCS prototype card as follows: ////
.................... //// Insert jumpers from 9 to 15 ////
.................... //// Use the #9 POT to vary the voltage. ////
.................... //// See additional connections below. ////
.................... //// ////
.................... //// This example will work with the PCM and PCH compilers. The ////
.................... //// following conditional compilation lines are used to include a ////
.................... //// valid device for each compiler. Change the device, clock and ////
.................... //// RS232 pins for your hardware if needed. ////
.................... /////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2001 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. ////
.................... /////////////////////////////////////////////////////////////////////////
....................
....................
.................... #if defined(__PCM__)
.................... #include <16c74.h>
.................... //////// Standard Header file for the PIC16C74 device ////////////////
.................... #device PIC16C74
.................... #list
....................
.................... #fuses HS,NOWDT,NOPROTECT
.................... #use delay(clock=20000000)
*
002D: MOVLW 2A
002E: MOVWF 04
002F: MOVF 00,W
0030: BTFSC 03.2
0031: GOTO 03F
0032: MOVLW 06
0033: MOVWF 21
0034: CLRF 20
0035: DECFSZ 20,F
0036: GOTO 035
0037: DECFSZ 21,F
0038: GOTO 034
0039: MOVLW 7B
003A: MOVWF 20
003B: DECFSZ 20,F
003C: GOTO 03B
003D: DECFSZ 00,F
003E: GOTO 032
003F: BCF 0A.3
0040: GOTO 095 (RETURN)
.................... #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
....................
.................... #elif defined(__PCH__)
.................... #include <18c452.h>
.................... #fuses HS,NOPROTECT
.................... #use delay(clock=20000000)
.................... #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
.................... #endif
....................
....................
.................... main() {
....................
.................... int i,value,min,max;
*
0064: CLRF 04
0065: MOVLW 1F
0066: ANDWF 03,F
0067: MOVLW 07
0068: BSF 03.5
0069: MOVWF 1F
006A: MOVLW 20
006B: MOVWF 19
006C: MOVLW 22
006D: MOVWF 18
006E: MOVLW 90
006F: BCF 03.5
0070: MOVWF 18
....................
.................... printf("Sampling:"
;
*
0004: BCF 0A.0
0005: BCF 0A.1
0006: BCF 0A.2
0007: ADDWF 02,F
0008: RETLW 53
0009: RETLW 61
000A: RETLW 6D
000B: RETLW 70
000C: RETLW 6C
000D: RETLW 69
000E: RETLW 6E
000F: RETLW 67
0010: RETLW 3A
0011: RETLW 00
*
0071: CLRF 2A
0072: MOVF 2A,W
0073: CALL 004
0074: INCF 2A,F
0075: MOVWF 20
0076: BTFSS 0C.4
0077: GOTO 076
0078: MOVWF 19
0079: MOVLW 09
007A: SUBWF 2A,W
007B: BTFSS 03.2
007C: GOTO 072
....................
.................... setup_port_a( ALL_ANALOG );
007D: BSF 03.5
007E: CLRF 1F
.................... setup_adc( ADC_CLOCK_INTERNAL );
007F: BCF 03.5
0080: MOVF 1F,W
0081: ANDLW 38
0082: IORLW C1
0083: MOVWF 1F
.................... set_adc_channel( 0 );
0084: MOVLW 00
0085: MOVWF 21
0086: MOVF 1F,W
0087: ANDLW C7
0088: IORWF 21,W
0089: MOVWF 1F
....................
.................... do {
.................... min=255;
008A: MOVLW FF
008B: MOVWF 28
.................... max=0;
008C: CLRF 29
.................... for(i=0;i<=30;++i) {
008D: CLRF 26
008E: MOVF 26,W
008F: SUBLW 1E
0090: BTFSS 03.0
0091: GOTO 0A8
.................... delay_ms(100);
0092: MOVLW 64
0093: MOVWF 2A
0094: GOTO 02D
.................... value = Read_ADC();
0095: BSF 1F.2
0096: BTFSC 1F.2
0097: GOTO 096
0098: MOVF 1E,W
0099: MOVWF 27
.................... if(value<min)
009A: MOVF 28,W
009B: SUBWF 27,W
009C: BTFSC 03.0
009D: GOTO 0A0
.................... min=value;
009E: MOVF 27,W
009F: MOVWF 28
.................... if(value>max)
00A0: MOVF 27,W
00A1: SUBWF 29,W
00A2: BTFSC 03.0
00A3: GOTO 0A6
.................... max=value;
00A4: MOVF 27,W
00A5: MOVWF 29
.................... }
00A6: INCF 26,F
00A7: GOTO 08E
.................... printf("
Min: %2X Max: %2X
",min,max);
*
0012: BCF 0A.0
0013: BCF 0A.1
0014: BCF 0A.2
0015: ADDWF 02,F
0016: RETLW 0A
0017: RETLW 0D
0018: RETLW 4D
0019: RETLW 69
001A: RETLW 6E
001B: RETLW 3A
001C: RETLW 20
001D: RETLW 25
001E: RETLW 32
001F: RETLW 58
0020: RETLW 20
0021: RETLW 20
0022: RETLW 4D
0023: RETLW 61
0024: RETLW 78
0025: RETLW 3A
0026: RETLW 20
0027: RETLW 25
0028: RETLW 32
0029: RETLW 58
002A: RETLW 0D
002B: RETLW 0A
002C: RETLW 00
*
0041: BTFSC 2D.7
0042: GOTO 054
0043: MOVLW 0F
0044: MOVWF 20
0045: SWAPF 2C,W
0046: ANDWF 20,F
0047: MOVLW 0A
0048: SUBWF 20,W
0049: BTFSC 03.0
004A: GOTO 04E
004B: MOVLW 30
004C: ADDWF 20,F
004D: GOTO 050
004E: MOVF 2D,W
004F: ADDWF 20,F
0050: MOVF 20,W
0051: BTFSS 0C.4
0052: GOTO 051
0053: MOVWF 19
0054: MOVLW 0F
0055: ANDWF 2C,F
0056: MOVLW 0A
0057: SUBWF 2C,W
0058: BTFSC 03.0
0059: GOTO 05C
005A: MOVLW 30
005B: GOTO 05E
005C: BCF 2D.7
005D: MOVF 2D,W
005E: ADDWF 2C,F
005F: MOVF 2C,W
0060: BTFSS 0C.4
0061: GOTO 060
0062: MOVWF 19
0063: RETLW 00
*
00A8: CLRF 2A
00A9: MOVF 2A,W
00AA: CALL 012
00AB: INCF 2A,F
00AC: MOVWF 20
00AD: BTFSS 0C.4
00AE: GOTO 0AD
00AF: MOVWF 19
00B0: MOVLW 07
00B1: SUBWF 2A,W
00B2: BTFSS 03.2
00B3: GOTO 0A9
00B4: MOVF 28,W
00B5: MOVWF 2C
00B6: MOVLW 37
00B7: MOVWF 2D
00B8: CALL 041
00B9: MOVLW 0A
00BA: MOVWF 2B
00BB: MOVF 2B,W
00BC: CALL 012
00BD: INCF 2B,F
00BE: MOVWF 20
00BF: BTFSS 0C.4
00C0: GOTO 0BF
00C1: MOVWF 19
00C2: MOVLW 11
00C3: SUBWF 2B,W
00C4: BTFSS 03.2
00C5: GOTO 0BB
00C6: MOVF 29,W
00C7: MOVWF 2C
00C8: MOVLW 37
00C9: MOVWF 2D
00CA: CALL 041
00CB: MOVLW 0D
00CC: BTFSS 0C.4
00CD: GOTO 0CC
00CE: MOVWF 19
00CF: MOVLW 0A
00D0: BTFSS 0C.4
00D1: GOTO 0D0
00D2: MOVWF 19
....................
.................... } while (TRUE);
00D3: GOTO 08A
....................
.................... }
....................
00D4: SLEEP
Configuration Fuses:
Word 1: 3FFA HS NOWDT PUT NOPROTECT
.................... value = Read_ADC();
0095: BSF 1F.2
0096: BTFSC 1F.2
0097: GOTO 096
0098: MOVF 1E,W
0099: MOVWF 27
En la parte de la rutina de conversion, esta guardando solo un byte del resultado, en la direccion 27 de la memoria, no sera que tienes que declararle que el conversor sera de 10 bits o mas en algun lado de la configuracion???



-
Hola, bueno en principio para definir si trabajas con 8 o 10 bits lo podes hacer con esta directiva
#device ADC=10 para 10 bits ó
#device ADC=8 para 8 bits
simpemente con esto cuando escribas
valor= read_adc()
en el programa vas a tener en la variable el valor del conversor,
despues para presentarlo podes ir dividiendo y comparando, pues si usas 8 bits y la referencia del conversor del micro es 5 volt tienes 5/256=0,01953125 osea que cada division vale 20 milivolts, por ende cada voltio 51 unidades del conversor, entonces cuando tengas en valor 102 que es la lectura del conversor del micro confirgurado a puedes comparar y mostrar 2 y asi sucesivamente hasta que tengas 5 voltios que va a ser 51*5=255, entonces solo puedes reducir el programa a 6 lineas ( incliudo mostrar el cero ) sin tablas ni mas complicaciones bueno espero que te quede claro si no a tus ordenes, tambien puedes optar para mas resolucion aplicando el mismo metodo y usando los 10 bits del conversor, de hecho lo que pretendes es una referencia por lo que creo que con 8 bits te va bien.
saludos
Ariel
-
Ok. clarisimo.
Lo pruebo y te cuento.
Muchas gracias.
Saludos.
Pablo
-
¿Y si quieres usar una resolución de 16 bits (resolución que tiene, por ejemplo el 16F876)? ¿Sale por defecto?
Salu2
-
Estás confundido... el 16F87x tiene una resolución de 10-bits.
Saludos!
-
Vive Dios! Eso es tan cierto como que yo estaba equivocado!
Gracias por alumbrarme el camino bendita cucaracha
-
Por defecto (sin usar #device ADC) sale para una resolución de 8 bits. Si deseas que la resolución sea de 10 bits hay que añadir #device ADC=10
Un saludo
PD Resolución de 16 bits con la serie 87x no se puede conseguir, ya que solo se utilizan 10 bits internos. Desconozco si los PIC18 ya vienen con mayor resolución