CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

MAX7219 Serial 8 digit seven segment display driver

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
jitun



Joined: 25 Mar 2009
Posts: 5

View user's profile Send private message Yahoo Messenger

MAX7219 Serial 8 digit seven segment display driver
PostPosted: Tue May 12, 2009 12:49 am     Reply with quote

One of my student got some of these display drivers, MAX7219. As I was experimenting, I ended up writing the code to interface it with PIC18F4550. Here is the code and the example.

It won't compile with older version CCS C Compilers. With old version(I tested with 3.249) it will show compile time error "Arrays of bits are not permitted"

MAX7219.c
Code:
#define clk_delay 1
int1 nd;
unsigned int8 pos;
//concat two 8bit int and gives a 16 bit int
//helper function
unsigned int16 concat(unsigned int8 d1,unsigned int8 d2)
{
   unsigned int16 temp;
   temp=0x0000;
   temp=d1;
   shift_left(&temp,2,0);
   shift_left(&temp,2,0);
   shift_left(&temp,2,0);
   shift_left(&temp,2,0);
   shift_left(&temp,2,0);
   shift_left(&temp,2,0);
   shift_left(&temp,2,0);
   shift_left(&temp,2,0);
   //temp=temp&0x0111;
   temp=temp|d2;
   return temp;
}
//since the segment sequence of MAX7219 is
//D7 D6 D5 D4 D3 D2 D1 D0
//DP  A  B  C  D  E  F  G   while according to convention it is
//DP  G  F  E  D  C  B  A
//One may avoide this my doing the proper changes in the circuit wiring but
//it will again lead to more complication because in CODE B decode mode the
//segment are just opposit to what u see in no decode mode. so in any case
//one need to use this helper function if he wants to use the chip in both
//no decode and decode modes.
unsigned int8 reverse(unsigned int8 nd_data)
{
   int1 D[8];
   unsigned int8 i;
   unsigned int8 temp;
   for(i=0;i<8;i++)
   {
      if(shift_left(&nd_data, 1, 0))
         D[i]=1;
      else
         D[i]=0;
   }
   temp=D[1];
   D[1]=D[7];
   D[7]=temp;
   
   temp=D[2];
   D[2]=D[6];
   D[6]=temp;
   
   temp=D[3];
   D[3]=D[5];
   D[5]=temp;
   
   temp=0x00;
   for(i=0;i<8;i++)
      shift_left(&temp,1,D[i]);

   return temp;
}
//Quite self explanatory
//it displays a data at the address given
//1 -> 1st digit
//8 -> 8th digit
//and dis_data is the data that is to be displayed there
void display(char adresse,char dis_data)
{
 char x;
 unsigned int16 dout;
 if(nd==0)
   dis_data=reverse(dis_data);
 dout=concat(adresse,dis_data);
 output_low(LOAD);

 for (x=16;x>0;x--)
 {
  if (bit_test(dout,x-1)) output_high(DATA);
  else output_low(DATA);
  output_high(CLK);
  delay_cycles(clk_delay);
  output_low(CLK);
  delay_cycles(clk_delay);
 }

 output_high(LOAD);
}

//use this function to continously put data in the digits
//without bothering about incremanting the address
//the address increment is done automatically
void seg_putc(unsigned int8 c)
{
   display(pos,c);
   if(pos>=8)
      pos=1;
   else
      pos++;
}
//another variant of the display function if you use the hardware SPI
/*void display(char adresse,char dis_data)
{
output_low(LOAD);
spi_write(adresse);
spi_write(dis_data);
output_high(LOAD);
}*/
//Takes an array of 8 datas and put them on the digits
//the dp decides the position of the decimal point
//1 -> decimal point on 1st digit
//8 -> decimal point on 8th digit
void display_digits(unsigned int8 arr[],unsigned int8 dp)
{
      unsigned int8 i;
      //int decimal;
      if(dp>8 || dp<1)
         dp=0;
      for(i=1;i<=8;i++)
      {
         if(dp==i)
            display(i,arr[i-1]+0x80);
         else
            display(i,arr[i-1]+0x00);
      }
      pos=1;
}
//intialize the display driver chip
//it takes the argument decode that decides whether the digits are
//decoded using CODE B scheme or they are not decoded at all
//0 -> No decode
//1 -> Decode
void display_init(int1 decode)
{
 output_low(CLK);
 delay_us(1);
 output_high(LOAD);
 nd=1;
 display(0x0B,0x07);  // scan limit - 8 columns
 display(0x0C,0x01);  // Shutdown - normal mode
 if(!decode)
   display(0x09,0x00);  // decode mode = 0
 else
   display(0x09,0xFF);  // decode mode = 1
 display(0x0A,0x07);  // intensity
 nd=decode;
 pos=1;
 //display(0x0F,0x00);  // test
}


And the example code of how to use it

main.c
Code:
#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HSPLL                    //High Speed Crystal/Resonator with PLL enabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                      //No Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES NOXINST                    //Extended set extension and Indexed Addressing mode enabled
#FUSES PLL5                     //Divide By 5(20MHz oscillator input)
#FUSES CPUDIV4                  //System Clock by 4
#FUSES USBDIV                   //USB clock source comes from PLL divide by 2
#FUSES VREGEN                   //USB voltage regulator enabled
#FUSES ICPRT                    //ICPRT enabled

#use delay(clock=48000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define     DATA       PIN_D7
#define     LOAD       PIN_D6
#define     CLK        PIN_D5

#include "MAX7219.c"

void main()
{
   int data1[8]={0x38,0x77,0x6F,0x54,0x77,0x1E,0x30,0x78};  //It writes LAgnAJit
   int data2[8]={1,2,3,4,5,6,7,8};
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   //setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);



   display_init(0);           //No decode
   display_digits(data1,3);
   delay_ms(1000);
   display_init(1);           //Decode as Code B
   display_digits(data2,5);
   delay_ms(1000);
   seg_putc(4);               //update 1st digit to '4'
   delay_ms(1000);
   display(8,3);              //Update 8th digit to '3'
   
}


Here are the code: the compiled hex and cof file and the Proteus test circuit.

http://ifile.it/gj6faxs
http://rapidshare.com/files/231991833/MAX7219_Interfacing.zip
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group