Arduino en español
Circuitos con Arduino - Juan Antonio Villalpando
-- Tutorial de iniciación a Arduino --
Volver al índice del tutorial
____________________________
14B.- Módulo con 4 Display de 7 segmentos.
- Pantalla con 4 display de 7 segmentos.
- Los terminales son: VCC, SCLK, RCLK, DIO, GND.
- Alimentación de 3,3V a 5V.
- Este módulo funciona con el principio que indiqué en el tutorial anterior.
- Se van enviado los números y mediante los pulsos se enciende secuencialmente el display correspondiente.
____________________________________________________
- Códigos.
- Aquí muestro una recopilación de códigos, en cada uno de ellos se encuentra a qué terminales del Arduino debemos conectar los de este módulo.
SCLK = ShifClock.
RCLK = LatchClock.
DIO = DisplayOut
- En todos los códigos he adaptado esta configuración de terminales:
shiftClock = SCLK = 5
latchClock = RCLK = 6
displayOut = DIO = 7
Código 1 |
// TubeSevenSegment 1.05
//
// demo sketch controls 4 digit 7 segment display
// Unknown manufacturer - labelled "4-bit LED Digital Tube Module"
// timer interrupt version (previous were micros() controlled)
// 2015-05-09 by aarg
// 2015-05-11 add variable base print
// 2015-05-17 allow choice of two different internal timers
// choose system Timer1 or Timer2:
#define TIMER_USED 2
/*
- display driver supports a decimal point attribute for each character. If bit 7 of the byte in the display buffer is set, the decimal point will be displayed.
- indexed display location. A pointer is set to the display location. You can change the display buffer location just by changing the pointer,
thus you can support multiple display "windows"
-improved numeric print function. Has range check and error display,
also supports negative numbers
-allows the use of delay() and other blocking code in loop()
*/
// extended character definitions:
#define LETTER_G 16
#define LETTER_H 17
#define LETTER_J 18
#define LETTER_L 19
#define LETTER_P 20
#define LETTER_U 21
#define LETTER_SPACE 22
#define LETTER_MINUS 23
const byte numDigits = 4;
// control pin definitions:
int shiftClock = 5; //module pin label SCLK
int latchClock = 6; //module pin label RCLK
int displayOut = 7; //module pin label DIO
// count variables:
unsigned long previousCountUp = 0; // will store last time of count
const long intervalCountUp = 200; // interval at which to count (milliseconds)
unsigned long previousText = 0; // will store last time of count
const int intervalOnText = 1000; // interval at which to count (milliseconds)
const unsigned long intervalOffText = 8000; // interval at which to count (milliseconds)
unsigned long intervalText = intervalOnText; // interval at which to count (milliseconds)
unsigned long previousDecimalPoint = 0; // will store last time of count
const int intervalDecimalPoint = 80; // interval at which to count (milliseconds)
// demo variables
byte PIGS[][numDigits] =
{
{LETTER_H, 0xE, LETTER_L, LETTER_P},
{LETTER_P, 1, LETTER_G, 5},
{LETTER_G, LETTER_U, LETTER_L, LETTER_P},
{LETTER_J, LETTER_U, LETTER_G, 5},
{LETTER_SPACE, 0, 0xf, LETTER_SPACE},
{5, LETTER_L, 0, LETTER_P}
};
// standard way to set up a display buffer
byte testDigits[numDigits] = {0};
byte* displayLocation = testDigits;
int showText = 6; // overflow will reset to the first line of PIGS[]
long charCount = 0xff00; // initial demo counter value
void setup ()
{
// configure outputs:
pinMode(shiftClock, OUTPUT);
pinMode(latchClock, OUTPUT);
pinMode(displayOut, OUTPUT);
//******************************
// timer code
// Timer 1 - gives us the display segment refresh interval
#if TIMER_USED == 1
TCCR1A = 0; // reset Timer 1
TCCR1B = 0;
// TCCR1B = bit (WGM12) | bit (CS10) | bit (CS11); // configure as CTC mode
// 16 MHz clock (62.5 nS per tick) - prescaled by 256
// counter increments every 16 µS.
// There are 8 segments and 4 digits to scan every 1/60th of a second
// so we count 32 of them at 60Hz, giving a display refresh interval of 512 µS.
#define scanRateHz 120 // tested, maximum that works is 88 using Wire library and Serial
#define displayScanCount 1000000L / numDigits / 8 / scanRateHz / 8
OCR1AH = displayScanCount / 256; // count up to 32 @ 60Hz
OCR1AL = displayScanCount % 256; // count up to 32 @ 60Hz
// Timer 1 - interrupt on match (ie. every segment refresh interval)
TIMSK1 = bit (OCIE1A); // enable Timer1 Interrupt
TCNT1H = 0; // counter to zero
TCNT1L = 0; // counter to zero
// Reset prescalers
GTCCR = bit (PSRASY); // reset prescaler now
// start Timer 1
TCCR1B = bit (WGM12) | bit (CS12); // configure as CTC mode
#endif
#if TIMER_USED == 2
// Timer 2 - gives us the display segment refresh interval
TCCR2A = 0; // reset Timer 2
TCCR2B = 0;
TCCR2A = bit (WGM21) ; // configure as CTC mode
// 16 MHz clock (62.5 nS per tick) - prescaled by 256
// counter increments every 16 µS.
// There are 8 segments and 4 digits to scan every 1/60th of a second
// so we count 32 of them at 60Hz, giving a display refresh interval of 512 µS.
#define scanRateHz 60 // tested, maximum that works is 88 using Wire library and Serial
#define displayScanCount 1000000L / numDigits / 8 / scanRateHz / 16
OCR2A = displayScanCount; // count up to 32 @ 60Hz
// Timer 2 - interrupt on match (ie. every segment refresh interval)
TIMSK2 = bit (OCIE2A); // enable Timer2 Interrupt
TCNT2 = 0; // counter to zero
// Reset prescalers
GTCCR = bit (PSRASY); // reset prescaler now
// start Timer 2
TCCR2B = bit (CS21) | bit (CS22) ; // prescaler of 256
#endif
// ***** end of timer setup ******************************
} // end of setup()
void loop()
{
// no need to call the display scan routine, as it is timer driven
// Here is some non-blocking test code...
//
// see if it's time to increment the counter
unsigned long currentMillis = millis();
if (currentMillis - previousCountUp >= intervalCountUp)
{
previousCountUp = currentMillis;
// actions to perform for this interval:
if (++charCount > 10100)
{
charCount = -1010;
}
modulePrint(charCount, 10, testDigits);
// modulePrint() can be used to display any valid integer value at any time.
// So it could also display sensor readings or other information.
}
if (currentMillis - previousText >= intervalText)
{
previousText = currentMillis;
// actions to perform for this interval:
showText = ++showText % 7;
if (showText == 6)
{
displayLocation = testDigits;
intervalText = intervalOffText;
}
else
{
displayLocation = PIGS[showText];
intervalText = intervalOnText;
}
}
if (currentMillis - previousDecimalPoint >= intervalDecimalPoint)
{
previousDecimalPoint = currentMillis;
// actions to perform for this interval:
for (int i = 0; i < numDigits; i++)
{
PIGS[showText % 6][random(4)] |= 0x80;
PIGS[showText % 6][random(4)] &= 0x7f;
}
}
} // end of loop()
//***********************************************
//
// display update ISR
//
// every time this routine is called, 16 bits are shifted into the display
// and latched.
// The first 8 bits is the segment data, and first 4 bits of the second byte are
// the segment select.
#if TIMER_USED == 1
ISR (TIMER1_COMPA_vect)
#endif
#if TIMER_USED == 2
ISR (TIMER2_COMPA_vect)
#endif
{
// segment list to make a seven segment font
const byte NUM_PLUS_SYMBOL_FONT[] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
0b01110111, // A
0b01111100, // b
0b00111001, // C
0b01011110, // d
0b01111001, // E
0b01110001, // F
0b00111101, // (71) G
0b01110110, // (72) H
0b00011110, // (74) J
0b00111000, // (76) L
0b01110011, // (80) P
0b00111110, // (85) U
0b00000000, // (32) <space>
0b01000000, // (45) -
};
static byte digit = 0;
static byte segment = 0x80;
byte tempDigit = displayLocation[digit];
// send segment data
shiftOut(displayOut, shiftClock, MSBFIRST,
~(segment & ((NUM_PLUS_SYMBOL_FONT[tempDigit & 0x7f]) | (tempDigit & 0x80))) );
// send digit select data
shiftOut(displayOut, shiftClock, MSBFIRST, 8 >> digit);
// data is now in the display shift register, so latch to LEDs
digitalWrite(latchClock, LOW);
digitalWrite(latchClock, HIGH);
// increment variables to select the next segment and possibly the next digit:
//
segment = segment >> 1;
if (segment == 0)
{
segment = 0x80;
digit++;
if (digit >= numDigits)
digit = 0;
}
}
// *********** end of display update ISR *****************
// Print an integer to the display buffer.
// Values between -xxx and xxxx will be displayed,
// where xxx's are the number of digits that will fit for a given base,
// else an error message.
//
void modulePrint(long val, byte base, byte* printLocation)
{
const byte HIGH_ERROR[numDigits] = {LETTER_H, 1, LETTER_G, LETTER_H};
const byte LOW_ERROR[numDigits] = {LETTER_MINUS, LETTER_L, 0, LETTER_MINUS};
long maxNegativeDigits = base;
for (int i = 0; i < numDigits - 2; i++) maxNegativeDigits *= base;
// validate number size for digits:
if (val >= maxNegativeDigits * base)
memcpy(printLocation, HIGH_ERROR, numDigits); //high number error message
else if (val <= -maxNegativeDigits)
memcpy(printLocation, LOW_ERROR, numDigits); //low number error message
//negative number
else if (val < 0)
{
// prepare first symbol to print when digits are exhausted
boolean needsMinusSign = true;
int posval = -val; //use the absolute value of the number
for (int i = numDigits - 1; i >= 0; i--)
{
if (posval > 0)
printLocation[i] = posval % base; // digits to print
else if (needsMinusSign)
{
printLocation[i] = LETTER_MINUS; // print one minus sign
needsMinusSign = false;
}
else
printLocation[i] = LETTER_SPACE; // the rest are spaces
posval /= base;
}
}
else // it is a positive number
{
for (int i = numDigits - 1; i >= 0; i--)
{
if (val > 0 || i == numDigits - 1)
printLocation[i] = val % base; // digits to print
else
printLocation[i] = LETTER_SPACE; // the rest are spaces
val /= base;
}
}
}
|
http://forum.arduino.cc/index.php?topic=316731.30
Código 2 |
// controls 4 digit 7 segment display
// test version 1
// 2015-04-22 by aarg
const byte numDigits = 4;
byte testDigit[numDigits];
// control pin definitions:
int shiftClock = 5;
int latchClock = 6;
int DIO = 7;
void setup ()
{
// configure outputs:
pinMode(shiftClock, OUTPUT);
pinMode(latchClock, OUTPUT);
pinMode(DIO, OUTPUT);
for (int i = 0; i < numDigits; i++)
testDigit[i] = i;
}
void loop()
{
displayUpdate(testDigit);
//
// any code in here that is non-blocking for more than the display
// refresh interval should not
// interfere with the display.
}
// non-blocking display update
//
// every time this routine is called, 16 bits are shifted into the display
// and latched.
// The first 8 bits is the segment data, and first 4 bits of the second byte are
// the segment select.
void displayUpdate(byte displayDigit[])
{
unsigned long lastDisplayUpdate;
const int scanRateHz = 60;
const int displayScanPeriod = 1000000L / numDigits / 8 / scanRateHz;
byte segmentList[] =
{ // 0123456789AbCdEF-
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x8C, 0xBF, 0xC6, 0xA1, 0x86, 0xFF, 0xbf
};
static byte digit = 0;
static byte segment = 0x80;
if (micros() - lastDisplayUpdate > displayScanPeriod)
{
// send segment data
for (byte i = 8; i >= 1; i--)
{
if ( i & (~segment | segmentList[displayDigit[digit]]) != 0)
digitalWrite(DIO, HIGH);
else
digitalWrite(DIO, LOW);
bitClock();
}
// send digit select data
for (byte i = 0; i < 8; i++)
{
if (i == digit)
digitalWrite(DIO, HIGH);
else
digitalWrite(DIO, LOW);
bitClock();
}
// data is now in the display shift register, so latch to LEDs
//
latchData();
// increment variables to select the next segment and possibly the next digit:
//
segment = segment >> 1;
if (segment == 0)
{
segment = 0x80;
digit++;
if (digit >= numDigits)
digit = 0;
}
// reset timer for next update:
lastDisplayUpdate = micros();
}
// else just return without doing anything
}
void bitClock()
{
digitalWrite(shiftClock, LOW);
digitalWrite(shiftClock, HIGH);
}
void latchData()
{
digitalWrite(latchClock, LOW);
digitalWrite(latchClock, HIGH);
}
|
Código 3 |
#define SCLK 5
#define RCLK 6
#define DIO 7
byte digitBuffer[4];
void setup(){
pinMode(RCLK, OUTPUT);
pinMode(SCLK, OUTPUT);
pinMode(DIO, OUTPUT);
}
void loop(){
digitBuffer[0] = 1;
digitBuffer[1] = 2;
digitBuffer[2] = 3;
digitBuffer[3] = 4;
showDisplay();
}
void showDisplay(){
const byte digit[10] = {
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
};
const byte chr[4] = {
0b00001000,
0b00000100,
0b00000010,
0b00000001
};
for(byte i = 0; i <= 3; i++){
digitalWrite(RCLK, LOW);
shiftOut(DIO, SCLK, MSBFIRST, digit[digitBuffer[i]]);
shiftOut(DIO, SCLK, MSBFIRST, chr[i]);
digitalWrite(RCLK, HIGH);
delay(1);
}
}
|
Código 4 |
#define SCLK 5
#define RCLK 6
#define DIO 7
byte digits[5] = {
};
byte i = 0;
boolean dp = 0;
const byte digit[] = {
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
0b11111111, //
};
byte chr[] = {
0b00001000,
0b00000100,
0b00000010,
0b00000001
};
unsigned long moneyTime = 0;
unsigned long showTime = 0;
unsigned long dpTime = 0;
int money = 0;
void setup() {
pinMode(RCLK, OUTPUT);
pinMode(SCLK, OUTPUT);
pinMode(DIO, OUTPUT);
}
void loop() {
if (millis() - moneyTime > 20) {
money++;
if (money > 9999) money = 0;
moneyTime = millis();
}
if (millis() - dpTime > 500) {
dp = !dp;
dpTime = millis();
}
if (millis() - showTime > 1) {
showDisplay(money);
showTime = millis();
}
}
void showDisplay(int v) {
digits[3] = v % 10;
v = v / 10; digits[2] = v % 10;
v = v / 10; digits[1] = v % 10;
v = v / 10; digits[0] = v % 10;
if (digits[0] == 0)digits[0] = 10;
if (digits[0] == 10 & digits[1] == 0) digits[1] = 10;
if (digits[0] == 10 & digits[1] == 10 & digits[2] == 0) digits[2] = 10;
digitalWrite(RCLK, LOW);
shiftOut(DIO, SCLK, MSBFIRST, (i == 1 && dp) ? digit[digits[i]] - 128 : digit[digits[i]]);
shiftOut(DIO, SCLK, MSBFIRST, chr[i]);
digitalWrite(RCLK, HIGH);
//delay(1000);
i++;
if (i > 3) i = 0;
}
|
Código 5 |
/*
* Sketch derived from http://www.vcc2gnd.com/2014/08/8-digit-numeric-display-module-with_4.html
*
* for
*
* Banggood 4 x 7-Segment Display Module w/ 74HC595 Shift Registers
* http://www.banggood.com/2Pcs-4-Bits-Digital-Tube-LED-Display-Module-Board-With-Clock-p-944244.html
*/
#define RCLK 6 #define SCLK 5 #define DIO 7 #define SHOW_DOT 127
#define ALL_DIGIT 255
#define SPACE 255
/*
bit pattern array (bit is inverted for common anode)
+-a-+
f b
+-g-+
e c
+-d-+ (h)
*/
byte maps[ 16 ] = {
//hgfedcba
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
0b10001000, // A
0b10000011, // b
0b11000110, // C
0b10100001, // d
0b10000110, // E
0b10001110 // F
};
// Send Data to dual 74HC595 shift register
void update2x595( byte digit, byte value ) {
digitalWrite( RCLK, LOW );
// Second register output as segment pattern
// connected with cathode pins
shiftOut( DIO, SCLK, MSBFIRST, value ); // update data
// First register output to select digit (as mask),
// connected with corresponding anode pin
shiftOut( DIO, SCLK, MSBFIRST, digit ); // select digit(s)
digitalWrite( RCLK, HIGH );
}
//function to display 4-digit hex value (right justified)
void d4_hex( unsigned long value ) {
boolean nonBlank = true;
byte dMask = 1;
while( dMask > 0 ) {
update2x595( dMask, nonBlank ? maps[ ((byte)value) & 15 ] : SPACE );
if( nonBlank ) {
value >>= 4;
nonBlank = value > 0;
}
dMask <<= 1;
}
}
//function to display 4-digit dec value (right justified)
void d4_dec( unsigned long value ){
boolean nonBlank = true;
byte dMask = 1;
while( dMask > 0 ) {
update2x595( dMask, nonBlank ? maps[ value % 10 ] : SPACE );
if( nonBlank ) {
value /= 10;
nonBlank = value > 0;
}
dMask <<= 1;
}
}
const byte incDelay = 32;
byte incCtr = incDelay;
unsigned long vInc = 0;
void setup() {
pinMode( RCLK, OUTPUT );
pinMode( SCLK, OUTPUT );
pinMode( DIO, OUTPUT );
update2x595( ALL_DIGIT, SPACE );
}
void loop() {
d4_dec( vInc );
delay( 8 );
if( --incCtr == 0 ) {
vInc++;
incCtr = incDelay;
}
/* d4_hex( vInc );
delay( 8 );
if( --incCtr == 0 ) {
vInc++;
incCtr = incDelay;
}*/
}
|
Código 6 |
unsigned char LED_0F[] =
{// 0 1 2 3 4 5 6 7 8 9 A b C d E F -
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf
};
unsigned char LED[4];
int SCLK = 5;
int RCLK = 6;
int DIO = 7;
void setup ()
{
pinMode(SCLK,OUTPUT);
pinMode(RCLK,OUTPUT);
pinMode(DIO,OUTPUT);
}
void loop()
{
LED[0]=1;
LED[1]=2;
LED[2]=3;
LED[3]=4;
while(1)
{
LED4_Display ();
}
}
void LED4_Display (void)
{
unsigned char *led_table;
unsigned char i;
led_table = LED_0F + LED[0];
i = *led_table;
LED_OUT(i);
LED_OUT(0x01);
digitalWrite(RCLK,LOW);
digitalWrite(RCLK,HIGH);
led_table = LED_0F + LED[1];
i = *led_table;
LED_OUT(i);
LED_OUT(0x02);
digitalWrite(RCLK,LOW);
digitalWrite(RCLK,HIGH);
led_table = LED_0F + LED[2];
i = *led_table;
LED_OUT(i);
LED_OUT(0x04);
digitalWrite(RCLK,LOW);
digitalWrite(RCLK,HIGH);
led_table = LED_0F + LED[3];
i = *led_table;
LED_OUT(i);
LED_OUT(0x08);
digitalWrite(RCLK,LOW);
digitalWrite(RCLK,HIGH);
}
void LED_OUT(unsigned char X)
{
unsigned char i;
for(i=8;i>=1;i--)
{
if (X&0x80)
{
digitalWrite(DIO,HIGH);
}
else
{
digitalWrite(DIO,LOW);
}
X<<=1;
digitalWrite(SCLK,LOW);
digitalWrite(SCLK,HIGH);
}
}
|
Código 7 |
/*
written by Jason Berger ,arduinoall, ?.?????
reedited by Phaisarn Te. @060614
8-Digit 7-Segment display driver.
2x 74HC595 wired to 2x 4-digit 7-segment displays
bits 0-7 select a digit
bits 8-14 A-G
*/
char disp_c[8] ;
const int SCLK_pin= 5;
const int RCLK_pin= 6;
const int DIO_pin = 7;
// 0-9 --> 0-9
// 0.-9. --> 10-19
// space --> ' '
// A-Z, a-z --> 'A' 'B' ... 'a' 'b'
int disp[8];
//time values for delay workaround
unsigned long prev =0;
unsigned long waitMS=0;
void setup()
{
pinMode(RCLK_pin,OUTPUT);
pinMode(DIO_pin,OUTPUT);
pinMode(SCLK_pin,OUTPUT);
showText('O','P','E','N');
}
int n;
unsigned long start=millis();
byte b = 0;
void loop()
{
showDisplay();
if(b==0){
b++;
wait(3000);
}
else{
if ( millis() > (prev + waitMS))
{
//code to loop in here
showText((n/1000)%10,(n/100)%10+10,(n/10)%10,n%10);
n++;
if(n>10000) {
n=0;
}
wait(1000);
}
}
}
void showText(char a, char b , char c,char d){
disp_c[0] = d;
disp_c[1] = c;
disp_c[2] = b;
disp_c[3] = a;
}
void showDisplay()
{
setDisp();
for(int i=0; i<8; i++)
{
setDigit(i,disp[i]);
}
}
void setDigit(int dig, int character)
{
int digits[]= {
128,64,32,16,8,4,2,1 };
//character set (0-9)0-9
// (10-19)0.-9.
// (20-45)A-Z
// (46-71)a-z
// (72)- (73) space
int characters[]= {
3,159,37,13,153,73,65,31,1,9,
2,158,36,12,152,72,64,30,0,8,
17,1,99,3,97,113,67,145,243,135,145,227,85,19,3,49,25,115,73,31,129,129,169,145,137,37,
5,193,229,133,33,113,9,209,247,143,81,227,85,213,197,49,25,245,73,225,199,199,169,145,137,37,
253,255 };
digitalWrite(RCLK_pin, LOW);
shiftOut(DIO_pin, SCLK_pin, LSBFIRST, characters[character]);
shiftOut(DIO_pin, SCLK_pin, LSBFIRST, digits[dig]);
digitalWrite(RCLK_pin, HIGH);
}
void setDisp()
{
for (int i=0; i<8;i++)
{
int val = disp_c[i];
if((val >= 32)&&(val <= 47)){
switch (val){
case 45 :
val = 72;
break;
default :
val = 73;
break;
}
}
else if((val >= 48)&&(val <= 57)) //0-9
{
val -= 48;
}
else if((val >= 65)&&(val <= 90)) //A-Z
{
val -= 45;
}
else if((val >= 97)&&(val <= 122)) //a-z
{
val -= 51;
}
disp[i] = val;
}
}
void wait( unsigned long milsec)
{
prev = millis();
waitMS = milsec;
}
|
___________________________________________________
- El Arduino envía una palabra de 16 bits en serie hacia los dos controladores 74HC595.
- La parte alta de esa palabra (8 bits más significativos) activan a nivel BAJO a los segmentos ".gfedcba", es decir cada uno enciende si le llega nivel bajo.
- La parta baja de esa palabra (4 bits menos significativos) selecciona a uno de los 4 display, se selecciona cuando cada uno tiene el nivel bajo.
- Los otros 4 bits más altos, que quedan para formar los 8, no se utilizan.
Send 16-bit word serial messages for the two 74hc595 controllers.
High byte = segments ".gfedcba" active low.
Lowest 4 bits of low byte selects digit(s) to display.
High 4 bits = don't care
Send bit 15 first, bit 0 last. Clock each data bit on DIO with a positive SCLK edge.
After 16 bits are clocked in, latch with a positive edge on RCLK.
If daisy-chaining, 16 bits per module, then RCLK edge.
Proceed to next digit. Look at avg 5ms per digit or less, to give a steady display. RCLK and SCLK only cares about rising edges, not levels.
Typically, you will lower RCLK at start of a word, place a bit on DIO and then give SCLK a high pulse.
When all 16 bits are done - raise RCLK again.
Adjust for number of segments. A "1" will be much brighter than a "8" with same delay. 1ms per displayed segment in a digit is a good starting value.
Example: write 12.34 word0: 11111001 00001000 ; segments "1", digit 3, no decimal point,
delay=2ms word1: 00100100 00000100 ; segments "2", digit 2, with decimal point, delay=6ms word2: 10110000 00000010 ;
segments "3", digit 1, no decimal point, delay=5ms word3: 10011001 00000001 ; segments "4", digit 0, no decimal point, delay=4ms
For small microcontrollers, I suggest lookup tables for both segment encoding and delay. Add one to delay if decimal point is used on that digit.
________________________________
|