Autor Tema: Nuevo en lenguaje C para PIC usando CCS Compiler  (Leído 4839 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado trucksbear

  • PIC10
  • *
  • Mensajes: 10
Nuevo en lenguaje C para PIC usando CCS Compiler
« en: 08 de Diciembre de 2016, 22:39:23 »
Hola, soy nuevo usando lenguaje C con PIC, siempre usé ASM que fue lo que me enseñaron en el secundario, pero ahora necesito mudarme a lenguaje C por que es una exigencia del profesor, además del NO uso de librerías. Y estoy tratando de inicializar el sensor DHT11-22, aunque el que poseeo es el DHT11, y quería saber si esta rutina que hice es correcta o qué es lo que habría que cambiar, dado que no tengo como simularlo para saber si es correcto muchas gracias.
El programa a continuacion:

#incluide <PIC16F628A>
#fuses NOWDT,NOPROTECT,NOLVP,NOMCLR,INTRC_IO
#use delay(clock = 4000000)
#define DHT11 PIN_A4

//Acá inicio el programa sólo incluiré una parte la de inicialización del sensor, dado que no sé si todo es correcto

void main(){
inicio_DHT
output_high (DHT11) //Aseguro el estado alto de la salida
output_low (DHT11)
delay_mS (20)           //Lo paso a estado bajo durante 20mS para iniciar la respuesta del sensor, el fabricante pide >18mS
output_high (DHT11)
delay_uS (30)    //El fabricante espera un estado alto de 20-40uS, lo puedo ajustar en el caso que el programa no ande
input (DHT11) //Configuro el pin como entrada para iniciar el conteo de la respuesta del sensor
if (DHT11 == 0) {delay_us (80)} //el sensor debe enviar un pulso bajo de 80uS
else {goto inicio_DHT}                // esto no sé si es correcto
if (DHT11 == 1) {delay_us (80)} //el sensor debe enviar un pulso alto de 80uS
else {goto inicio_DHT}

también, quisiera saber si hay manera de llenar un vector (array) y que éste al estar lleno salte al llenado de otro vector (array)
muchas gracias espero sus respuetas

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #1 en: 08 de Diciembre de 2016, 23:25:20 »
La verdad que si venis desde ASM y te manejas bien modificando los registros del PIC, te recomendaria XC8 en ves de CCS, ya que CCS tiene algunas cosas buenas y malas a mi gusto. Las buenas es que te permite hacer cosas rapidamente sin tener que pensar en registros. La mala es que hace muchas cosas detras tuyo y si no tenes experiencia con el compilador puede llegar a ser un dolor de cabeza.

Primero en C no necesitas "etiquetas" ( labels ) como lo es inicio_DHT.
Por otro lado salvo algunas excepciones no se usa el goto, Digo excepciones porque a veces es mejor usarlo, pero para los primeros pasos mejor dejarlos aparte ya que es posible que cometas errores al no tener conocimiento de como funciona C internamente.

El DHT11 esta realizado para que se use con un pin colector abierto. Pero el PIC no posee esto. Por lo tanto la unica forma seria de activar la salida y luego pasarlo a entrada.
¿Cual es el problema de esto en CCS?

Como te decia, CCS hace cosas que alguien que no lo conoce pueden parecer raras. Cuando usas las instrucciones:

output_high();
output_low();

El compilador agregar lineas de codigo cambiando el TRIS de esos pines, suponete que lo tenias como entradas y pusiste esa instruccion, entonces lo deja como salida. Si pones un:

input_pin();

Ocurre lo mismo , nomas que ahora cambia el TRIS de ese pin a entrada.
Hay forma de evitar esto, y la forma es usando una directiva propia de CCS ( de estas posee muchas como fuses, use, bit, byte , etc ) y que no siguen el estándar de C.

Si pones

#USE FAST_IO(A)

Eso hace que para aquellos pines del puerto A no cambie el TRIS por si solo, y depende unicamente de vos.

Ahora podes definir los tris con set_tris_a(0b00010101);

------------------------------------------------------

Problemas de programacion en tu programa:

La primer linea es "include", usualmente si incluis un archivo es una cabecera o archivo con extension .h
Toda instruccion debe terminar con un punto y coma, excepto los if, for entre otros, ejemplo:

Código: C
  1. output_low(PIN_A4);
  2. if(input_pin(PIN_A3))
  3. {
  4.      output_high(PIN_A0);
  5.      delay_ms(30);
  6. }
  7.  
  8. // Esto siempre se cumple, por lo tanto es un bucle infinito
  9. while(1)
  10. {
  11.  
  12. }

Recorda como hacias en ASM, y te vas a dar cuenta que siempre se debe tener un bucle infinito. Para eso se usa el while(1), en resumen tu programa quedaria con este formato:

Código: C
  1. void main(void)
  2. {
  3.       //Aca la inicializacion de modulos o de partes externas
  4.  
  5.      while(1)
  6.      {
  7.               //Aca el programa principal
  8.               que siempre se va a estar ejecutando
  9.      }
  10. }

Te recomiendo que busques por internet los tipos de control de flujo que tenes, como los "for", los "if", los "while" y "do..while" y que realizes ejemplos simples para entenderlos.
Eso antes de meterte de lleno con las partes del microcontrolador. A lo que me refiero es tratar de conocer las herramientas que tenes para luego usarlas.

Desconectado trucksbear

  • PIC10
  • *
  • Mensajes: 10
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #2 en: 08 de Diciembre de 2016, 23:39:59 »
Gracias, ha sido bastante útil, con el CCS me manejo bastante bien, el uso del lenguaje C lo manejo bastante, pero hacíamos programas en el CCS para luego pasarlos al DEVC para simular en consola, siempre que usaba un PIC lo hacía en ASM por que eso era lo que quería el profesor, pero ahora el nuevo profesor quiere que sólo usemos lenguaje C, y al incluir el archivo header (.h) el CCS al intentar compilar me salta errores de dicho archivo .H que se supone que trae el CCS para ahorarte la definición de los pines, esto me está molestando bastante, y otro capricho del profesor, quiere que solo usemos el CCS...

Desconectado trucksbear

  • PIC10
  • *
  • Mensajes: 10
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #3 en: 08 de Diciembre de 2016, 23:51:01 »
hice que la inicialización del sensor fuera una función, haciendo así:
void inicio_DHT(){
output_high (DHT11);              //Aseguro el estado alto de la salida por 1S
delay_mS (1000);
output_low (DHT11);
delay_mS (20);                    //Estado bajo durante 20mS para la respuesta del sensor, el fabricante pide >18mS
output_high (DHT11);
delay_uS (30);                    //El fabricante espera un estado alto de 20-40uS
input (DHT11);                    //Configuro el pin como entrada para iniciar el conteo de la respuesta del sensor
if (DHT11 == 0) {delay_us (80);}  //el sensor debe enviar un pulso bajo de 80uS
else {inicio_DHT();}
if (DHT11 == 1) {delay_us (80);}  //el sensor debe enviar un pulso alto de 80uS
else {inicio_DHT();}
}

dentro del else, puse como condicionante que volviera al inico de la función,
ahora tendría que hacer un array de 40 lugares para llenarlo con los bits que brinda el sensor
y dentro del main puedo hacer la llamada a la función y la impresión en el LCD
« Última modificación: 09 de Diciembre de 2016, 01:47:46 por trucksbear »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #4 en: 09 de Diciembre de 2016, 02:06:02 »
Citar
dentro del else, puse como condicionante que volviera al inico de la función,

No deberias, porque estas haciendolo recursivo en un microcontrolador que no posee gran espacio de stack. Utiliza un while o un for, pero no eso.

Ademas el DHT no tiene inicializacion, simplemente es enviar el valor correspondiente y leer.

Desconectado trucksbear

  • PIC10
  • *
  • Mensajes: 10
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #5 en: 09 de Diciembre de 2016, 02:37:42 »
al DHT11 hay que enviarle un pulso bajo de >18mS volver a alto durante 20 a 40 uS
y ahí el sensor te envía un pulso bajo de 80uS y uno alto de 80uS
luego de eso empieza a enviar los datos
enviando un "separador" de 50uS entre "0" y "1"
siendo que un "0" es un estado alto de 26 a 28 uS
y siendo que un "1" es un estado alto de 70uS

no logro  entender como usar el while, en el caos de que no se cumpla el estado bajo de 80uS y vuelva a enviarle el pulso bajo de >18mS al sensor

por si no se entendió acá esta la hoja de datos del ensor
http://www.micropik.com/PDF/dht11.pdf
« Última modificación: 09 de Diciembre de 2016, 02:40:59 por trucksbear »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #6 en: 09 de Diciembre de 2016, 11:55:01 »
Bueno, pero para que lo entiendas, NO ES UNA INICIALIZACION.

Si tenes que enviarle ese pulso para que el DHT11 comienze a transmitir el resultado, pero no lo tenes que hacer apenas arrancas.
Yo usaria while y for.

Ejemplo:

Código: C
  1. int8 i,j,valor[5],temp;
  2.  
  3. output_low(PIN_A4);                     // Pulso bajo
  4. delay_ms(30);                           // demora
  5. while(input_pin(PIN_A4) == 0) {}        // Al ponerlo como entrada, se va a 1 por la resistencia de pull-up, espero que que envie un 0 el DHT
  6. while(input_pin(PIN_A4) == 1) {}        // Espero que lo suelte, es decir que aparezca un 1.
  7.  
  8. //Comienzo a recibir los datos, son 5 bytes, en el cual tienen 8 bits cada uno
  9.  
  10. for(j=0;j<5;j++)
  11. {
  12.         valor[j] = 0;                                           // Inicio el valor
  13.  
  14.         for(i=0;i<8;i++)                                        // Repito 8 veces, para cada j
  15.         {
  16.                 while(input_pin(PIN_A4) == 0) {}                // Espero que primero este en 0
  17.                 delay_us(100);                                  // 100us espero, si leo 1, significa que llego un 1, si leo 0 implica que era un 0
  18.                 valor = (valor << 1) | input_pin(PIN_A4);       // Desplazo un lugar a la izquierda y pongo el bit recibido, que es justamente el valor que debe ser
  19.         }
  20.  
  21. }
  22.  
  23. for(i=0;i<4;i++)
  24. {
  25.         temp += valor[i]
  26. }
  27.  
  28. if(temp!=valor[4])
  29. {
  30.         // Error aca, el cheksum no es correcto
  31. }
  32.  
  33. /* Resultado
  34.  
  35. Tendrias los siguientes valores:
  36.  
  37. valor[0] = Entero Humedad Relativa
  38. valor[1] = Decimal Humedad Relativa
  39. valor[2] = Entero Temperatura
  40. valor[3] = Decimal Temperatura
  41. valor[4] = Checksum
  42.  
  43. */

Desconectado trucksbear

  • PIC10
  • *
  • Mensajes: 10
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #7 en: 13 de Diciembre de 2016, 17:51:28 »
hice una rutina muy similar, compiló y todo, lo pasé al PIC16F628A y no manda ningún caracter al LCD, probé armar una rutina pequeña, como esta y tampoco pude hacer que mostrara nada en el LCD, pero contrariamente sí lo hac een el Proteus 8

#include <16F628A.h>
#fuses  NOWDT,NOPROTECT,NOLVP,MCLR,INTRC_IO,NOBROWNOUT
#use    delay(clock = 4000000)
#define LCD_DATA_PORTB
#define LCD_ENABLE_PIN  PIN_A3
#define LCD_RW_PIN      PIN_A2
#define LCD_RS_PIN      PIN_A1                         
#define LCD_DATA4       PIN_B4                         
#define LCD_DATA5       PIN_B5                         
#define LCD_DATA6       PIN_B6                         
#define LCD_DATA7       PIN_B7
#include <lcd.c>

unsigned int dia = 26, mes = 8, an = 19, io = 96;

void main(){
lcd_init();
lcd_gotoxy (1,1);
printf     (lcd_putc "\fNombre");
delay_mS   (1000);
lcd_gotoxy (1,1);
printf     (lcd_putc " Apellido \n %u / %u / %u%u", dia, mes, an, io);
delay_mS   (1000);
while      (true);}
   
alguien más le sucedió lo mismo?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #8 en: 13 de Diciembre de 2016, 18:11:17 »
Tenes conectador el MCLR a VDD ?
Esta correcta la conexion del LCD ( contraste, señales, etc ) ?

Mas que eso no te podria ayudar. Ya que no me manejo demasiado con CCS y sus librerias. Pero si te funciona en Proteus, lo mas seguro que sea un problema de FUSES o conexiones del PIC/LCD

Desconectado trucksbear

  • PIC10
  • *
  • Mensajes: 10
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #9 en: 13 de Diciembre de 2016, 21:52:26 »
el problema estaba en el contraste del LCD, el problema es que el programa imprime en el LCD

Nombre

luego imprime:

Apellido
dia/mes/año

pero no vuelve a reiniciarce y volver a imprimir la secuencia se queda "tildado" en apellido...

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #10 en: 13 de Diciembre de 2016, 22:32:22 »
Es que el programa no hace mas nada que eso...

Borra y escribe "Nombre"
Espera 1 segundo
Se posiciona en el primer valor y luego escribe

"Apellido
dia/mes/año"

Y luego con el while(true) se queda dentro del while para siempre. No se que estas buscando hacer.

Desconectado trucksbear

  • PIC10
  • *
  • Mensajes: 10
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #11 en: 13 de Diciembre de 2016, 22:46:16 »
y que sería lo que correspondería para que vuelva a iniciar el programa otra vez?
no se supone que con el while, establezco un bucle?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #12 en: 13 de Diciembre de 2016, 23:34:02 »
Si pero tu "bucle" queda ahi nomas por que el while esta cerrado... te lo escribo de otra forma para que te des cuenta:

Código: C
  1. void main()
  2. {
  3.     lcd_init();
  4.     lcd_gotoxy(1, 1);
  5.     printf (lcd_putc "\fNombre");
  6.     delay_mS(1000);
  7.     lcd_gotoxy(1, 1);
  8.     printf (lcd_putc " Apellido \n %u / %u / %u%u", dia, mes, an, io);
  9.     delay_mS(1000);
  10.     while (true)
  11.     {
  12.     }
  13. }

Y lo que queres hacer vos es:

Código: C
  1. void main()
  2. {
  3.     lcd_init();
  4.    
  5.     while (true)
  6.     {
  7.         lcd_gotoxy(1, 1);
  8.         printf (lcd_putc "\fNombre");
  9.         delay_mS(1000);
  10.         lcd_gotoxy(1, 1);
  11.         printf (lcd_putc " Apellido \n %u / %u / %u%u", dia, mes, an, io);
  12.         delay_mS(1000);
  13.     }
  14. }

Espero que veas la diferencia.
Al hacer while(true); y ponerle el ";" lo que haces es terminar el while ahi nomas. que seria lo mismo que en el primer codigo que te pase, es como si tuvieras ejecutando un codigo con nada.
Distinto es el segundo codigo, el cual ahora si vuelve a comenzar a enviar todo de 0 una ves que termina con el delay leugo de escribir "Apellido...."

Desconectado trucksbear

  • PIC10
  • *
  • Mensajes: 10
Re:Nuevo en lenguaje C para PIC usando CCS Compiler
« Respuesta #13 en: 14 de Diciembre de 2016, 00:08:37 »
muchas gracias, y incluso pude hacer que me mostrata lso datos enviados por el DHT11
 :o :o :o
aunque no son reales  :x :x