Autor Tema: Almacén de rutinas en C para PIC  (Leído 2769 veces)

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

Desconectado elmasvital

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 1713
Almacén de rutinas en C para PIC
« en: 07 de Octubre de 2005, 08:29:00 »
Bueno He visto que en el foro de basic para pic tienen un almacén de rutinas y nosotros no... Ya se que existen los maravillosos ejemplos de vzener y el cursillo de c pero no una biblioteca al uso de rutinas para nuestros pics en c así que la inicio yo si os parece ok?


Desconectado elmasvital

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 1713
RE: Almacén de rutinas en C para PIC
« Respuesta #1 en: 07 de Octubre de 2005, 08:30:00 »
Contador de segundos para pic. Muestra la implementación de un timer (el 2) y la configuración del preescaler para velocidades de 4mhz y presenta el resultado en
un lcd

Ojo que no es exacto... pierde algun que otro microsegundo...

#include <16F628.h>

#use delay (clock=4000000)
#fuses intrc_io,NOWDT,NOBROWNOUT,NOPROTECT,PUT,NOLVP,NOMCLR //ordenes para el programador
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd


#define INTS_PER_SECOND 25        // (20000000/(4*16*250*10))

int8 seconds;      // A running seconds counter
int8 int_count;    // Number of interrupts left before a second has elapsed


#INT_TIMER2                        // This function is called every time
void clock_isr() {                 // timer 2 overflows (250->0), which is
                                   // approximately 125 times per second for
    if(--int_count==0) {           // this program.
      ++seconds;
      int_count = INTS_PER_SECOND;
    }
}


void main() {
   int8 contador;
   int_count = INTS_PER_SECOND;

   lcd_init();
   setup_timer_2(T2_DIV_BY_16, 250, 10);
   set_timer2(0);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);


      int_count = INTS_PER_SECOND;
      seconds = 0;
      contador = 1;
   while(TRUE) {
      if (contador!=seconds)
      {
         printf(lcd_putc, "f%u seconds", seconds);
         contador=seconds;
      }
   }
}


PD: cómo se hace para que presente el texto identado?

Desconectado elmasvital

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 1713
RE: Almacén de rutinas en C para PIC
« Respuesta #2 en: 07 de Octubre de 2005, 08:45:00 »
rutina lcd.c para ccs modificada por mi por dos razones:

1. contine un fallo en el send_byte, le falta activar el bit rw=1 por lo que en concreto mi lcd de 1x16 no funcionaba. Si tu lcd da problemas usa esta a ver que tal.

2. no configura bien los lcd de 1x16

para usarla en modo 1x16 debeis definir antes de el include del archivo

#define use_lcd_1x16


ahí va

///////////////////////////////////////////////////////////////////////////
////                             LCDD.C                                ////
////                 Driver for common LCD modules                     ////
////                                                                   ////
////  lcd_init()   Must be called before any other function.           ////
////                                                                   ////
////  lcd_putc(c)  Will display c on the next position of the LCD.     ////
////                     The following have special meaning:           ////
////                      f  Clear display                            ////
////                      
  Go to start of second line               ////
////                        Move back one position                   ////
////                                                                   ////
////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)    ////
////                                                                   ////
////  lcd_getc(x,y)   Returns character at position x,y on LCD         ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (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.                               ////
///////////////////////////////////////////////////////////////////////////

// MODIFICADO POR VITAL para que acepte todos los lcd"s sin problemas //


// As defined in the following structure the pin connection is as follows:
//     D0  enable
//     D1  rs
//     D2  rw
//     D4  D4
//     D5  D5
//     D6  D6
//     D7  D7
//
//   LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B
// #define use_portb_lcd TRUE


struct lcd_pin_map {                 // This structure is overlayed
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rs;               // access to the LCD pins.
           BOOLEAN rw;               // The bits are allocated from
           BOOLEAN unused;           // low order up.  ENABLE will
           int     data : 4;         // be pin B0.
        } lcd;


#if defined(__PCH__)
#if defined use_portb_lcd
   #byte lcd = 0xF81                   // This puts the entire structure
#else
   #byte lcd = 0xF83                   // This puts the entire structure
#endif
#else
#if defined use_portb_lcd
   #byte lcd = 6                  // on to port B (at address 6)
#else
   #byte lcd = 8                 // on to port D (at address 8)
#endif
#endif

#if defined use_portb_lcd
   #define set_tris_lcd(x) set_tris_b(x)
#else
   #define set_tris_lcd(x) set_tris_d(x)
#endif


//MODIFICADO POR VITAL... si vas a usar lcd"s de 1 linea por 16 declara la varible use_lcd_1x16 en tu programa
//            así --> #define use_lcd_1x16 antes del include de este archivo

#if defined use_lcd_1x16
   #define lcd_type 0
#else

   #define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines


#define lcd_line_two 0x40    // LCD RAM address for the second line


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE modo, BYTE n ) {

      lcd.rs = 0;
     lcd.rw = 1; // MODIFICADO POR VITAL... fallo de la rutina... el protocolo necesita este bit
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = modo; //MODIFICADO POR VITAL... aqui addres lleva a confusión... este bit define el modo comando o texto
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE 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 "
"   : lcd_gotoxy(1,2);        break;
     case ""   : lcd_send_byte(0,0x10);  break;
     default     : lcd_send_byte(1,c);     break;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}

Desconectado gomalejo

  • PIC10
  • *
  • Mensajes: 1
RE: Almacén de rutinas en C para PIC
« Respuesta #3 en: 18 de Octubre de 2005, 12:16:00 »
Sonrisa Gigante    Hola, en esta direccion podran encontrar muchas librerias y ejemplos para trabajar con C.
http://user.chollian.net/~ascbbs/appnote.htm

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.


 

anything