Eight Digit Seven-Segment Display based on MX7219
tomcrawford
Posts: 1,126
Here is an eight digit Seven-segment display based on MX7219 that recently appeared on eBay. They mostly come from China/Hong Kong and cost from $4.00 up, a little less in fives or tens. You can find plenty of them by searching MAX7219 Digital Tube (dont know where the tube part came from).
http://www.ebay.com/itm/New-MAX7219-8-Digit-Red-LED-Digital-Tube-Display-Module-Green-Board-For-Arduino-/281347153969?pt=LH_DefaultDomain_0&hash=item418198e031
It is based on the Maxim MX7219; here is a pointer to their data sheet.
http://www.maximintegrated.com/en/datasheet/index.mvp/id/1339
This module is different from the Seven-segment module discussed in some detail in this tread. That module used just shift registers and requires constant refreshing.
http://forums.parallax.com/showthread.php/157074-7-Segement-DisplayHelp-Needed
Here is a sample driver that generates random numbers in the range +-9,999,999, and calls a PASM cog to convert to BCD and write onto a single module.
Here are a couple of photos. The eBay ads all shown the module next to a metric scale but I'm enough native U.S. to not really get a good feeling for the actual size. One picture shows a module next to a good ol' USA quarter. The other shows how the LEDs are socketed. Don't know why they did that.
I will do some fiddling to drive multiple modules and post results in this thread. tc
PS: I think I now understand why the comsub instruction happened.
http://www.ebay.com/itm/New-MAX7219-8-Digit-Red-LED-Digital-Tube-Display-Module-Green-Board-For-Arduino-/281347153969?pt=LH_DefaultDomain_0&hash=item418198e031
It is based on the Maxim MX7219; here is a pointer to their data sheet.
http://www.maximintegrated.com/en/datasheet/index.mvp/id/1339
This module is different from the Seven-segment module discussed in some detail in this tread. That module used just shift registers and requires constant refreshing.
http://forums.parallax.com/showthread.php/157074-7-Segement-DisplayHelp-Needed
Here is a sample driver that generates random numbers in the range +-9,999,999, and calls a PASM cog to convert to BCD and write onto a single module.
{Demo MX7219 Seven-segment display: Single stick} CON _clkmode = xtal1 + pll16x 'Standard clock mode _xinfreq = 5_000_000 '* crystal frequency = 80 MHz CS = 0, CLK = 1, DI = 2 'Mx7219 Pins VAR long BinValue, BCDValue, random 'input, result, randomizer byte Flag 'value input available long MyParm[5] 'passing addresses to display driver byte Cog OBJ pst : "parallax serial terminal" PUB main pst.Start (115_200) 'start up ser terminal pst.str(String("hello, world ")) 'runs in cog 1 pst.NewLine waitcnt(clkfreq/10 + cnt) MyParm[0] := @BinValue 'argument to driver cog MyParm[1] := @BCDValue 'value displayed MyParm[2] := @Flag 'valid inpiut available MyParm[3] := Constant((CS << 16) | (CLK << 8) | DI) 'the pins cog := cognew(@PCog, @MyParm) 'start up the output cog pst.str(String("Panel Cog: ")) ' pst.hex(Cog,1) pst.NewLine waitcnt(clkfreq/10 + cnt) repeat 'forever binvalue := random? // 9_999_999 'new argumwent in rangw -9,999,999..9,999,999 Flag := 1 'tell cog to convert repeat while flag <> 0 'tis he gets done pst.dec(BinValue) 'display input in decimal pst.str(string(" ")) pst.hex(BCDValue,8) 'display my result pst.Newline waitcnt(clkfreq*5+cnt) DAT PCog org 0 'This PASM cog converts bin2BCD, displays on a 7 segment panel mov AdPar,Par 'get the address of input parameters rdlong AdBin, AdPar 'Address in main memory of input argument add AdPar, #4 rdlong AdBCD, AdPar 'result add AdPar, #4 rdlong AdFlag, AdPar 'run flag add AdPar ,#4 rdlong APins, AdPar 'get the pins mov Work1, APins 'copy of pins shr Work1, #16 'scale chip select pin number and Work1, #$1F 'extract just pin number mov CSMask, #1 'single bit mask shl CSMask, Work1 'scaled or outa, CSMask 'CS starts out high or dira, CSMask 'enabled mov Work1, APins 'clk mask is just the same shr Work1, #8 and Work1, #$1F mov ClkMask, #1 shl ClkMask, Work1 or dira, ClkMask mov Work1, APins 'and data pin and Work1, #$1F mov DMask, #1 shl DMask, Work1 or dira, DMask 'start up the Mx7219 Array mov Shifter, StDown 'shut down: get initial control call #Commo mov Shifter, Decode 'decode all digits call #Commo mov Shifter, Intens 'medium intensity call #Commo mov Shifter, ScanAll 'scan all digits call #Commo mov Shifter, Normal 'normal operation call #Commo Wait rdbyte Work1, AdFlag wz 'get the flag if_Z jmp #Wait 'no bits set, wait here rdlong BinIn, AdBin 'get input argument mov Accum, BinIn 'copy in case it is positive mov BCDOut, #$F 'decodes to blank. Positive result test BinIn, SignBit wz 'see if it is negative if_Z jmp #L1 'jump if positive mov accum, #0 'negative input sub Accum, BinIn 'covert to pos mov BCDOut, #$A 'decodes as minus sign L1 mov CSI, CSub 'get nice fresh copy of cmpsub instruction mov DigCnt, #7 'will do seven digits L2 shl BCDOut, #4 'shift the current results CSI nop 'becomes compare/sub instruction if_NC jmp #L3 'subtract was impossible add BCDOut, #1 'subtract took place, increment result 'if_Z jmp #L4 'special case of exactly done 'try uncommenting to see why this won't work jmp #CSI 'continue with same subtractor L3 add CSI, #1 'go on to next power of 10 djnz DigCnt, #L2 'for all seven powers of 10 'ok the conversion is complete L4 wrlong BCDOut, AdBCD 'stash result in hub memory call #OneModule 'write one eight-digit module wrbyte zero, AdFlag 'indicate done jmp #Wait OneModule mov Work1, #8 'we will do eight registers mov work2, #$100 'this will be the register address in MX7219 OneML mov Shifter, BCDOut 'into shifter and Shifter, #$F 'just four bits or Shifter, Work2 'register number 'or shifter, #$80 'for decimal point andn outa, CSMask 'chip select active shl shifter, #16 'scale for shift call #Shift ror BCDOut, #4 'next four bits into D3..0 'MX is wired with digit 0 on the right or outa, CSMask 'take away chip select (LOAD) add Work2, #$100 'to next register djnz work1,#OneML 'eight times for eight registers (digits) OneModule_ret ret Commo andn outa, CSMask 'chip select: send contents of command[31..16] eight times CommoLp Call #Shift 'always shifts left 16 bits or outa, CSMask 'turn off CS Commo_Ret ret Shift mov BitC, #16 'serialize shifter[31..16] to left for 16 bits SLoop rol shifter, #1 wc 'get next bit into carry if_C or outa,DMask 'set data bit if needful if_NC andn outa, DMask 'or reset it mov MyCnt, cnt 'initialize timing for this bit add MyCnt, #70 'this will be data setup waitcnt MyCnt, #80 'data setup time, set clock high time or outa, ClkMask 'clock hi waitcnt MyCnt, #150 'clock hi period, set data hold from clock down andn outa, ClkMask 'clock goes low waitcnt MyCnt, #50 'data hold from clock low djnz BitC, #SLoop 'for however many bits andn outa, DMask 'force data low Shift_Ret ret 'and return StDown long $0C00_0000 'shutdown Note prescaled for shift routine Decode long $09FF_0000 'decode all digits Intens long $0A02_0000 'modest brightness ScanAll long $0B07_0000 'scan all digits Normal long $0C01_0000 'normal operation Ten6 long 1000000 Ten5 long 100000 Ten4 long 10000 Ten3 long 1000 Ten2 long 100 Ten1 long 10 Ten0 long 1 SignBit long $8000_0000 Zero long 0 CSub cmpsub Accum, Ten6 wc, wz 'fresh copy of compare, subtract BinIN res 'input in Binary BCDOut res 'Output in signed BCD AdPar res 'address of parameter list AdBCD res 'result AdFlag res 'run flag AdBin res 'input Accum res 'running remainder APins res CSMask res 'pin masks ClkMask res DMask res Work1 res 'couple of COG general working registers Work2 res BitC res '16 bits in each register Command res 'used for global commands Shifter res 'variable being shifted MyCnt res 'used to time shifters DigCnt res 'counts the digits fit 150
Here are a couple of photos. The eBay ads all shown the module next to a metric scale but I'm enough native U.S. to not really get a good feeling for the actual size. One picture shows a module next to a good ol' USA quarter. The other shows how the LEDs are socketed. Don't know why they did that.
I will do some fiddling to drive multiple modules and post results in this thread. tc
PS: I think I now understand why the comsub instruction happened.
Comments
Thanks for posting your code.
http://youtu.be/JH0_inuzoO4
I had tried "daisy-chaining" the sticks, but there was way too much VCC drop to do more than a couple. So I connected them in parallel, so to speak, with common clock and data, separate chip selects.
You can use the MUXC instruction to replace these two lines of code:
with...
Perhaps my wife was right about reading the Prop Manual in bed after all.
I should point out that pull-ups on the CS pin(s) are really really Good. I think the MX7219 gets very confused if CS is undefined when power comes on and goes into some odd state a lot like lamp test except it ignores anything you tell it. Seems to me that Duane Degn and I found this during the MX7219 8x8 module days. I use 20K to +5V and that seems to work. Also 20K to +5V shouldn't fry the prop pin.
All BS2 examples use 4 digits with MAX7219, had no luck running 8 digits on it.
This should get you started. Remember, DIG is your friend.
I've set decide register to 0X00 and now assigning varios data to Sword variable displays various segments lit, however, it is hard to determine,which digit does what.
The high order byte of SWORD specifies which digit is written (1..8) and the low order byte specifies which segments are lit. Be systematic and write values with a single bit set in the SWLO field, one at a time, and write down on a piece of paper which bit controls which segment. Then decide which combinations are pleasing.
Or you could look at the data sheet, Table 6 on page 8.
tc
The "Drive" portion works fine, I see "0 1 2 3 " on display (using 4 digit right now)
but the code below works not as planned. Even if SWLO=%00000001, 4 segments lit up - G segments in char 2,3,4 and B segment in char 4. If the wiring was incorrect, then "0 1 2 3" should not be displayed, right?