Author Options:

How to drive serial data via (shift registers) AVR? Answered

Is there some sort of code that will allow easy serial data tranfser from an AVR to a shift register (specifically the max6921 driver)? Thanks


another question, I got all the code set up, and i just used a #define wait for all for all of the places that needed a pause in serial. I'm going to delay 200nanoseconds (0.2 microseconds) for each "wait" is the proper code for this: wait _delay_loop_1 (0.2) or is it something else?

At first I thought this was a prototype (which shouldn't be necessary--it would be in the include file.) But I checked the "include" file, and the function definition itself is there--it's compiled on the fly, not in any external library module.
void _delay_loop_1 (uint8_t)     // function desc. in prototype "form"
The _delay_loop_1() function returns a void type, and takes an 8-bit unsigned integer as an argument. It's loaded automatically when you include the "include" file for the library module at the top of your source code:
#include <util/delay_basic.h>
There's no return value, only the input argument. Here's an example usage:
// define some delay constants#define WAIT_CLK 10#define WAIT_LOAD 120// somewhere in the code_delay_loop_1(WAIT_CLK);// or_delay_loop_1(WAIT_LOAD);

The wait lengths are surely incorrect; just there to illustrate the concept.

Use of variables or explicit numbers as the argument is OK, too...

Also--since the input argument is an 8-bit unsigned integer (uint8_t), only integer values of 0-255 are legal. You cannot pass a float value (0.2), unless you "typecast" it as an integer--and it would be typecast to the nearest integer value: zero.

The other delay loop function: _delay_loop_2() takes a 16-bit integer (uint16_t), so values of 0-65535 would work...

I'll just change it to 1 then

You guys are going long on this one (1400 lines o' code) ;-)

One more thing about those delay loops--these are simple count-down loops, and don't take the clock speed into account. That's OK, as long as you recognize that changing the clock will effect the operation.

The "util/delay.h" functions (_delay_us(), etc. ) do factor in the clock speed...

...so long as you define the F_CPU constant at the top...

thanks, so I had that almost right. this is the longest code that me and dwg300 (he did most of it, like 80% of it) ever wrote, yay. lol. Right now it's about 1400 lines


9 years ago

Looking at the datasheet (pdf), it's an unusual protocol ("industry-standard VFD"), so you'd just likely write the AVR code yourself. There's nothing standard in the AVR serial hardware for this one. But it looks pretty darn simple.

Some things to note:

-- important lines for a data load are CLK, DIN and LOAD (clock, data in and load)
-- VFD data is passed in 20-bit "words"

Writing to the VFD:

Data is loaded from the DIN bus (by the max6921) on the leading edge of the rising CLK signal.

So just set DIN to the current bit value; then raise CLK, wait for it to "take," then drop CLK, load the next bit on DIN. Repeat...

...Until all 20 bits have been transferred, then drop the LOAD pin low. LOAD can be high or low during data transmission, but the "load" is triggered on the falling edge of the LOAD pin.

RE: timing--the "SERIAL INTERFACE TIMING CHARACTERISTICS" are on pages 3 and 4 of the datasheet. There's a timing diagram, too. They are fast (typical for a custom hardware protocol), but the timing for the LOAD pin is longer (us) than the CLK or DIN (ns). So just wait a little longer when LOADing.

I've played with "custom" serial protocols for some chips (Sonix SNAD01C clone), and you likely don't need a symmetrical clock. I.E., your microcontroller is providing the CLK signal. So as long as the min. timing requirements are followed, it doesn't matter if you pause during the transmission. The max6921 will probably wait patiently for the next signal.

well, that's depressing, lol. So, i'll do it manually then