pic16f77 acting goofy

I will try to make this question as short as possible. I'm making a "quiz box" that displays the first two of any 20 players that buzz in. I'm using a pic16f77. The program scans 20 ports (buttons) and displays the first two numbers (1-20) on four single digit 7-segment LED displays via a display driver. Also, a speaker buzzes after the first player has buzzed in. Everything works great except for this one "little" bug.

When I first turn on the power, the displays get set to zero's and the program starts scanning the buttons. If I first push a button in the teens (10-19) the first digit is always wrong. For example, in stead of displaying 12, it displays 32 or 72. Next I push a button (1-9) and it displays correctly. If I reset the program and push the same buttons in the same order, the problem occurs again. However, if I reset the program and first push a button (1-9), then push a button (10-20), it displays correctly and every time thereafter until the power switch is toggled off then on again.

The same thing happens when I turn the power on and first press a button (1-9) then a button (10-19) - it displays incorrectly until I reverse the order. I push one (10-19) then one (1-9) and everything works fine.

So, everytime I want to use it, I have to "intialize" it to get past the bug before it will work right. This problem is very perplexing. The program debugs fine. There is absolutely no reason for the mc to be spitting out these goofy numbers. Does anyone have any idea, hardware or software, what could be causing this problem? I hope this wasn't too confusing. Thanks in advance.

Steve

Reply to
mcki0127
Loading thread data ...

This problem is best fixed by single stepping in an emulator or in a simulator. I would be surprised if it was not a S/W problem.

--
Best Regards,
Ulf Samuelsson   ulf@a-t-m-e-l.com
 Click to see the full signature
Reply to
Ulf Samuelsson

It sounds like you have forgotten to initialize a register. Namely, the one that holds the most-significant digit. Check your initialization code.

Noel

Reply to
Noel Henson

?!

Well, there clearly must be a reason - it sounds very predictable: you have just not found the reason, yet.

You have enough info in the interaction to start the debug process. When a system is path dependent, but does have the ability to behave correctly, it points to a software initialise problem. Look for different variable handling, in your 'works OK' path, from the 'fails' path. It is good practice to clear all variable RAM on reset, in a 80c51 this takes 6 bytes of code - and can save a lot of other variable inits. You then code, so all 'safe defaults' are the 00 or FALSE values.

-jg

Reply to
Jim Granville

I did something similar with an Atmel AT90S2313 processor. Code works fine and is in use, I believe. Circuit schematics and box and source code etc. are all right here if that helps, too. Here's some of the header comments:

; This program operates a Jeopardy or college-bowl kind of game device ; where the first person to press a switch is selected, locking out the ; others. Eight contestants are supported, each by direct connection to ; an input pin. An LED lights up to indicate which switch (contestant) ; is pressed first and the rest of the contestants are then locked out. ; The buzzer emits a short burst, as well, to signal that a contestant ; has pressed their button.

Not 20 buttons in this case, but extending it would be easy. In any case, the basic ideas in the code are there, too.

Jon

Reply to
Jonathan Kirwan

"Jim Granville" wrote

Zeroing ram is always a good idea at the start, but I find it most useful in debugging because it makes a memory dump easier to interpret.

I develop with RAM zeroed, and then verify operation with ram set to 0FFH. Variables that are not explicitly initialized are verboten under all circumstances.

If you are having weird problems then setting memory to all 1's can often make the source of the problem stand out like a sore thumb (or stamp).

--
Nicholas O. Lindan, Cleveland, Ohio
Consulting Engineer:  Electronics; Informatics; Photonics.
 Click to see the full signature
Reply to
Nicholas O. Lindan

Wow, thanks for all the help and suggestions. I'm using MPLAB IDE v6.61 with MPLAB SIM. I can step through the program and use the pin stimulus feature to check the different scenarios. The program seems to work fine, storing all the correct values in each register.

I've declared two variables that keep track of the buttons pushed: flag1 and flag2. I intitialize these registers by

clrf flag1 clrf flag2

Is this sufficient? In a later subroutine, those hex numbers get split into dig1a, dig1b, dig2a, and dig2b to be sent to the display driver. They are initialized the same way. I'm not exactly sure what is meant by the RAM. Is that the block of general purpose registers used to store all the variables? If that's the case, then mine starts at 020H. If I write all 0's (or 1's) to these registers, should I then run the program to the point where it's messing up, and then do a memory dump to see what each variable holds?

Jon, I would like to take a look at your box design, but there doesn't seem to be a link with your message :=)

Steve

Reply to
mcki0127

During your initialization, did you setup your PORTs to have the correct default value? This is usually done just before a write to TRIS. It is just as important as properly initializing your variables.

Noel

Reply to
Noel Henson

Yes, I also clear all the ports before writing to the TRIS registers. Steve

Reply to
mcki0127

Assuming your program is written in assembler, this sounds like the kind of PIC bug that results from forgetting a bank select instruction somewhere.

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
 Click to see the full signature
Reply to
Spehro Pefhany

Steve,

I'm not trying to second-guess you but, is clearing the ports the correct thing to do? In my own circuits, I usually have low-true scan signals. When I do, I set those port bits to a 1.

HTH,

Noel

Reply to
Noel Henson

My program is written in assembler and I've tried to be careful about writing to the correct banks. I do however get several messages like this one:

Message[302] C:\PIC PROJECTS\QUIZ.ASM 34 : Register in operand not in bank 0. Ensure that bank bits are correct.

This is referring to me writing to the OPTION_REG which is in bank1.

bank1 movlw b'10000111' movwf OPTION_REG ; intitialize interrupts

bank1 macro bsf STATUS, RP0 bcf STATUS, RP1 endm

So, I think I'm writing to the banks correctly.

Reply to
mcki0127

Noel,

Do you mean that your inputs are active low? Mine are active high. I have 1K pull-down resistors from each pin to ground.

Steve

Reply to
mcki0127

And you switch back to bank 0 after that in every case?

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
 Click to see the full signature
Reply to
Spehro Pefhany

Yes I do, and I just stepped through the program again while monitoring the STATUS bits. After initializations, the bank bits stay in bank0 for the remainder of the program.

Reply to
mcki0127

Both the outputs, because I scan key matricies, and the inputs are active-low. This is done for noise immunity and habit from two decades of design with TTL-level circuit. Since mine are active-low, I initialize the device with high (negated) outputs.

Your technique will work fine. I hope you didn't think I was being remedial.

Noel

Reply to
Noel Henson

After re-reading your description, and in light of the rest of the thread, it looks like your scanning and port initialization are correct. Perhaps there is an uninitialized variable in the routine that converts the scanned key to a displayed value.

You mentioned that if you press, say, key 19, you see key 39 or key 79. in binary:

19: 0001 1001 39: 0011 1001 79: 0111 1001

Since I have not seen your conversion routines I cannot be sure but it looks like a register used for the most-significant digit is not being initialized.

Noel

Reply to
Noel Henson

Noel,

Remedial is fine with me. I'm open to improvement and I in no wise consider myself an expert (competent? :=) )at any of this.

Now that I look back over my program I can see that I don't initialize dig1a or dig1b (I've changed things around a lot while troubleshooting). My thinking there was that those registers get rewritten anyway before being used to send data to the display. Here is my conversion routine:

___movf flag1,0 ___movwf temp ; move flag1 to temp for safe keeping ___movlw .10 ; store 10 in W ___subwf temp,0 ; subtract 10 (W) from temp (flag1) ___btfsc STATUS,C ; check if flag1

Reply to
mcki0127

clearing dig1a in initialization may help. You may also want to change: bsf dig1a,0 to: movlw 0x01 movwf dig1a

I don't see dig1a being in the case of a key in the 10-19 range.

Just an educated guess,

Noel

Reply to
Noel Henson

Dear Steve,

snipped-for-privacy@hotmail.com schrieb:

^^^^^^ NEVER do this. Two btfsc/gtfss in a row are no good idea!

HTH Wolfgang

--
From-address is Spam trap
Use: wolfgang (dot) mahringer (at) sbg (dot) at
Reply to
Wolfgang Mahringer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.