Teensy 4.1 + SN74HC595N problems

Emans

Member
Good day everyone, I'm once again asking support for a Teensy 4.1 project.
I recently got a big 7 segment single digit display to be used as a gear counter, and to manage the connections from the display to the MCU I'm using a SN74HC595N in DIP 16 package.
To test everything, I used an Arduino Uno (in a 5V based system) and everything's fine, but since I need to transfer everything from a breadboard to a small universal PCB to be used with both 3.3V and 5V-based systems, I decided to try the circuit on a Teensy 4.1 (which will likely be the final choice for the MCU in my project).
The problem is that the maximum frequency allowed on the clock pins of the 74HC595 is way below even the slowest clock speed of the Teensy 4.1 (25-29MHz for 5V and more than 5MHz for 3.3V), and as I connected the Teensy 4.1 to the circuit the segments started to behave erraticaly, lighting up in the wrong order and with a very dim light (except for the decimal point, who is just as bright as the others). As the Teensy 3.3V internal supply is not powerful enough, I hooked up a 9V to 5V/3.3V conversion board, and for some reason the decimal point lights up even with the supply turned off, albeit erratically.
I adjusted the resistor accordingly (from 220 Ohm with 5V to 120 Ohm with 3.3V, chanign from 15mA to ~13mA), and below is the code I am using (mostly taken by an Elegoo guide seen on YT, my only contribute at this point has been changing the data format from binary to decimal, as the latter worked better for me. It's probably my ignorance in shift registers, tough).
C-like:
int latchPin = 3;
int clockPin = 4;
int dataPin = 2;

byte sevenSegDP = B00100000; // = DP

bool bAddDecimalPoint = true; // display state of show decimal point

/* ***********************************************************
 *                         Void setup                        *
 * ********************************************************* */
void setup() {
    // Set latchPin, clockPin, dataPin as output
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
}

// display a alpha, binary value, or number on the digital segment display
void sevenSegWrite(byte digit, bool bDP = false, char switchValue='D') {
    /*       digit = array pointer or binary value, as a byte
     *         bDP = true-include decimal point, as boolean
     * switchValue = 'A' alpha
     *               'B' binary
     *               'D' digits <default>, as char           */
    
    // set the latchPin to low potential, before sending data
    digitalWrite(latchPin, LOW);
    
    // the data (bit pattern)
    if (switchValue=='B') {
        // binary
        shiftOut(dataPin, clockPin, MSBFIRST, digit+(sevenSegDP*bDP));
    }
    // set the latchPin to high potential, after sending data
    digitalWrite(latchPin, HIGH);
}

void sevenSegBlank(){
    // set the latchPin to low potential, before sending data
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000); 
    // set the latchPin to high potential, after sending data
    digitalWrite(latchPin, HIGH);
}

void loop() {
    // display numbers (dec)
    sevenSegWrite(32, false,'B');    // .
    delay(500);
    sevenSegWrite(95,false,'B');    // 0
    delay(500);
    sevenSegWrite(6,false,'B');    // 1
    delay(500);
    sevenSegWrite(155,false,'B');    // 2
    delay(500);
    sevenSegWrite(143,false,'B');    // 3
    delay(500);
    sevenSegWrite(198,false,'B');   // 4
    delay(500);
    sevenSegWrite(205,false,'B');   // 5
    delay(500);
    sevenSegWrite(221,false,'B');   // 6
    delay(500);
    sevenSegWrite(7,false,'B');  // 7
    delay(500);
    sevenSegWrite(223,false,'B');   // 8
    delay(500);
    sevenSegWrite(207,false,'B');   // 9
    delay(500);
    // suspend 1 second
    sevenSegBlank();
    delay(1000);
}
I believe the problem is with the Teensy frequency, as powering the circuit through the 3.3V system on Arduino Uno worked just fine.
I saw a thread that used delays to artifically lower the speed, but I would prefer a less intrusive solution, as the MCU will be used for high speed CAN and SPI communications parallel to operating the display.
Do you guys reckon there's a way to lower the frequency on a specific pin in order to maintain the high core clock speed for different tasks, while maintaining the SN74HC595 chip?
As a last resort, I'm open to changing shift register, but I am not currently aware of ICs with both 3.3V and 5V tolerancies and equal pinout...
 
Why not use a 74HCT595 ? 5V supply so fast (31MHz), but 3V compatible inputs.
On the Nexperia datasheet, maximum frequency is labeled at 24MHz. The 5V supply and 3.3V logic input seems a nice combination, but I'm still left with the frequency problem.
Maybe I can hook the IC to the SPI pins instead of the general purpose ones? I already need to set the SPI frequency to around 21MHz to power a RA8875 display, when I declare it in the code, is it applied to all the SPI pins?
 
Try the T.I. datasheet then... 31MHz at 25C and 4.5V supply. Probably go a little faster at 5.0V.

If you want faster and can do all-3.3V, the 74LCV or 74LCX families are the fast 3.3V CMOS ones.
So a 74LCV595 with its outputs buffered/level-shifted with a 74HCT245 might be an approach.
 
Back
Top