The SPI hardware in the ATmega only does 8 bit multiples. You can try writing 3 bytes and hope the device ignores the last 4 bits, or you will need a software SPI library.
Would something like this work? (controlling an 8-digit 7-segment display)
for(d=0;d<=7;d++) // go through each digit position.
{
for(b=20;b>=0;b--) // for each digit, send the 20 bits out backwards
{
digitalWrite(DIN,send_array[i][b]); // write the value in send_array to the pin DIN
digitalWrite(clock,HIGH); // set the clock high so that the value of send_array will be "sent" to the MAX6921
delay(1); // wait one millisecond
digitalWrite(clock,LOW); // set the clock low
}//move onto the next bit
digitalWrite(LOAD,HIGH); //send this digit to the display
digitalWrite(LOAD,LOW); //lock the digits into the display
}//move onto the next digit
Make the delay(1) a delayMicroseconds(1)! SPI is fast (most devices support 10MHz). Also digitalWrite takes more than 1us anyhow!
Thanks for the tip - Should I just remove the delay entirely then?
Why does it take 20 bits to define a single digit to display? For a 7 segment display, there need be only 7 bits - a segment is either on or off.
I'm driving a IV-18 VFD used in LadyAda's Ice Tube project. 8 bits are used to select 7 segments + decimal, 8 additional bits are used to select which digit you want to write to (0 through 7), so that's 16 total bits. The MAX6921 used for the project has 20 outputs so I assumed you had to fill all of them. However, since you asked, maybe I can just shift in the 16 bits which are actually used and then "output" the bits to the display without filling the remaining 4 bits?
SPI is not what you want to use. SPI is not some asynchronous channel through which you can just 'send' bits. It works by shifting a buffer between master and slave, simultaneously transferring a byte (1 bit at a time) from one to the other and vice versa.
The chip you have says:
"Data is input using an industry standard 4-wire serial interface (CLOCK, DATA, LOAD, BLANK), compatibile with either Maxim's or industry-standard VFD driver and controller."
You need to get the specs on that and emulate it through software.
This doesn't clock the LOAD/LATCH pin but that's easy to add.
As TelsaFan says you may have to mod things a little bit to drive that chip although I would think that CLOCK, DATA and LOAD are the same as everything else. As for BLANK, don't know I'll have a look at the data sheet.
OK the chip is effectively just a 20-bit shift register, no smarts at all.
So one of the above bit-bang functions should work.
Another way is to use the SPI library to shift 3 bytes but offset your data within those 3 bytes, put your 20 bits in the upper 20 of the 24 bits you shift.
The Max6921 has 20 outputs but I only need to use 16 of them. Do I need to fill all 20 outputs before "pushing" the data to the output pins or can I just shift in 16 bits and then output the data?
From looking at the block diagram on page 6 timing diagram on page 8 of the datasheet, I can see that it might work if you only care about setting the outputs for OUT0-OUT15. You will notice the following:
-DOUT will be offset by 4 bits of junk data
-OUT16-OUT19 will be set by the previous loaded data
Regards,
Scott
Maxim Applications Engineer
So it looks like it's okay to use SPI and just shift in 16 bits of data, then output the bits without any issues.
SPI is not what you want to use. SPI is not some asynchronous channel through which you can just 'send' bits. It works by shifting a buffer between master and slave, simultaneously transferring a byte (1 bit at a time) from one to the other and vice versa.
I beg to disagree, you can use the hardware anyway that works, its not sacrosanct! You could use it to just send, to just receive, to send and receive, or just to send clock pulses (in sets of 8 at certain defined rates only). If the 'slave' has a select line the SPI bus can be shared with other more compliant SPI devices. On the ATmega the SPI hardware is a great way to offload cycles when clocking shift registers and the like.
On the Arduino you can even use the SPI hardware just to flash the pin13 LED!
Im not sure if thats the right part of the forum.... so im sorry if its not
Im biulding myself a VFD tube clock with 6 IV-6 tubes, and two really small ones for the dots.
Ive got the theory alv figured out, BUT I only have 2 max6921, so thats for driving 4 tubes right?
ive been thinking... can I multyplex those tubes? As together, Bs together, Cs together.... and only switching Grounds on and off, either with high transistors or spare outputs on 6921?
Am I thinking in a right direction. Is this even possible?
So you appear to need 7 segment drivers/tube
6 x 7 = 42m, so you're a couple short.
Do you need 6 full digits? Perhaps have the left-most digit just be 1 or Off, and only use 2 segments.
Then 5 digits * 7 + 2 segments = 37, and you can use 3 remaining for periods in between pairs of digits:
1H.MM.SS,
I needed to shift out 25 bits of serial data to two 16 bit serial series connected shift registers wired to the SPI pins. I just would do the transaction as four consecutive 8 bit write operations and just let the first 7 bits sent fall out to the bit bucket of the far shift register.
MarkT:
Make the delay(1) a delayMicroseconds(1)! SPI is fast (most devices support 10MHz). Also digitalWrite takes more than 1us anyhow!
Agreed. Digital read and write are HORRIBLY slow. I replaced some "digitalWrite" lines in a VFD driver with PORT = xxx and got an almost TENFOLD increase in speed!