MAX7219 7-Segment Display

Voorbeeld code om het MAX7219 7 segment 8 digit display te testen voor de Proton picbasic compiler.
De MAX7219 wordt aangesloten met 1 data lijn (Din), 1 klok lijn (Clk) en 1 load lijn (CS) (3 draads). Data en klok lijn worden parallel aan eventueel meerdere displays aangesloten. De load lijnen zijn per display.

Deze code maakt het normale “print” commando dat gebruikt wordt bij LCD (Hitachi 44780 controller) displays bruikbaar voor de MAX7219.
Met deze code kunnen alleen cijfers 0-9 en de karakters H, h, E, e, L, l, P, p, – en . geprint worden.
Indien een . geprint wordt zal deze weergegeven worden op de decimale punt locatie van het vorige karakter.(neemt dus geen extra digit in)

Print at 1,1, “12.34.56.16” (11 karakters) geeft:


Tot maximaal 4 MAX7219 displays zijn te benaderen met het “print” commando.
Je geeft dit aan door de cursor te positioneren met “At”.
Print At 1,8, “1” zal een “1” printen op het 1e display op het 8e digit (rechts)
Print At 2,1, “1” zal een “1” printen op het 2e display op het 1e digit (links)
Indien je geen “At” gebruikt zal de volgende print opdracht verder gaan waar de cursor gebleven was.
De onderstaande code is bedoeld voor 2 MAX7219 displays, wil je meer dan
zullen Display3 en Display4 ook gedefinieerd moeten worden met de
bijbehorende load pinnen.

Demo code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
'****************************************************************
'*  Name    : MAX7219 7 segment 8 digit print test              *
'*  Author  : Knutselaar.eu                                     *
'*  Notice  : Copyright (c) 2019                                *
'*          : All Rights Reserved                               *
'*  Date    : 29-5-2019                                         *
'*  Compiler: 3.5.8.6 (Proton picbasic)                         *
'*  Version : 1.0                                               *
'*  Notes   : Free to use demo software                         *
'*          : Not for commercial use                            *
'****************************************************************
    Device = 18F25K22

    Xtal = 8  
             '76543210                    
    OSCCON = %01100110  ;8 mhz,int-osc
    ANSELB = %00000000  ;Port B Digital
    TRISB  = %00000011  ;B7-2 output
   
    Symbol Seg7Dta           = LATB.7   '  MAX7219 data pin (DIN)     (use PORTB.5 for 16Fxxxx devices)
    Symbol Seg7Clk           = LATB.6   '  MAX7219 clock pin (CLK)
    Symbol Seg7Load          = LATB.5   '  MAX7219 load pin (CS) 1e display
   
    $define Display2
    Symbol Seg7Load2         = LATB.4   '  MAX7219 load pin 2e display
   
    ''$define Display3
    'Symbol Seg7Load3         = LATB.3   '  MAX7219 load pin 3e display
   
    ''$define Display4
    ''Symbol Seg7Load4         = LATB.2   '  MAX7219 load pin 4e display
   
    Dim test As Byte

   Clear
   
    Include "MAX7219PrintCommand.inc"   ' sent "print" output to MAX7219 7 segment display controller via ISP
   
    Print At 1,1, "12345678"

loop:  

    DelayMS 2000
   
    Print Cls
   
    Print At 1,7, "1.2"        ;with decimal point
   
    For test = 16 To 32        ;this demonstrate 16 step light intensity
        DelayMS 500
        Print $FE, test
        Print At 1,7, Dec2 test - 16
    Next test
   
    DelayMS 1000
   
    Print At 2,1, "3.4"        ;second display (will print on the first if Display2 is NOT defined)
   
    For test = 16 To 32        ;this demonstrate 16 step light intensity on the second display
        DelayMS 500            ;it acts on th 2e display now because that is the latest accessed by the "print" command.
        Print $FE, test
        Print At 2,7, Dec2 test - 16
    Next test
   
    ;DelayMS 1000
   
    ;Print At 3,7, "56"        ;in case you hook up a third display
   
    ;DelayMS 1000
   
    ;Print At 4,1, "78"         ;in case you hook up a fourth display
   
    DelayMS 1000
   
    Print At 1,1, "  -help "    ;supported non number signs
   
    DelayMS 2000
   
    Print $FE, 3                ;this will set the last accessed dispay (in this case the first)into standby (dark)
   
    DelayMS 2000
   
    Print $FE, 4                ;this will set the last accessed dispay into normal mode (on)
                                ;can be used for blink
 
GoTo loop
   

 Config_Start    
     FOSC = INTIO67              ;Internal oscillator block, port function on RA6 and RA7  
     FCMEN = Off                 ;Fail-Safe Clock Monitor disabled
     IESO = Off                  ;internal external switchover mode
     PWRTEN = On                 ;power-up timer
     BOREN = On                  ;brown-out reset
     BORV = 190                  ;brown-out reset value (2,7V)
     WDTEN = SWON                ;watchdog timer
     WDTPS = 128                 ;1:128 WDT prescalar
     PBADEN = Off                ;analog port B<4:0>
     STVREN = On                 ;stack overflow reset
     LVP = Off                   ;low voltage programming
     XINST = Off                 ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
     Debug = Off                 ;no debug
Config_End

Incude file: “MAX7219PrintCommand.inc”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
'*****************************************************************************************************************
'*  Name    : MAX7219PrintCommand.inc                                                                            *
'*  Purpose : allow Proton PIC Basic Print commands to access the MAX7219 7 segment 8 digit display              *
'*  Author  : Knutselaar.eu                                                                                      *
'*  Notice  : Copyright (c) 2019                                                                                 *
'*          : All Rights Reserved                                                                                *                                                                                    
'*  Date    : 29/05/2019                                                                                         *
'*  Compiler: 3.5.8.6                                                                                            *
'*  Version : 1.0                                                                                                *
'*  Notes   : Free to use demo software                                                                          *
'*          : Not for commercial use                                                                             *                                                                                        
'*          : This programm uses the MAX7219 in BCD decode mode                                                  *
'*                                                                                                               *
'*  Print $FE,3  set the MAX7219 into standby mode (low power, display off)                                      *
'*  Print $FE,4  set the MAX7219 into normal mode (can be used for blinking purpose also)                        *
'*  Print $FE,16 to Print $FE,31 set the brightness of the display in 16 staps)                                  *                                                                  
''****************************************************************************************************************
 
  #Disable Print                                     ;Disable the Proton Print command    
 
  Symbol  SegmentQuantity          = 7               ;aantal digits - 1 (0 telt ook mee)                                                  
  Symbol  SegmentBrightness        = 8               ;brightness 0 - 15
 
  Dim seg7Print_Initialised As Byte = 0
  Dim seg7Print_Store       As Byte
  Dim seg7Print_Data        As Byte
  Dim seg7Print_Flag        As Byte  
  Dim seg7Register          As Byte                                                          
  Dim seg7R_Val             As Byte
  Dim seg7DisplayNr         As Byte = 1
 
  ' The following Variables should be defined in your main programm
 
  ' Symbol Seg7Dta           = LATB.7   '  MAX7219 data pin      (use PORTB.5 for 16Fxxxx devices)
  ' Symbol Seg7Clk           = LATB.6   '  MAX7219 clock pin
  ' Symbol Seg7Load          = LATB.5   '  MAX7219 load pin
  ' Symbol Seg7Load2         = LATB.4   '  MAX7219 load pin only for 2th display
  ' Symbol Seg7Load3         = LATB.3   '  MAX7219 load pin only For 3th display
  ' Symbol Seg7Load4         = LATB.2   '  MAX7219 load pin only For 4th display                                                                                                                  
 
  GoTo Seg7PrintCommand_End
 
 ;****************************************************************************************************************
 
  @Print                                               ; assembler Print redirect
                                                       
    Wreg_Byte seg7Print_Data                           ; save the W Register
   
    seg7Print_Store = seg7Print_Data                    
 
    If seg7Print_Initialised = 0 Then                  ; initialize
 
        seg7Register = 11                              ' Point to the Scan Register
        seg7R_Val = SegmentQuantity                    ' Number of segments
        seg7DisplayNr = 1
        GoSub Seg7Transfer                             ' Transfer this 16-bit Word to the MAX7219
        $ifdef Display2
            seg7DisplayNr = 2                          ' Init 2e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display3
            seg7DisplayNr = 3                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display4                                
            seg7DisplayNr = 4                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
   
        seg7Register = 10                              ' Point to the Luminance Register
        seg7R_Val = SegmentBrightness                  ' Value for Brightness
        seg7DisplayNr = 1
        GoSub Seg7Transfer                             ' Transfer this 16-bit Word to the MAX7219
        $ifdef Display2
            seg7DisplayNr = 2                          ' Init 2e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display3
            seg7DisplayNr = 3                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display4                                
            seg7DisplayNr = 4                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
       
        seg7Register = 9                               ' Point to BCD Decode Register
        seg7R_Val = %11111111                          ' Decode all 8 digits
        seg7DisplayNr = 1
        GoSub Seg7Transfer                             ' Transfer this 16-bit Word to the MAX7219
        $ifdef Display2
            seg7DisplayNr = 2                          ' Init 2e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display3
            seg7DisplayNr = 3                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display4                                
            seg7DisplayNr = 4                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
       
        seg7Register = 12                              ' Point to the Switch Register
        seg7R_Val = 1                                  ' Set to One, (switches the display ON)
        seg7DisplayNr = 1
        GoSub Seg7Transfer                             ' Transfer this 16-bit Word to the MAX7219
        $ifdef Display2
            seg7DisplayNr = 2                          ' Init 2e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display3
            seg7DisplayNr = 3                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display4                                
            seg7DisplayNr = 4                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
       
        seg7Register = 15                              ' Point to the Test Register
        seg7R_Val = 0                                  ' Reset to Zero, (turns off Test mode)
        seg7DisplayNr = 1
        GoSub Seg7Transfer                             ' Transfer this 16-bit Word to the MAX7219
        $ifdef Display2
            seg7DisplayNr = 2                          ' Init 2e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display3
            seg7DisplayNr = 3                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
        $ifdef Display4                                
            seg7DisplayNr = 4                           ' Init 3e display
            GoSub Seg7Transfer
        $endif
       
        GoSub Seg7Blank                                 ' Blank (all) display(s)
       
        Set seg7Print_Initialised                      ; Indicate that the LCD is initialized
       
        seg7Register = SegmentQuantity + 1              ; shift to the left
        seg7Print_Flag = 1                              ; data / command flag
   
    EndIf
 
    seg7Print_Data = seg7Print_Store
   
    If seg7Print_Data = 0xFE Then                       ; it is a command header
        seg7Print_Flag = 0                              ; clear a flag so we know the next byte will be a command
    Else
        If seg7Print_Flag = 0 Then                      ; command byte  (At, Cls, standby, brightness)
            Select seg7Print_Store
                Case 1
                    GoSub Seg7Blank                     ; blank  Cls
                    seg7Register = SegmentQuantity + 1  ; reset position to left
                Case 3
                    seg7Register = 12                   ' Point to the Switch Register
                    seg7R_Val = 0                       ' Set to Zero, (switches the display OFF)
                    GoSub Seg7Transfer                  ' Transfer this 16-bit Word to the MAX7219
                Case 4
                    seg7Register = 12                   ' Point to the Switch Register
                    seg7R_Val = 1                       ' Set to One, (switches the display ON)
                    GoSub Seg7Transfer                  ' Transfer this 16-bit Word to the MAX7219
                Case 16 To 31
                    seg7Register = 10                   ' Point to the Luminance Register
                    seg7R_Val = seg7Print_Store - 16    ' Value for Brightness
                    GoSub Seg7Transfer                  ' Transfer this 16-bit Word to the MAX7219
                Case 128 To 135                         ; set position 1-8 for line 1  (print at 1,x)
                    seg7DisplayNr = 1
                    seg7Register = (SegmentQuantity + 1) - (seg7Print_Store - 128)
                Case 192 To 205                         ; set position 1-8 for 2th display (Print At 2,x)
                    $ifdef Display2
                        seg7DisplayNr = 2
                    $endif
                    seg7Register = (SegmentQuantity + 1) - (seg7Print_Store - 192)
                Case 148 To 155
                    $ifdef  Display3                         ; set position 1-8 for 3th display (Print At 3,x)
                        seg7DisplayNr = 3
                    $endif
                    seg7Register = (SegmentQuantity + 1) - (seg7Print_Store - 148)
                Case 212 To 219                         ; set position 1-8 for 4th display (Print At 4,x)
                    $ifdef  Display4
                        seg7DisplayNr = 4
                    $endif
                    seg7Register = (SegmentQuantity + 1) - (seg7Print_Store - 212)
            End Select
        Else                                             ; data byte
            Select seg7Print_Store
                Case 32                                  ; space
                    seg7R_Val = 15
                Case 45                                  ; minus sign
                    seg7R_Val = 10
                Case 46                                  ; dot (this is a reprint of the previous character together with the dot)
                    seg7Register = seg7Register + 1      ; shift back (left)
                    seg7R_Val = seg7R_Val + 128          ; 7th digit (128) of the byte will set te decimal point.
                Case 69, 101                              ; E, e
                    seg7R_Val = 11
                Case 72, 104                              ; H, h
                    seg7R_Val = 12
                Case 76, 108                              ; L, l
                    seg7R_Val = 13
                Case 80, 112                              ; P, p
                    seg7R_Val = 14
                Case 48 To 57                               ; 0 - 9
                    seg7R_Val = seg7Print_Store
                Case Else
                    ;seg7R_Val = seg7Print_Store
                    ;seg7Register = seg7Register - 1      ; ingnore non supported characters
                    ;or
                    ;seg7R_Val = 15                       ; blank non supported characters
                    ;or
                    ;seg7R_Val = 15  + 128                ; blank with dot non sopprted characters
            End Select                                    
            GoSub Seg7Transfer
            seg7Register = seg7Register - 1             ; position shift to the next (right)      
        End If
        seg7Print_Flag = 1                              ; set the flag so the next byte will be send as Data
    End If
                           
    Byte_Wreg seg7Print_Data                            ; restore the W register
  Return
 
' ****************************************************************************
' **                             S U B R O U T I N E S                      **
' ****************************************************************************

Seg7Transfer:
    SHOut Seg7Dta,Seg7Clk,MsbFirst,[seg7Register,seg7R_Val]              ' Shift Out the Register first, then the data
    Select seg7DisplayNr
        Case 1
            High Seg7Load                                               ' The data is now acted upon
            DelayUS 2                                                   ' A small delay to ensure correct clocking times
            Low Seg7Load
        Case 2
            $ifdef Display2
                High Seg7Load2                                           ' The data is now acted upon
                DelayUS 2                                                   ' A small delay to ensure correct clocking times
                Low Seg7Load2
            $endif
         Case 3
            $ifdef  Display3
                High Seg7Load3                                               ' The data is now acted upon
                DelayUS 2                                                   ' A small delay to ensure correct clocking times
                Low Seg7Load3
            $endif
        Case 4
            $ifdef  Display4
                High Seg7Load4                                               ' The data is now acted upon
                DelayUS 2                                                   ' A small delay to ensure correct clocking times
                Low Seg7Load4
            $endif
    End Select
Return                                                          ' Exit from Subroutine
   
Seg7Blank:                                                      
    For seg7Register = 1 To SegmentQuantity + 1                 'blank all digit's on all displays
        SHOut Seg7Dta,Seg7Clk,MsbFirst,[seg7Register,15]
        High Seg7Load
        $ifdef Display2
            High Seg7Load2
        $endif
        $ifdef Display3
            High Seg7Load3
        $endif  
        $ifdef Display4
            High Seg7Load4
        $endif            
        DelayUS 2                    
        Low Seg7Load
        $ifdef Display2
            Low Seg7Load2
        $endif
        $ifdef Display3
            Low Seg7Load3
        $endif  
        $ifdef Display4
            Low Seg7Load4
        $endif            
        DelayUS 2                                          
    Next seg7Register
Return    

Seg7PrintCommand_End:

MAX7219 en MAX7219 8 digit display in de winkel.

Sinds 13 Juni 2019