1
\$\begingroup\$

I'm learning Embedded Systems and how to use ATMEGA32 MCU. Now I'm trying to display a fractional number to the 7 segment but it just won't display! 7SEG Displaying nothing

But if I move the handle of the potentiometer -The voltage on its middle pin I'm trying to display - it displays a weird bar.

7SEG Displaying bar

However if I forget about doing the decimal thing and just display the integer and replace the double 7SEG with an ordinary one, it works. Meaning that the MCU reads the value correctly.

If I add a delay in the code.

It displays the numbers momentarily before removing them.

So I guess for whatever reason it still alters the second 7SEG even if the code is commanding it to alter the first only and vice versa.

What am I missing here?

Edit: Here's the code:

    void SvnSEG_Disp(float num) {
        num_int = (uint8_t)num; // Will take values from Zero to 5
        after_point = (num - (uint8_t)num)*10; // Will take values from Zero to 9
        PORTD &= ~(1 << PD5); // Set PD5 to Zero. Use first 7SEG
        PORTD |= (1 << PD6);  // Set PD6 to One. Don't use second 7SEG
        PORTD |= (1 << PD4);  // Set PD4 turning on the Decimal point.
        PORTD &= ~(1 << PD0); // Set PD0 to 0
        PORTD &= ~(1 << PD1); // Set PD1 to 0
        PORTD &= ~(1 << PD2); // Set PD2 to 0
        PORTD &= ~(1 << PD3); // Set PD3 to 0 


        PORTD |= num_int; // Set the lower 4 bits of Port D (PD0 - PD3) to the bits of the number.

        PORTD |= (1 << PD5); // Set PD5 to One. Don't use first 7SEG
        PORTD &= ~(1 << PD6); // Set PD6 to Zero. Use second 7SEG
        PORTD |= (1 << PD4); // Set PD4 turning on the Decimal point.
        PORTD &= ~(1 << PD0); // Set PD0 to 0
        PORTD &= ~(1 << PD1); // Set PD1 to 0
        PORTD &= ~(1 << PD2); // Set PD2 to 0
        PORTD &= ~(1 << PD3); // Set PD3 to 0


        PORTD |= after_point; // Set the lower 4 bits of Port D (PD0 - PD3) to the bits of the number.

   }
\$\endgroup\$
  • \$\begingroup\$ Exactly which 'double 7SEG' display did you choose? (eg. 7SEG-MPX2-CA-BLUE) \$\endgroup\$ – Bruce Abbott Feb 1 '18 at 18:01
  • \$\begingroup\$ you made me laugh ... you are trying to light up a 7 segment display ... when one of the segments finally lights, you call it a "weird bar" ... lol ... +1 for that \$\endgroup\$ – jsotola Feb 1 '18 at 19:31
  • 1
    \$\begingroup\$ in general, and to keep the code simple, the code needs to contain a table of what bits need to be ON/OFF for each desired digit displayed. Then the code is passed a value and that value is used to select the desired entry from the table. Then the code sets the 4 output port bits per that entry from the table \$\endgroup\$ – user3629249 Feb 2 '18 at 19:12
  • 1
    \$\begingroup\$ because the changing of the individual bits will result in flashing on the 7segment LCDs, strongly suggest building the whole port value as an image in memory, then writing the whole byte as a single I/O \$\endgroup\$ – user3629249 Feb 2 '18 at 20:21
  • 1
    \$\begingroup\$ Please post a link to the data sheet for the 7SEG-MPX2-CC-BLUE. \$\endgroup\$ – user3629249 Feb 2 '18 at 20:29
1
\$\begingroup\$

One thing about 7 segment displays is that they have no memory. Typically the way to control more than one is to:

display on digit 1 -> switch to digit 2 -> display on digit 2 -> switch to digit 1 -> display on digit 1 -> switch to digit 2 -> and so on.

You are setting digit 1, and then switching to digit 2 (so digit 1 is now off) and stopping after that.

You should constantly cycle between the digits to keep all of them on. If you do this fast enough it will appear like they are both always on.

The "weird bar" you are seeing looks like the color-inverted digit 0. I generally suggest applying a mask to the values you write to PORTD to make sure you are actually only changing bits 0-3. Do something like this:

PORTD &= ~0xF;      // Clear bits 0-3
PORTD |= num & 0xF; // Write bits 0-3
\$\endgroup\$
  • \$\begingroup\$ I will try the mask thing. \$\endgroup\$ – Raafat Abualazm Feb 1 '18 at 20:56
  • \$\begingroup\$ But if I use a loop inside in the function, well, the MCU will not do anything else. Anyways the function is called in the While(1) block so it should be constantly lit? I guees it doesn't have the time to be lit. \$\endgroup\$ – Raafat Abualazm Feb 1 '18 at 20:58
  • \$\begingroup\$ "But if I use a loop inside in the function, well, the MCU will not do anything else." - what else does your code need to do? \$\endgroup\$ – Bruce Abbott Feb 1 '18 at 21:21
  • 1
    \$\begingroup\$ @RaafatAbualazm, you could always use a timer interrupt to trigger the digit change. I would let them stay lit for a little bit at least though. \$\endgroup\$ – Catsunami Feb 1 '18 at 23:25
  • 1
    \$\begingroup\$ @BruceAbbott Calculate the number from the value of the ADC then show it. \$\endgroup\$ – Raafat Abualazm Feb 3 '18 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.