-2
\$\begingroup\$

I want to show a decimal number between 0-99 on 7-segment display by using 2 push buttons. These buttons will be used for incrementing and decrementing the number on display. I'm using pic18f assembly language for developing. The incrementing part of my code is

 inc:

    call disp
    call DELAY
    call lisButton    ;it waits for the corresponding push button.

    INCF num          ;num is used for getting 0 after 9 in incrementing
    MOVLW h'0A'
    CPFSEQ num,0
    GOTO inc
    GOTO main

 disp:
 MOVF num,0
 ADDWF num,0
 call Tab
 MOVWF PORTJ
 BSF   LATH, 0
 call longdelay
 return


 Tab
 ADDWF PCL
 RETLW b'00111111' ;0
 RETLW b'00000110' ;1
 RETLW b'01011011' ;2
 RETLW b'01001111' ;3
 RETLW b'01100110' ;4
 RETLW b'01101101' ;5
 RETLW b'01111101' ;6
 RETLW b'00000111' ;7
 RETLW b'01111111' ;8
 RETLW b'01100111' ;9
 return

And the decrementing part is similar. However, this code either increments or decrements, not both. So, how can I correct my code?

Thanks in advance.

\$\endgroup\$
2
  • \$\begingroup\$ It appears from your singular original comment that lisButton hangs unless a particular switch is pressed. How can it 'see' the other switch if the program is hung up in a loop waiting for a different switch? \$\endgroup\$ Commented Apr 2, 2016 at 16:36
  • \$\begingroup\$ Yes,you are right. But, how can I solve that problem because when I remove that line the code even does nothing? \$\endgroup\$ Commented Apr 2, 2016 at 16:48

2 Answers 2

3
\$\begingroup\$

Your immediate problem seems to spring from lisButton hanging unless a particular switch is pressed. It thus cannot 'see' the other switch while the subroutine is hung up in a loop waiting for a different switch.

There are a few ways to approach this problem. One would be to write a subroutine that looks for either switch and returns a code that indicates which switch it saw. You can then test that code and act differently for the different switches. This is sort of the equivalent of kicking the can down the road- it solves the problem today, but if you need to do something else that isn't a switch the problem will arise again.

Another way is to think in terms of events. The switch being pressed is an event, the switch being released is an event. Events can be detected in an interrupt (typically a periodic timer interrupt) and false events like switch bounce and noise can be rejected. Verified real events can be put in a queue of sorts (minimum one event, but you could have a larger number in a FIFO) and the main program loops waiting for events and then responds to each event. This allows you to easily (and reliably) do things like create an event when a switch is held for more than 2 seconds, or the user does a double click.

The reason to have a queue rather than just a single location is that it allows your main program more time to deal with events that occur in fast succession, such as two key presses that are almost simultaneous. If you don't have a queue you might miss one of them.

I do agree with Olin's comments with regard to programming structure and style. Unlike, say, Python, assembly code has little inherent structure so you have to be vigilant and impose visible structure and pepper it with useful comments so you don't get a heap of write-only spaghetti code. Using subroutines, as you did, is a start. Things like explaining the overall code structure and all I/O assignments in an exhaustive comment header at the top of the program are de rigeur. I recently revisited a fairly complex (mathematically and logically complex) assembly program I wrote more than 16 years ago- the chip is obsolescent so it has to be ported, and it turns out to a different architecture. The comments are very handy in such a situation.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for your good explanation... I have a last question. How can I check both press and release for a push button to be able to call a function after pressing and then releasing a button? \$\endgroup\$ Commented Apr 3, 2016 at 12:02
  • \$\begingroup\$ Ignoring debouncing, if the last time you read the switch it was closed, and this time it is open, it was released. For a press, the opposite occurs. If no change has occurred since the last read, there was no event. So if you have a subroutine, it must retain the previous state(s) of the switch(es) it is dealing with. Hint: you can retain 8 switch states in one byte and ex-or to find ones that are different, and then test directly to determine how they are different. \$\endgroup\$ Commented Apr 3, 2016 at 15:40
4
\$\begingroup\$

The basic problem is that your code is a mess. You're not ready to address whatever your specific incrementing bug is, and you're certainly not ready to show your code to others. Without proper coding discipline, you're going to forever get flaky results. Some obvious problems:

  1. You show 35 lines of code, but only a single comment! Of course you're going to have bugs when you're this sloppy. Even worse, asking others to look at this mess is irresponsible to the point of being rude. Without comments we can only guess at what you think some of this code does and how you intended it to work.

  2. In MPASM, opcode mnemonics start in column 2 or later. This distinguishes them from labels, which start in column 1. How did this mess ever assemble?

  3. What's with the ",0" like on the line "MOVF num,0"? If I remember right, that specifies whether the result gets loaded into W or not. This is done with the ",w" optional parameter to make the code more clear. The default is then to write the result into the file register instead of W. Using the actual bit value instead of the mnemonic provided for that purpose makes the code difficult to follow and invites mistakes.

  4. ADDWF PCL is a primitive way to implement a jump table. It can be used, but you have to make sure there isn't a 256 byte address boundary within the table, which you haven't.

Trying to follow this code to find a bug would be like trying to bail the Titanic with a teaspoon. Come back when you've at least applied basic common software design principles and are ready to show some respect to those you seek free help from If you don't care about your code, why should anyone else?

\$\endgroup\$
2
  • \$\begingroup\$ Is it better now? (By the way there are 11 comments in the code and I put the 12th) \$\endgroup\$ Commented Apr 2, 2016 at 15:10
  • \$\begingroup\$ I wouldn't ask if it's better now without addressing every point in the answer. Hint: you haven't and it isn't. This is going to take you some time to study good practice and do a major rewrite. \$\endgroup\$
    – Transistor
    Commented Apr 2, 2016 at 17:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.