A generic library to support Max7221 chip for 8 digit 7 segment displays

Dependencies:   mbed

Dependents:   Example_Max7221

MAXIM SPI interfaced, 8 digit LED display Driver

MAX221

  • The image below was my initial development setup. The top of the image shows a wire wrap connection to a Max7221 to an 8 digit 7 segment display.
  • The small board below it is the new max7221 board that was created with surface mount chips and using a toaster oven to do reflow soldering. /media/uploads/jakowisp/img_0012.jpg

Example of using a single Max7221 on SPI p5,p6,p7

Import program

00001  #include "mbed.h"
00002  #include "Max7221.h"
00003  
00004 
00005 // p5: DIN, p7: CLK, p8: LOAD/CS
00006 Max7221 max7221disp1(p5, p7, p8);
00007 //Max7221 max7221disp2(p5, p7, p8);
00008 //Max7221 max7221disp3(p11, p13, p14);
00009 //Max7221 max7221disp4(p11, p13, p14);
00010 
00011 int count=-99;
00012 
00013 void loop(void) {
00014    max7221disp1=count;
00015    if (count < 100)
00016       count=count+1;
00017    else 
00018       count=-99; 
00019 }
00020 
00021 int main() {  
00022     max7221disp1.Setup();
00023     //Max7221::SetupALl();
00024     max7221disp1.WriteFloat(123.125);
00025     wait(1.0);  
00026 
00027     while (1) {
00028         loop();
00029         wait(1.0);
00030     }
00031 }
00032 
00033 
Revision:
3:5abc4047af8d
Parent:
2:828c62cc1861
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Max7221.cpp	Wed Aug 07 02:34:59 2013 +0000
@@ -0,0 +1,272 @@
+/**
+* @file Max7221.cpp
+* @brief This file defines the Max7221 class methods and the default values for static variables
+* 
+* @author Dwayne S. Dilbeck
+*
+* @date 8/6/2013
+*/
+#include "mbed.h"
+#include "Max7221.h"
+
+///Intialize the Class static members
+///Devices used per SPI bus are set to ZERO
+int Max7221::maxInUseSPI1 = 0;
+int Max7221::maxInUseSPI2 = 0;
+///Set the static pointers to the SPI busses to NULL
+SPI *Max7221::spi1=NULL;
+SPI *Max7221::spi2=NULL;
+///Set the static pointers to the load signals to NULL
+DigitalOut *Max7221::load1=NULL;
+DigitalOut *Max7221::load2=NULL;
+
+/**
+*  Constructor. This is the default constructor
+*  @author Dwayne S. Dilbeck
+*  @param msoi  The SPI pin used as input to the device.       Valid values for LPC1768 are p5 or p11
+*  @param mclk  The SPI pin used as clock for the device.      Valid values for LPC1768 are p7 or p13
+*  @param load  The pin used to control load for the device.   Any pin capable for DigitalOut can be used, but the same load pin must be used for 
+*    device that share the same msoi and mclk pins
+*  @date 8/6/2013
+*/
+Max7221::Max7221(PinName msoi, PinName mclk, PinName load){
+   ///Determine which bus we are connecting the device to based on the MSOI pin name
+   switch (msoi) {
+     ///If using SPI bus #1
+     case p5: maxInUseSPI1++; 
+              ///Set this insctance to pointers to the correct static pointers
+              this->id=maxInUseSPI1;
+              this->maxInUse=&maxInUseSPI1;
+              ///If no devices have been assigned to the SPI bus it must be initialized
+              if (spi1 ==NULL) {
+                 spi1 = new SPI(msoi, NC, mclk);
+                 load1 = new DigitalOut(load);
+              } else {
+                ///TODO: Check that load pin is the same for all SP2 
+              }
+              this->max72_spi=spi1;
+              this->load = load2;
+              break;
+     ///If using SPI bus #2
+     case p11: maxInUseSPI2++;  
+              ///Set this insctance to pointers to the correct static pointers
+              this->id=maxInUseSPI2;
+              this->maxInUse=&maxInUseSPI2;
+              ///If no devices have been assigned to the SPI bus it must be initialized
+              if (spi2 ==NULL) {
+                 spi2 = new SPI(msoi, NC, mclk);
+                 load2 = new DigitalOut(load);
+              } else {
+                ///TODO: Check that load pin is the same for all SP2 
+              }
+              this->max72_spi=spi2;
+              this->load = load2;
+              break; 
+     ///If a pin not belonging to a SPI bus is used, Throw error
+     default: error("Not a SPI port");
+   }
+   
+}
+
+/**
+*  This method is used to write a byte of data to a specified register for only the device defined in this class instance
+*  @author Dwayne S. Dilbeck
+*  @param reg  The register to write to.
+*  @param data The value to be written.
+*  @date 8/6/2013   
+*//**
+*  This method is used to write a byte of data to a specified register for only the device defined in this class instance
+*  @author Dwayne S. Dilbeck
+*  @param reg  The register to write to.
+*  @param data The value to be written.
+*  @date 8/6/2013   
+*/
+void Max7221::Write( unsigned int reg, unsigned int data) {
+    int c = 0;
+    *load = LOW;
+
+    ///if there are multiple devices sharing the SPI buss and they preceed the current device in the cascade Write a NOOP to them
+    for ( c = *maxInUse; c > this->id; c--) {
+        max72_spi->write(0);  // no-op
+        max72_spi->write(0);  // no-op
+    }
+    ///Write to this device registers
+    max72_spi->write(reg);  // specify register
+    max72_spi->write(data);  // put data
+
+    ///if there are multiple devices sharing the SPI buss and they follow the current device in the cascade Write a NOOP to them
+    for ( c=this->id-1; c >= 1; c--) {
+        max72_spi->write(0);  // no-op
+        max72_spi->write(0);  // no-op
+    }
+    *load = HIGH;
+}
+
+/**
+*  This method is used to write an  intial set off values to the device to prepare it for use.
+*  @author Dwayne S. Dilbeck
+*  @date 8/6/2013   
+*/   
+void Max7221::Setup () {
+    // initiation of the max 7221
+    // SPI setup: 8 bits, mode 0
+    max72_spi->format(8, 0);
+    
+    // going by the datasheet, min clk is 100ns so theoretically 10MHz should work...
+    max72_spi->frequency(10*MHZ);
+    
+    Write(max7219_reg_scanLimit, 0x07);   ///ENABLE all 8 digits
+    Write(max7219_reg_decodeMode, 0xff);  // Turn on Code B font decode for all digits
+    Write(max7219_reg_shutdown, 0x01);    // Disable shutdown mode
+    Write(max7219_reg_displayTest, 0x00); // Disable display test
+    for (int e=1; e<=8; e++) {            // Write blank to all digits
+        Write(e,0xf);
+    }
+    Write(max7219_reg_intensity, 0x01 );    // Set the display intensity to a low level. 
+                                                  // range: 0x00 to 0x0f
+}
+
+/**
+*  This method is used to write a byte of data to a specified register for all the devices instantiated.
+*  @author Dwayne S. Dilbeck
+*  @param reg  The register to write to.
+*  @param data The value to be written.
+*  @date 8/6/2013   
+*/   
+void Max7221::WriteAll (unsigned int reg, unsigned int data) {   
+    ///Write to all the devices on SPI Bus #1 first
+    if(load1 !=NULL) {
+        *load1 = LOW;                    // begin
+        for ( int c=1; c<= maxInUseSPI1; c++) {
+            spi1->write(reg);  // specify register
+            spi1->write(data);  // put data
+        }
+        *load1 = HIGH;
+    }
+    ///Write to all the devices on SPI Bus #2
+    if(load2 !=NULL) {
+        *load2 = LOW;
+        for ( int c=1; c<= maxInUseSPI2; c++) {
+            spi2->write(reg);  // specify register
+            spi2->write(data);  // put data
+        }
+        *load2 = HIGH;
+    }
+}
+/**
+*  This method is used to display an integer to the specified device instance. Underflow and overflow result in '-' written to all digits
+*  @author Dwayne S. Dilbeck
+*  @param value  An integer value to display
+*  @date 8/6/2013   
+*/   
+void Max7221::WriteInt( int value ){
+  char buffer[16];
+   
+  ///TODO:SET UPPERBOUND AND LOWERBOUND based on NUMDIGITS
+  ///Check the the INT value can be displayed and convert to a string.
+  if (value <= UPPERBOUND && value >= LOWERBOUND) {
+     sprintf(buffer,"%8d",value);
+  } else {
+     sprintf(buffer,"--------");
+  } 
+  ///In case a program changed the decode mode, set it again.
+  Write(max7219_reg_decodeMode, 0xff);
+  for (int i=0;i<NUMDIGITS;i++) {
+       ///For each character of the string, convert the ASCII to the datacode needed by the device
+       switch(buffer[i]){
+           case 0x2d: buffer[i]=0xa; break;
+           case 0x20: buffer[i]=0xf; break;
+           default: buffer[i]= buffer[i] & 0x0f;
+       }
+       ///Call function to write the data for each character of the srting.
+       Write(NUMDIGITS-i,buffer[i]);
+  }
+}
+
+/**
+*  This method is used to display a floating point number to the specified device instance. 
+*   Underflow and overflow result in '-' written to all digits. The digits after the decimal 
+*   point are truncated to fit the display.
+*  @author Dwayne S. Dilbeck
+*  @param value  A float value to display
+*  @date 8/6/2013   
+*/   
+void Max7221::WriteFloat( float value ){
+  char buffer[32];
+  int ptr=-1,len;
+  int i;
+ 
+  sprintf(buffer,"%f",value);
+  len=strlen(buffer);
+  i=len-1;
+  while(buffer[i]==0x30) {
+     buffer[i]='\0';
+     i--;
+     len--;
+  }
+  for( i =0; i<=len; i++) {
+      switch(buffer[i]){
+               case 0x2d: buffer[i]=0xa; break;
+               case 0x20: buffer[i]=0xf; break;
+               case 0x2e: buffer[i]=buffer[i-1] | 0x80;
+                           ptr = i-1;
+                           break;
+               default: buffer[i]= buffer[i];
+      }       
+      if (ptr != -1) {
+        buffer[i-1]=buffer[i]; 
+     }
+  }
+     
+  len=strlen(buffer);
+  Write(max7219_reg_decodeMode, 0xff);
+
+  // If too large for display set to '-'
+  if(len > NUMDIGITS && (ptr==-1 || ptr>NUMDIGITS))
+        for (int i=0;i<NUMDIGITS;i++) {
+           buffer[i]=0x0a;
+        }
+  //if number is smaller than display, fill with ' '      
+  if (len<=NUMDIGITS) { 
+      for (int i=1;i<=NUMDIGITS;i++) {
+           if(len-i>=0) {
+             Write(i,buffer[len-i]);
+           } else {
+             Write(i,0xf);   
+           }
+      }
+  } else {
+  //Write out the buffer, truncating the decimal digits if larger than display
+      for (int i=0;i<NUMDIGITS;i++) {
+          Write(NUMDIGITS-i,buffer[i]);
+      }
+  }
+}
+
+/**
+*  This method is used to write an intial set off values to ALL device to prepare them for use.
+*  @author Dwayne S. Dilbeck
+*  @date 8/6/2013   
+*/   
+void Max7221::SetupAll () {
+    // initiation of the max 7219
+    // SPI setup: 8 bits, mode 0
+    if(spi1!=NULL) {
+       spi1->format(8, 0);
+       spi1->frequency(10*MHZ);    
+    }        
+    if(spi2!=NULL) {
+       spi2->format(8, 0);
+       spi2->frequency(10*MHZ);    
+    }        
+    WriteAll(max7219_reg_scanLimit, 0x07);
+    WriteAll(max7219_reg_decodeMode, 0xff);  // using an led matrix (not digits)
+    WriteAll(max7219_reg_shutdown, 0x01);    // not in shutdown mode
+    WriteAll(max7219_reg_displayTest, 0x00); // no display test
+    for (int e=1; e<=8; e++) {            // empty registers, turn all LEDs off
+        WriteAll(e,0xf);
+    }
+    WriteAll(max7219_reg_intensity, 0x01 & 0x0f);    // the first 0x0f is the value you can set
+                                                  // range: 0x00 to 0x0f
+}
+