jitun
Joined: 25 Mar 2009 Posts: 5
|
MAX7219 Serial 8 digit seven segment display driver |
Posted: Tue May 12, 2009 12:49 am |
|
|
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 |
|