Carry Flag Madness in PIC Microcontroller. - Page 1
Forum section: electronics / general

author: Dukov Ahzrukhal
author_rank: Regular Contributor
timestamp: June 26, 2018, 09:26:53 pm
content: Hello everyone, as part of a bigger project I've been working on an RS-232 terminal device that has a standard 20*4 LCD display and a PS/2 keyboard interface. All it does is send and receive data to a small computer over RS-232. For that, I am using a PIC16C65 microcontroller, and Im writing all the code in assembly. I started testing with a 16*2 display, and got everything working fine, but once I changed to a 20*4 display to add scrolling and cursor movement things that were working fine went haywire. When I press the arrow keys on the keyboard to move the cursor it does what its supposed to do, but exactly once every four times I press the down arrow an '8' is printed on the display, and exactly three times out of 4 times I press the up arrow a '2' is printed. At first it seemed my KB_translate function was broken, but when I noticed that something was happening exactly once every four times I pressed the up or down arrow I began to suspect it was something to do with the carry flag, since im using the upper two bits of a register to keep track of the current line on the display. Indeed clearing the carry flag after the LINED_LCD and LINEU_LCD functions does fix the issue, but it is only a matter of time before something else changes the carry flag and everything breaks. I've looked everywhere in my code for something that would fail if the carry flag is set, but I cant find it. Any help finding what was breaking would be greatly appreciated.

author: FrankBuss
author_rank: Unknown
timestamp: June 26, 2018, 09:49:29 pm
content: Wow, a PIC16C65? Didn't know that Microchip marked any chip as "end of life", but they did it for this chip. And it is one time programmable as well. How do you test your programs? Looks like a lot of wasted money. Why do you use such a microcontroller? At least use a PIC18F4520, if you want to use a PIC at all. Then program it in C (the light version of the C compiler is free for MPLABX, and you can do inline assembly for time critical stuff) and no problems with carry flags anymore

author: jpanhalt
author_rank: Super Contributor
timestamp: June 26, 2018, 10:24:29 pm
content: Without seeing your code, it is impossible to advise on the carry flag.Do you have any subtractions -- remember, in subtraction the carry is set, unless there is a borrow. Any rotates? Do you have any interrupts? If so, how do you turn off GIE?Agree, there are better chips that are simpler and/or more complex as you may desire to use. Even the 16F84 is an outdated option that is better.Oops, just saw your attachment. Looking at it now.

author: malagas_on_fire
author_rank: Frequent Contributor
timestamp: June 26, 2018, 10:44:45 pm
content: The funny thing is when you go on Microchip for select the considered device PIC16C65B, it is already Not Recommended for new designsthen jump to another..PIC16F724 and you get a big punch of peripherals.Programming in asm these days are very stiff, when there are C compiler very improved and instructions set was well for this, but get's more speedy and more into the machine's show, in terms of learning.For the carry bit it can be checked with AND bitwise instructions , RLF, ANDLW

author: Dukov Ahzrukhal
author_rank: Regular Contributor
timestamp: June 26, 2018, 11:36:01 pm
content: Quote from: FrankBuss on June 26, 2018, 09:49:29 pmThe chip is UV erasable, so with a handful of chips and a UV light I'm able to test all I want! It's really an exercise in assembly for me to make something like this; writing in C would be taking the easy way out

author: Dubbie
author_rank: Unknown
timestamp: June 26, 2018, 11:44:26 pm
content: Quote from: Dukov Ahzrukhal on June 26, 2018, 11:36:01 pmI think I am beginning to understand where the madness really lies

author: ggchab
author_rank: Frequent Contributor
timestamp: June 27, 2018, 08:38:17 am
content: Not very clear code: sometimes, you use the register symbolic name, sometimes, the physical address (PCL, STATUS, 02H, 03H, ...). And I find it's better to use tabs rather than spaces to align code.When you add a value to PCL (KB_TABLE), are you sure WREG contains the right value and there is no PCL overflow ? You might then jump anywhere in the 256 bytes page !Also, are you sure your jumps tables fit in the same 256 bytes page ? Otherwise, you have to play with PCLATH. Very boring ... PIC18F are easier to program and you'll have much more fun

author: jpanhalt
author_rank: Super Contributor
timestamp: June 27, 2018, 09:39:31 am
content: Checked most of the rotates and subtractions (common sources of problems) and didn't see anything.Can you explain how you are timing the communication at 2400 baud and your interrupt? At first, I thought you might be using TMR0 to set the pace, but then I couldn't find it in the code readily.Also,Code: (text)INTRPT CODE 0X04ISR CODE 0X08SERVINTBANKSEL OPTION_REGBSF OPTION_REG, 5;STOP TIMER0BANKSEL INTCONBCF INTCON, T0IFRETFIEAre you using interrupts? Are you saving context? Where do you restart TMR0? That may be obvious to you, but I simply used search to try to find the start and may have searched on the wrong characters.John

author: NivagSwerdna
author_rank: Super Contributor
timestamp: June 27, 2018, 10:55:53 am
content: You are using the top two bits of FLAG_REG as line counter and using ADDWF and SUBWF instructions so as you are aware that will affect the C flag as you wrap around the 00->11 rangeYou also use RLF instructions.... be aware that although this rotates out into the C flag it also rotates the value of the C flag into PORTB

author: Dukov Ahzrukhal
author_rank: Regular Contributor
timestamp: June 27, 2018, 01:26:03 pm
content: Thank you very much. Indeed, the problem was with the RRF instruction in KB_READ, the carry flag was being rotated into DREG which effectively made the subroutine read the wrong value from the keyboard. Clearing the carry flag at the start of that subroutine has fixed my problem.

author: Dukov Ahzrukhal
author_rank: Regular Contributor
timestamp: June 27, 2018, 04:08:35 pm
content: Quote from: jpanhalt on June 27, 2018, 09:39:31 amThis may sound insane, and I'll admit it is, but Im not using interrupts or timers, there is a delay loop that is precisely calculated to get get the baud rate. This only works for a clock frequency of 4MHz, which is what Im using. the reason why im not using the uart in the PIC16C65 is that I started off using a different microcontroller that didne have one, and since the code was working just fine I decided to keep it. Yes, its insane, yes its hard to read, but its working just fine. Sorry I made you go through the pain of reading it