Menu

MAX7221

2023-08-16
2023-08-18
  • Steve Scott

    Steve Scott - 2023-08-16

    Has anyone successfully used a MAX7221?
    I have used this but with a different compiler and using what I had used before, it throws errors.
    I am new to GCBasic but have had success with A/D, serial. etc. Now trying I2C.
    The MAx7221 uses a chip select.
    some code fragment below:
    'INIT any peripherals here
    'Init MAX7221

    I2CStart
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0A07\16) '50% intensity
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0B07\16) 'Display ALL digits (8)
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0F00\16) 'NORMAL mode
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0888\16) 'Digit 8 is BLANK
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0788\16) 'Digit 7 is BLANK
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0688\16) 'Digit 6 is BLANK
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0588\16) 'Digit 5 is BLANK
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0488\16) 'Digit 4 is BLANK
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0388\16) 'Digit 3 is BLANK
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0288\16) 'Digit 2 is BLANK
    7221_CS = 1 'Deselect the 7221
    7221_CS = 0 'Chip Select the 7221
    I2CSend ($0188\16) 'Digit 1 is BLANK
    7221_CS = 1 'Deselect the 7221

    Then I actually try to display something:
       ** 'Display Adr on MAX7221**
    7221_CS = 0                                                             'Chip Select the 7221
    I2CSend ($0877\16)                                                      'A
    7221_CS = 1                                                             'Deselect the 7221 
    7221_CS = 0                                                             'Chip Select the 7221
    I2CSend ($073D\16)                                                      'd
    7221_CS = 1                                                             'Deselect the 7221
    7221_CS = 0                                                             'Chip Select the 7221
    I2CSend ($0605\16)                                                      'r
    7221_CS = 1                                                             'Deselect the 7221
    

    As I am just starting, perhaps the answer is somewhere but I could not find it in the docs or on any user-supplied code fragments.

     
  • Jerry Messina

    Jerry Messina - 2023-08-16

    The MAX7221 has an simple serial shift register interface, like SPI.
    I wouldn't try using I2C calls with it... wrong style interface.

     
  • Steve Scott

    Steve Scott - 2023-08-16

    Yes Jerry, my mistake - up too late last night!
    This is what I have but it errors:
    'MAX7221 Settings
    #define 7221_CS PORTA.1 'Chip Select for MAX7221, active LOW
    Dir PORTA.0 Out 'Sets I2C Data as an OUTPUT
    Dir PORTA.1 Out 'Sets MAX7221 Chip Select as an OUTPUT
    Dir PORTA.2 Out 'Sets I2C Clock as an OUTPUT
    'Set SPI Mode to master, with fast clock
    SPIMode Master
    #define SPI_DO PORTA.0
    #define SPI_SCK PORTA.2
    7221_CS = 0 'Chip Select the 7221
    SendByteviaSPI (0x0A) '50% intensity
    SendByteviaSPI (0x08)
    7221_CS = 1 'Load data to the 7221

    I get an error on the 1st SendByteviaSPI....
    Am still looking through examples, etc. to figure this out.
    
     
  • David Stephenson

    You need to send an address followed by one byte of data.
    (the addresses and data are of course in the datasheet)
    Chip select
    FastHWSPITransfer address
    FastHWSPITransfer data
    Chip unselect

     
    • Anobium

      Anobium - 2023-08-17

      He is using software SPI as the port.pin selected are not supported by PPS/
      SendByteviaSPI () will have to be defined and then bit-bang the SPI out.

       
  • Steve Scott

    Steve Scott - 2023-08-17

    Yes, thank you both David and Anobium. I am forced to use software SPI and the design is working but using a different compiler. I do know how to code for the MAX7221 (If I dont stay up so late - grin).
    My problem is learning this compiler (quite capable) subtleties such as the proper syntax for using software SPI (bit banging).
    I must not have told the compiler correctly that I am using software SPI as I get errors pointing to the 1st line where I state 'SendByteviaSPI (0x0a, 0x08)' with the orange error triangle pointing to the command 'SendByteviaSPI'.
    Once I understand what the compiler wants, it will be smooth coding.....
    This is what I have told the compiler for my PIC67K40:
    'MAX7221 Settings
    #define 7221_CS PORTA.1 'Chip Select for MAX7221, active LOW
    Dir PORTA.0 Out 'Sets I2C Data as an OUTPUT
    Dir PORTA.1 Out 'Sets MAX7221 Chip Select as an OUTPUT
    Dir PORTA.2 Out 'Sets I2C Clock as an OUTPUT
    'Set SPI Mode to master, with fast clock
    SPIMode ( Master, SPI_CPOL_0 + SPI_CPHA_0 )
    #define SPI_DO PORTA.0
    #define SPI_SCK PORTA.2
    And then to set the LED intensity:
    7221_CS = 0 'Chip Select the 7221
    SendByteViaSPI (0x0A, 0x08) '50% intensity
    7221_CS = 1 'Load data to the 7221

    From what I understand this should be correct but the compiler barks and it does not compile.
    Regards.
    
     
  • Anobium

    Anobium - 2023-08-17

    What is in the sub routine SendByteViaSPI() ?

     
  • Steve Scott

    Steve Scott - 2023-08-17

    Ah, Anobium. That may be part of my problem in not knowing how to set this up in this compiler.
    I was following some examples not fully understanding what was written.
    There is no sub 'SendByteviaSPI' so that is where it is failing.
    Do you have a full example of how to use the software SPI? Clearly I am not following what has been written before.
    At the same time, I will go back and re-read some examples........ I got up at 5am local just in case!
    Thanks in advance,
    Steve

     
    • Anobium

      Anobium - 2023-08-17

      The new LCD.h has a sub routine that you can use. Locate the lcd.h in the gcbasic\include\lowlevel folder.

      There is a new SPI subroutine.

      LCD_SPI_WriteIOExpander))

      That sub sends three byte via SPI but if you cut/paste that sub into your code, then rename the sub, then the constants you have the basis of a software SPI sub.

       
  • David Stephenson

    Am I correct in the assumption that you are using a 18F67K40.
    Its got so many pins you could drive the LED display directly!(and its got 2 x I2C/SPI modules)

     
    • Anobium

      Anobium - 2023-08-17

      This is a capability for release, intended for solutions any chip.

      The specific example above, is a reference implementation.


      However, on the board I am using is has the Serial Expander attached as shown in the diagrams above.

       
      • David Stephenson

        Confusing! Apologies for completely misunderstanding the problem.

         
        • Anobium

          Anobium - 2023-08-17

          NP. 😀

           
  • Steve Scott

    Steve Scott - 2023-08-17

    Looking at it now Anobium, thanks.

     
  • Steve Scott

    Steve Scott - 2023-08-17

    OK Guys. I realize I am learning a new compiler and I may be coming here with pre-conceived ideas and philosophies from another compiler, but for the life of me - I cannot see where anyone has a SPI example that is pure software.
    There are some that make some sort of decision id hardware, but it is confusing if you are learning at the same time.
    Is there no 5 or more line example for bit-banging SPI in GCB?
    I have my Saleae poised and ready to learn SPI and I2C....
    Any help for a befudled guy is greatly appreciated.
    Regards to All.

     
    • Anobium

      Anobium - 2023-08-17

      I think I understand.

      There is no public software SPI sub routine. There are many library that have software Bit Banging SPI.

      We can easy add a Public sub routine.

       
  • Steve Scott

    Steve Scott - 2023-08-17

    I think I am learning - 'Sub' is new to me...
    It compiles without errors now that I have actually created a Sub called 'SendByteviaSPI'.
    Still no luck on the MAX7221 yet however.

     
  • kent_twt4

    kent_twt4 - 2023-08-17

    The glcd_ssd1306.h has a soft SPI implementation for sending byte size data. See the S4wire routines for Command, Data, and BitBang. A proper SPI routine would also include the receive bytes in the same sub, and I'm sure that is around someplace also.

     
  • Steve Scott

    Steve Scott - 2023-08-17

    My Saleae says I am sending the coded HEX values to the MAX7221 now.
    However, the MAX7221 does not display anything except initial all segments on.

     
  • Steve Scott

    Steve Scott - 2023-08-17

    I have tried a different timing scheme thanks Cosmok82!
    Still no joy however in the MAX7221.
    Logic Analyzer reports HEX codes are correct to the MAX7221.
    Pushing away for a bit since up at 5am to try stuff......

     
  • Steve Scott

    Steve Scott - 2023-08-17

    Thought I might not be handling the Chip Select correctly as I took care of that in the SUB, so I deleted it from the main body....
    Still MAX7221 does not respond.
    Seriously now pushing away.......

     
  • Anobium

    Anobium - 2023-08-17

    Timing... your analyser may be able to cope but please look at the timings. The transition of the SCK is 4ns.

    Look at the code below. The rotate takes a few cycles but also gives the timing delay for the clock transistion.

    Do not use single letter variables. Whilst they are supported it is very bad practice. as this can cause issue with register.bit called a single letter.

    I would rotate the address var rather than use the slower multiple routines.

        Sub SendByteviaSPI (Address, data)
          outword = (address * 256) + data
          7221_CS = 0                                                             'Chip Select the 7221
          SPI_CLK = 1
          for i = 1 to 16
            if outword.15 = 1 then
                SPI_DO = 1
            else
                SPI_DO = 0
            end if
            SPI_CLK = 0
            rotate __outword left
            SPI_CLK = 1
          next
          7221_CS = 1                                                             'Chip Select the 7221
        End Sub
    
     
  • mmotte

    mmotte - 2023-08-18

    The max 7219 is similar to the max7221

    I needed a counter to count two leds when they were blinked.

    #chip 16F886, 8
    
    
    #include <max7219_7segment.h>
    
    #define MAX7219_7seg_HardwareSPI 'comment this line for NOT hardware SPI
    #define Max7219_DO    PortC.5  'Dout Out
    #define Max7219_SCK   PortC.3  'clk Out
    #define Max7219_CS    PortC.2  'load Out
    
    #define YellowLED     PortB.0   'Carmelo Meteor detected
    #define RedLED        PortB.1   'Meteor stored
    
    dir PortB.0 in
    dir PortB.1 in
    
    
    
    Dim CountValueRed, CountValueYellow as word
    
    
    
    
    CountValueYellow = 0
    CountValueRed = 0
    updateDisp
    
    
    Mainloop:
    
    
        If YellowLED =1 then
           countValueYellow++
           Wait Until YellowLED = 0
           updateDisp
        end if
        If RedLED =1 then
           countValueRed++
           Wait Until RedLED = 0
           updateDisp
        end if 
    
      wait 200 ms
    Goto Mainloop
    
    Sub updateDisp
      clear
      Max7219_Dec 8,CountValueYellow
    
      Max7219_Dec 4,CountValueRed
    end sub
    
    Sub IncCounter
            CounterValueRed ++
    End Sub
    

    I used hardware but the software SPI is included in the MAX7219_7segment.h

    GL
    Mike

     

Log in to post a comment.