Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

decimal digits, MCU 8051 IDE

PG1995

Active Member
Hi,

I wrote this code years ago and at that time I used MCU 8051 IDE. I also have a screenshot when this code was implemented as is shown below.

Now the problem is that I don't remember how this code was implemented using 7-segment display and numeric keypad. I can no longer make it work. I needed to help someone but I don't know how 7-segment display and numeric keypad should be interfaced. Could you please help me?

Ian Rogers , if you don't mind my tagging, could you also please give it a look?

Code:
; Interface a numeric keypad to PORT 0 and display the entered decimal digits
; ,1-9, on a 7-segment display connected to PORT 1

org 0x0

    Repeat:
    mov P1, #11000000B    ; "0" is displayed on the display
    mov P0, #0x0FF    ;Port 0 is now an input port
    mov A, P0

    KeepChecking:
    mov A, P0
    cpl A
    JZ KeepChecking
    
    cpl A
    
    CJNE A, #11111110B, DigitIz2
    mov P1, #11111001B      ;this will diplay "1" on 7-segment display
    SJMP Repeat     ;execution of the program repeats
    
    DigitIz2:
    CJNE A, #11111101B, DigitIz3
    mov P1, #10100100B
    SJMP Repeat

    DigitIz3:
    CJNE A, #11111011B, DigitIz4
    mov P1, #10110000B
    SJMP Repeat

    DigitIz4:
    CJNE A, #11110111B, DigitIz5
    mov P1, #10011001B
    SJMP Repeat

    DigitIz5:
    CJNE A, #11101111B, DigitIz6
    mov P1, #10010010B
    SJMP Repeat

    DigitIz6:
    CJNE A, #11011111B, DigitIz7
    mov P1, #10000010B
    SJMP Repeat

    DigitIz7:
    CJNE A, #10111111B, DigitIz8
    mov P1, #11111000B
    SJMP Repeat

    DigitIz8:
    CJNE A, #01111111B, Error
    mov P1, #10000000B
    SJMP Repeat

    Error:
    ;CJNE A, #, DigitIz0  ;here digit "0" stands for an error
    mov P1, #01111111B    ;dot will denote error
    SJMP Repeat


end


Screenshot taken many years ago:
1685824337857.png
 
That code does not use a keyboard matrix, it's written to look at eight buttons wired directly to P0.
Buttons to ground and pullup resistors to VCC.

It looks for a single bit on the port being pulled LOW when any one button is pressed.

P1 connects to the segments of a common-anode display, via resistors. Anode to VCC.
Bit 0 looks to be segment A.
 
That code does not use a keyboard matrix, it's written to look at eight buttons wired directly to P0.
Buttons to ground and pullup resistors to VCC.

It looks for a single bit on the port being pulled LOW when any one button is pressed.

P1 connects to the segments of a common-anode display, via resistors. Anode to VCC.
Bit 0 looks to be segment A.

Thank you for pointing this out!

How do I reduce the simulation speed of MCU 8051 IDE? For example, in Multisim one can slow down the simulation time to notice things carefully.
 
Works okay for me. Try single stepping... Also place an org statement above the "repeat" as you need to jump over the interrupt vectors ( doesn't matter in tis case as you are not using them) but good practice for later. Single stepping is the pair of footprints after the rocket ( simulate ) or F8 ..

Last.. turn the keypad and digit display "ON" (use the smaller keypad for this sim)
 
Code:
org 0x0
    SJMP Repeat                   <<-- this will help later
    
    Repeat:
    mov P1, #11000000B    ; "0" is displayed on the display
    mov P0, #0x0FF    ;Port 0 is now an input port
    mov A, P0

    KeepChecking:
    mov A, P0
    cpl A
    JZ KeepChecking
 
Thank you for the help!

Yes, I should have used the smaller keypad but it won't let me display "9". Anyway, I'm okay with it.

By the way, I don't understand why the second "cpl A" is used below. I have checked it and without it the code does not work. Taking the complement two times would give us the original form.


; Interface a numeric keypad to PORT 0 and display the entered decimal digits
; ,1-9, on a 7-segment display connected to PORT 1

org 0x0

Repeat:
mov P1, #11000000B ; "0" is displayed on the display
mov P0, #0x0FF ;Port 0 is now an input port
mov A, P0

KeepChecking:
mov A, P0
cpl A
JZ KeepChecking

cpl A

CJNE A, #11111110B, DigitIz2
mov P1, #11111001B ;this will diplay "1" on 7-segment display
SJMP Repeat ;execution of the program repeats
 
By the way, I don't understand why the second "cpl A" is used below

If no buttons are pressed, the inputs are all "1"; 0xFF
Complementing that makes it 0x00
The JZ (jump if zero) then loops back, waiting for a keypress (which means something other than 0xFF and something other than 0x00 inverted.

If the inverted value is non-zero, the code runs through and re-inverts the inputs back to the levels read from the switches, which are then used in the rest of the compare sections.

That could have been left out, and the comparisons made to look for each single 1 bit rather than the single 0 bits.
 
Thank you!

I'm using the following "Simple Keypad". I had thought that the pressing of any keys connects the input to Vdd but it connects it to the ground.

So, when key "A" is pressed, the leftmost pin is grounded, i.e., 11111110.

It says, "Array of 8 independent keys, each one of them can connect any GPIO line to the ground."

The following capture is the manual of MCU 8051 IDE.
1685917374834.png
 
Correct! But the pins on a 8051/2 or variant works backwards.

The pin setup is very basic, you will notice you MUST set the port to 0xFF to make it an input.
Ergo when the pin is grounded the micro see's a 1 and not a 0. I see the schematic on the switch pop up and it does look like it, but input has always been like that on these micro's.
 
I've never used an 8051 but always assumed that to use a pin as input, you write a 1 to it and it's like an input with a pull-up and can be pulled low.
Is this not the case?

Mike.
 
I've never used an 8051 but always assumed that to use a pin as input, you write a 1 to it and it's like an input with a pull-up and can be pulled low.
Is this not the case?

Mike.
I've never used them either, but I'm aware that there are many 'strange' limitations on the 8051's :D

It's a bit like back in the 'old days' the 6502 PIO chip (the 6522) was well designed and worked sensibly - the usual Z80 PIO chip (the 8255) had all sorts of peculiar restrictions.

But back then, and now, you just need to be aware of the limitations, and work around them - just don't expect things to always work the way you'd expect :D One reason datasheets are so important.
 
I've never used an 8051 but always assumed that to use a pin as input, you write a 1 to it and it's like an input with a pull-up and can be pulled low.
Is this not the case?

Mike.
Looks like I explained it wrong.. When you read a pic pin the output is floating ergo high or low.

Only PORT0 on the 51 has floating inputs the others are called "quassi-bidirectional" ?? (no idea )

But the port still has to be driven high as the fet in the sink will just fry if you apply a 5v to the pin when configures as an output. So what I mean to say is you can only read a high voltage when the pin is driven high.. Oddly enough you van still read the pin when its an output.

The statement above is wrong a low on the pin is a low internally . I should have said to read a 1 you must first write a 1.
 
Looks like I explained it wrong.. When you read a pic pin the output is floating ergo high or low.

Only PORT0 on the 51 has floating inputs the others are called "quassi-bidirectional" ?? (no idea )

But the port still has to be driven high as the fet in the sink will just fry if you apply a 5v to the pin when configures as an output. So what I mean to say is you can only read a high voltage when the pin is driven high.. Oddly enough you van still read the pin when its an output.

The statement above is wrong a low on the pin is a low internally . I should have said to read a 1 you must first write a 1.

That's made it all clear! :D :D :D :D
 
Open collector with no disable, just on/off control?
I think so? - the pins are all inputs, but have an open collector (or open drain) transistor connected to them - so you can't switch the I/O's between input or output, but to use as an input you have to ensure the output transistor is turned off.

Something like the I2C port expander, who's number defeats me for the moment? - PCF something?.

Just googled - PCF8574 :D
 

New Articles From Microcontroller Tips

Back
Top