STM8 DISCOVERY – 7segment serial link (3) – C source code

C source to drive 7segment LED display (PIC 16f884).
All I/O pins can be in random order.
The user.c and system.c files are not shown, they contain a few additional lines.


/******************************************************************************/
/* Files to Include                                                           */
/******************************************************************************/
#if defined(__XC)
    #include          /* XC8 General Include File */
#elif defined(HI_TECH_C)
    #include         /* HiTech General Include File */
#endif
#include         /* For uint8_t definition */
#include        /* For true/false definition */
#include “system.h”        /* System funct/params, like osc/peripheral config */
#include “user.h”          /* User funct/params, such as InitApp */
/******************************************************************************/
/* User Global Variable Declaration                                           */
/******************************************************************************/
unsigned char v_PORTA,v_PORTB,v_PORTC,v_PORTD,v_PORTE;
unsigned char v_TRISA,v_TRISB,v_TRISC,v_TRISD,v_TRISE;
unsigned char disp_digits[]={0,0,0};
unsigned int v_disp_data;
unsigned char v_disp_upd;
#define c_disp_upd_delay 0x08
const unsigned char disp_data_shift[]={0,4,8};
unsigned char v_phase,v_led0;

#define c_led0_delay 0x30
#define c_digits 7
#define c_anodes 2
const unsigned char led7seg_data[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x47,\
                                    0x7f,0x67,0x77,0x7c,0x39,0x5e,0x79,0x71,\
                                    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
                                    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
#define v_PORTA_idx 0
#define v_PORTB_idx 1
#define v_PORTC_idx 2
#define v_PORTD_idx 3
#define v_PORTE_idx 4
#define c_nphases 3
const unsigned char* portvars[]={&v_PORTA,&v_PORTB,&v_PORTC,&v_PORTD,&v_PORTE};
const unsigned char* trisvars[]={&TRISA,&TRISB,&TRISC,&TRISD,&TRISE};
const unsigned char led7seg_decode[]={v_PORTD_idx,6,\
                           v_PORTB_idx,3,\
                           v_PORTA_idx,5,\
                           v_PORTE_idx,1,\
                           v_PORTE_idx,2,\
                           v_PORTD_idx,7,\
                           v_PORTA_idx,4,\
                           v_PORTE_idx,0};
const unsigned char led7seg_anodes[]={v_PORTD_idx,5,\
                             v_PORTB_idx,1,\
                             v_PORTB_idx,2};
// OR – set to 1
const unsigned char led7seg_decode_reset2[]={1,2,4,8,16,32,64,128};
// AND – set to 0
const unsigned char led7seg_decode_set2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
const unsigned char led7seg_phase_patts[]={0b00000100,0b00000010,0b00000001};
void configure_TRIS()
{unsigned char i,i2,v_port,v_portbit,v_trisdata;
unsigned char* v_trisvar;
 for(i=0;i<=c_digits;i++)
 {
     i2=i<<1;
     v_port=led7seg_decode[i2];
     v_trisvar=trisvars[v_port];
     v_trisdata=*v_trisvar;
     v_portbit=led7seg_decode[i2+1];

     v_trisdata&=led7seg_decode_set2[v_portbit];
     *v_trisvar=v_trisdata;
 }

 for(i=0;i<=c_anodes;i++)
 {
     i2=i<<1;
     v_port=led7seg_anodes[i2];
     v_trisvar=trisvars[v_port];
     v_trisdata=*v_trisvar;
     v_portbit=led7seg_anodes[i2+1];

     v_trisdata&=led7seg_decode_set2[v_portbit];
     *v_trisvar=v_trisdata;
 }
}

void refresh_anodes(unsigned char v_phase)
{unsigned char v_phase_patt;
 unsigned char i,i2,shl_data,port,portbit,portdata;
 unsigned char* portvar;

 shl_data=1;
 v_phase_patt=led7seg_phase_patts[v_phase];
 for(i=0;i<=c_anodes;i++)
 {
     i2=i<<1;
     port=led7seg_anodes[i2];
     portvar=portvars[port];
     portbit=led7seg_anodes[i2+1];
     portdata=*portvar;

     if(shl_data&v_phase_patt)
     {
      portdata|=led7seg_decode_reset2[portbit];
     }else
     {
      portdata&=led7seg_decode_set2[portbit];
     }
     *portvar=portdata;
     shl_data<<=1;
 }

}

void refresh_digits(unsigned char v_phase)
{unsigned char shl_val,disp_data_patt,disp_data;
unsigned char i,i2,port,port_data,portbit;
unsigned char* portvar;

disp_data=disp_digits[v_phase];
disp_data&=0x1f;
disp_data_patt=led7seg_data[disp_data];

 shl_val=1;
 for(i=0;i<=c_digits;i++)
 {
  i2=i<<1;
  port=led7seg_decode[i2];
  portvar=portvars[port];
  port_data=*portvar;
  portbit=led7seg_decode[i2+1];

  if(shl_val&disp_data_patt)
  {
   port_data&=led7seg_decode_set2[portbit];
  }else
  {
   port_data|=led7seg_decode_reset2[portbit];
  }
  *portvar=port_data;
  shl_val<<=1;
 }
}

void update_digits(unsigned int v_data)
{
    disp_digits[0]=(unsigned char)(v_data&0x0f);
    disp_digits[1]=(unsigned char)((v_data>>4)&0x0f);
    disp_digits[2]=(unsigned char)((v_data>>8)&0x0f);
}
/* i.e. uint8_t ; */
/******************************************************************************/
/* Main Program                                                               */
/******************************************************************************/
void main(void)
{
    /* Configure the oscillator for the device */
    ConfigureOscillator();
    /* Initialize I/O and Peripherals for application */
    configure_TRIS();
    InitApp();
    v_phase=0;
    v_led0=0;
    v_disp_data=0;
    v_disp_upd=0;
    update_digits(v_disp_data);
    while(1)
    {
        if(v_flags&c_flags_timer0_set)
        {
            v_flags&=c_flags_timer0_reset;
            refresh_digits(v_phase);
            refresh_anodes(v_phase);
            v_phase++;if(v_phase==c_nphases){v_phase=0;}
            v_disp_upd++;if(v_disp_upd==c_disp_upd_delay)
            {
                v_disp_upd=0;
                v_disp_data++;
                if(v_disp_data==0xfff)
                {
                    v_disp_data=0;
                }
                update_digits(v_disp_data);
            }
            v_led0++;if(v_led0==c_led0_delay)
            {
                v_led0=0;
                if(v_flags&c_flags_led0_set)
                {
                 v_flags&=c_flags_led0_reset;
                 v_PORTC&=c_flags_led0_reset;
                }else
                {
                 v_flags|=c_flags_led0_set;
                 v_PORTC|=c_flags_led0_set;
                }
            }
        PORTA=v_PORTA;
        PORTB=v_PORTB;
        PORTC=v_PORTC;
        PORTD=v_PORTD;
        PORTE=v_PORTE;
        }
        /* TODO  */
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *