Microcontroladores PIC en Linux.
¿Quieres reaccionar a este mensaje? Regístrate en el foro con unos pocos clics o inicia sesión para continuar.

Winavr- display 7 segmentos multiplexados - libreria alfa

Ir abajo

Winavr- display 7 segmentos multiplexados - libreria alfa Empty Winavr- display 7 segmentos multiplexados - libreria alfa

Mensaje por maigke Miér 26 Dic 2012 - 19:20

Buenas tardes desde Mx Very Happy bueno experimentando y gracias a los aportes de Felixls y de Samuel, estoy probando hacer una libreria para ATMEGA, la cual tiene la intención de enviar un numero o letra a un arreglo de 3 display de 7 segmentos, por el momento esta en primera liberacion y al parecer funciona bien (la he probado en proto y jala).

les dejo la lib
SO Win7-64
IDE AVR Studio 6
Compilador: WinAVR
programador: USBasp
IDE programador: avrdude-GUI

parametros de los fuses
hFuse DCh
lFuse D7h
eFuse FFh
uC: ATMEGA48

Winavr- display 7 segmentos multiplexados - libreria alfa 7seg


NOTA. No tengo idea del por que no funciona bien en isis, pero fisicamente si funciona muy bien
con delays de 100 usec.
NOTA2. La intencion es no usar un timer de momento, por eso mismo se utlizan los ciclos for tongue
Debe funcionar bien en SO Linux con GCC AVR
NOTA3. Los transistores son unos BC548C con resistencia en la base de 10k y no de 1k como se indica en el diagrama.
Código:

/**
El display de 7 segmentos

Ya que un display tiene siete segmentos mas un punto, es posible almacenar un estado completo del display en un byte,
es decir, para cada estado de cada segmento, un bit, apagado o encendido, de tal forma que el byte resultante es
de la forma abcdefgDP.

De lo anterior cada carácter alfanumérico, puede ser transcrito en cada byte, el cual será mostrado. Si se almacenan
 esos bytes y se indexan apropiadamente en arreglos, se tienen diccionarios.

Circuito:
Se usa una resistencia de 100 ohms entre ánodo/cátodo del display de siete segmentos y un ULN2803, y el circuito driver conectado al AVR

Efecto estroboscópico:
timeOn  100 y timeOff  100 es un buen punto de inicio

IMPORTANTE se requiere definir antes

    #include


    #ifndef F_CPU
    //Define la frecuencia de CPU (en Hertz) por defecto, si  no ha
    //sido definida.
    #define F_CPU 8000000UL // XTAL de 8 MHz
    #endif

    #include
    #define clear_bit(sfr, bit) (_SFR_BYTE(sfr) &=~_BV(bit))
    #define set_bit(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    #define toggle_bit(sfr, bit) (_SFR_BYTE(sfr) ^= _BV(bit))

    #include "SevSeg.h"

Libreria basada en el código:


 * AUTHOR:    Samuel M.H.
 * LAST REV:  17-May-2012
 * DESCRIPTION:
 *  Arduino C code headers for the SMH_7SD class (Seven Segment Display or SSD).
 *
 * LICENSE: GPL V3


*/

#ifndef SevSeg_h
#define SevSeg_h

    //Definiendo el tipo de display de siete segmentos a utilizar
    #define s7SD_COMMON_ANODE    1
    #define s7SD_COMMON_CATHODE    2
   

    //Definiendo los pines a utilizar por parte del usuario
    #define c7s_a    DDB0  //Configura los pines que van a controlar a los segmentos
    #define c7s_b    DDB1
    #define c7s_c    DDB2
    #define c7s_d    DDB3
    #define c7s_e  DDB4
    #define c7s_f    DDB5
    #define c7s_g    DDC0
    #define c7s_dp    DDC1
   
    //define los puertos a utilizar para configurarse como salidas
    #define DDATAa    DDRB
    #define DDATAb    DDRB
    #define DDATAc    DDRB
    #define DDATAd    DDRB
    #define DDATAe    DDRB
    #define DDATAf    DDRB
    #define DDATAg    DDRC
    #define DDATAdp    DDRC
   
    #define cdisp1    DDC2 //Configura los pines que van a seleccionar el display a activar
    #define cdisp2  DDC3
    #define cdisp3  DDC4
   
    #define cddip1    DDRC
    #define cddip2  DDRC
    #define cddip3  DDRC
   
    #define s7s_a    PB0
    #define s7s_b    PB1
    #define s7s_c    PB2
    #define s7s_d    PB3
    #define s7s_e    PB4
    #define s7s_f    PB5
    #define s7s_g    PC0
    #define s7s_dp    PC1
   
    #define PPorta    PORTB
    #define PPortb    PORTB
    #define PPortc    PORTB
    #define PPortd    PORTB
    #define PPorte    PORTB
    #define PPortf    PORTB
    #define PPortg    PORTC
    #define PPortdp    PORTC
   
    #define disp1    PC2
    #define disp2    PC3
    #define disp3    PC4
   
    #define Pdisp1  PORTC
    #define Pdisp2  PORTC
    #define Pdisp3  PORTC

    //definiendo estados
    #define HIGH    1
    #define LOW        0
    http://16.6ms son 60Hz aprox la luminosidadesta en funcion del cico de trabajo
    //si se desea un ciclo del 80% por ejemdplo ton=80 x 16.6 / 100 que sob aproximadamente 14ms
    #define ton    100
    #define toff 100
   
    /* ========= DICTONARIES  =============  */

    //Numbers 0-9
    #define SMH_7SD_NUMBERS (char[]){  \
    0B11111100,                      \
    0B01100000, 0B11011010, 0B11110010, \
    0B01100110, 0B10110110, 0B10111110, \
    0B11100000, 0B11111110, 0B11110110  \
    }

    //Letters A-Z
    #define SMH_7SD_LETTERS (char[]){                        \
    0B11101110, 0B00111110, 0B10011100, 0B01111010, 0B10011110, \
    0B10001110, 0B10111100, 0B01101110, 0B01100000, 0B01111000, \
    0B01011111, 0B00011100, 0B11101101, 0B00101010, 0B11111100, \
    0B11001110, 0B11100110, 0B00001010, 0B10110110, 0B00011110, \
    0B01111100, 0B00111000, 0B11110011, 0B00110011, 0B01110110, \
    0B11011010,                                            \
    }

    /***********************************************************************
    Funciones para trabajar con los display de 7 segmentos
                                                                       
    ***********************************************************************/
    uint8_t on,off;
   
   
    void init_7S(short tipo)
    {
                if(tipo == s7SD_COMMON_CATHODE){
                    on = HIGH; off = LOW;
                } else {
                    on = LOW; off = HIGH;
                }
               
                //Se configuran como salidas los pines indicados
                //para las salidas de los display
                set_bit(DDATAa, c7s_a);
                set_bit(DDATAb, c7s_b);
                set_bit(DDATAc, c7s_c);
                set_bit(DDATAd, c7s_d);
                set_bit(DDATAe, c7s_e);
                set_bit(DDATAf, c7s_f);
                set_bit(DDATAg, c7s_g);
                set_bit(DDATAdp, c7s_dp);
                //se configura como salidas los pines de multiplexado
                set_bit(cddip1, cdisp1);
                set_bit(cddip2, cdisp2);
                set_bit(cddip3, cdisp3);
                //Se deshabilitan desde un inicio los display
                clear_bit(Pdisp1,disp1);
                clear_bit(Pdisp2,disp2);
                clear_bit(Pdisp3,disp3);
    }
   
    void printRaw(char data)
    {
        if(data & 0b10000000)  //se verifica primero el estado del segmento a
            {
                if(on){set_bit(PPorta,s7s_a);}  //para display de catado
                    else{clear_bit(PPorta,s7s_a);} //para display de anodo
            }
            else
            {
                if(on){clear_bit(PPorta,s7s_a);}
                    else{set_bit(PPorta,s7s_a);}
            }
           
            if(data & 0b01000000)  //se verifica primero el estado del segmento b
                {
                    if(on){set_bit(PPortb,s7s_b);}  //para display de catado
                    else{clear_bit(PPortb,s7s_b);} //para display de anodo
                }
                else
                {
                    if(on){clear_bit(PPortb,s7s_b);}
                    else{set_bit(PPortb,s7s_b);}
            }
           
            if(data & 0b00100000)  //se verifica primero el estado del segmento c
                {
                    if(on){set_bit(PPortc,s7s_c);}  //para display de catado
                    else{clear_bit(PPortc,s7s_c);} //para display de anodo
                }
            else
                {
                    if(on){clear_bit(PPortc,s7s_c);}
                    else{set_bit(PPortc,s7s_c);}
                }

            if(data & 0b00010000)  //se verifica primero el estado del segmento d
                {
                    if(on){set_bit(PPortd,s7s_d);}  //para display de catado
                    else{clear_bit(PPortd,s7s_d);} //para display de anodo
                }
            else
                {
                    if(on){clear_bit(PPortd,s7s_d);}
                    else{set_bit(PPortd,s7s_d);}
                }
               
            if(data & 0b00001000)  //se verifica primero el estado del segmento e
                {
                    if(on){set_bit(PPorte,s7s_e);}  //para display de catado
                    else{clear_bit(PPorte,s7s_e);} //para display de anodo
                }
            else
                {
                    if(on){clear_bit(PPorte,s7s_e);}
                    else{set_bit(PPorte,s7s_e);}
                }
               
            if(data & 0b00000100)  //se verifica primero el estado del segmento f
                {
                    if(on){set_bit(PPortf,s7s_f);}  //para display de catado
                    else{clear_bit(PPortf,s7s_f);} //para display de anodo
                }
            else
                {
                    if(on){clear_bit(PPortf,s7s_f);}
                    else{set_bit(PPortf,s7s_f);}
                }               
               
            if(data & 0b00000010)  //se verifica primero el estado del segmento g
                {
                    if(on){set_bit(PPortg,s7s_g);}  //para display de catado
                    else{clear_bit(PPortg,s7s_g);} //para display de anodo
                }
            else
                {
                    if(on){clear_bit(PPortg,s7s_g);}
                    else{set_bit(PPortg,s7s_g);}
                }
               
            if(data & 0b00000001)  //se verifica primero el estado del segmento dp
                {
                    if(on){set_bit(PPortdp,s7s_dp);}  //para display de catado
                    else{clear_bit(PPortdp,s7s_dp);} //para display de anodo
                }
            else
                {
                    if(on){clear_bit(PPortdp,s7s_dp);}
                    else{set_bit(PPortdp,s7s_dp);}
                }
    }
   
    void s7S_putc(char c, char disp)
    {
        char b;
        if(48<= c && c<=57){
            b = SMH_7SD_NUMBERS[c-48];  //numeros
        }else if(65 <= c && c<=90){
            b = SMH_7SD_LETTERS[c-65];  //mayusculas
        }else if (97 <= c && c<= 122){
            b = SMH_7SD_NUMBERS[c-97];
        }
        else if(c == ' ') b = 0x00;
        else if(c == '.') b = 0x01;
        else if(c == '-') b = 0x02;
        else if(c == '_') b = 0x10;
       
        printRaw(b);  //enciende solo un display
        switch (disp)
        {
            case 0:
            {
                set_bit(Pdisp1,disp1);
                clear_bit(Pdisp2,disp2);
                clear_bit(Pdisp3,disp3);
                break;
            }           
            case 1:
            {
                set_bit(Pdisp2,disp2);
                clear_bit(Pdisp1,disp1);
                clear_bit(Pdisp3,disp3);
                break;
            }               
            case 2:
            {
                set_bit(Pdisp3,disp3);
                clear_bit(Pdisp1,disp1);
                clear_bit(Pdisp2,disp2);
                break;
            }           
            default:
            {
                clear_bit(Pdisp1,disp1);
                clear_bit(Pdisp2,disp2);
                clear_bit(Pdisp3,disp3);
            }           
        }
       
    }
   
    void s7S_puts(char *ptr)
    {
        int i=0;
        while(ptr[i]!='\0')
        {
            s7S_putc(ptr[i],i);
            _delay_us(ton);
            s7S_putc(' ',i);
            _delay_us(toff);
            i++;
        }
    }
   
#endif //SevSeg_h


Aun se puede mejorar mucho, pero es un comienzo, saludos

Código:

/*
 * SevenSeg_Numeros.c
 *
 * Created: 24/12/2012 00:51:55
 *  Author: Miguel
 */


#include

//////////////////////////////////////////////////////////////// 
#ifndef F_CPU
/* Define la frecuencia de CPU (en Hertz) por defecto, si  no ha
 * sido definida. */
#define F_CPU 20000000UL // XTAL de 8 MHz
#endif

#include
#define clear_bit(sfr, bit) (_SFR_BYTE(sfr) &=~_BV(bit))
#define set_bit(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define toggle_bit(sfr, bit) (_SFR_BYTE(sfr) ^= _BV(bit))

#include "SevSeg.h"

int main(void)
{
    char i;
    int j;
    init_7S(s7SD_COMMON_CATHODE);
    while(1)
    {
        for (i = 0; i < 200; i++)
        {
            s7S_puts("-18");
        }
        for (j=0; j<500; i++)
        {
            s7S_puts(" 8 "); //Se dejan 3 espacios por que son 3 display
        }
       
        //TODO:: Please write your application code
        i=0;
    }
}
maigke
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 47
Localización : Mexico

Volver arriba Ir abajo

Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.