Unable to bit complement on XC8 compiler for microchip  - Page 1
Forum section: electronics / general

author: singlarrysong
author_rank: Contributor
timestamp: September 16, 2016, 01:38:49 am
content: Hola! I'm new to XC8 compiler and I'm facing a problem that as the topic I said.Previously I use Hi-Tech C for 8bit microchip MCU and it work fine to complement the output TRIS channel such as,RA1 = ~RA1; //if RA1 currently is 1 then will be 0 after this code.But after I start using XC8, it don't work anymore. Then I move on to try the belowCode:unsigned char a = 0;while(1){RA1 = ~a;__delay_ms(500);}and it don't work still.Do I have to Pragma or define sth at the preprocessor?

author: dannyf
author_rank: Super Contributor
timestamp: September 16, 2016, 01:46:55 am
content: PORTAbits.RA1You should read the compiler manual.

author: singlarrysong
author_rank: Contributor
timestamp: September 16, 2016, 02:34:57 am
content: still the sameCode:while(1){PORTAbits.RA1 = ~PORTAbits.RA1;__delay_ms(500);}

author: forrestc
author_rank: Unknown
timestamp: September 16, 2016, 02:38:54 am
content: Quote from: singlarrysong on September 16, 2016, 02:34:57 amTry TRISAbits instead....No reason why this shouldn't work. That said, I normally do something like TRISAbits.RA1=!TRISAbits.RA1;Or, far more likely anymore I have MCC running and use the Toggle() function... aka OUTPUT1_Toggle(); (Going from memory, the function may be named differently).-forrest

author: singlarrysong
author_rank: Contributor
timestamp: September 16, 2016, 02:52:51 am
content: RAx is not under TRISx register thus it wont work definitely. Toggle() is not in XC8 I guess as I cant find it in the user guide.I wonder if current versions have this problems, looking forward more XC compiler user for this idea

author: JPortici
author_rank: Super Contributor
timestamp: September 16, 2016, 06:17:58 am
content: what are you doing?- define TRISA as an output- DISABLE the analog channel through ansela/adconx or whatever depending on the PIC in question. check the datasheet.writing "RA1" directly is ok, but i think it depends on the XC version.RA1, _RA1, PORTAbits.RA1 should be equivalent.(actually i think RA1 is for XC8, _RA1 for XC16... whatever.)finally, writing directly to the PORT registers is not advisable. use the LATx register if available (Read the datasheet. the LATx registers ONLY affect the pins selected as output, while writing to port will force a new state on the pin, regardless the setting, for part of the next instruction cycle. causing glitching in peripheral, input lines and analog inputs)then, to your C code.RA1 = ~a;should ALWAYS return 1, as you don't save the state of aRA1 = ~RA1; and the PORTAbits.RA1 version may work but that'n not how you'd do it.RA1 ^= 1; (or any bit type ^= 1) is the way to do it. the best way to toggle bits, as how it is handled by the compiler.(thank god you won't find such crap functions as toggle in the compiler library but rather in the bullshit hal)

author: singlarrysong
author_rank: Contributor
timestamp: September 16, 2016, 06:41:36 am
content: Yes I saw my mistake on the char a there.btw using LATx work now.It should be a bad habits I earn while my time using Hi-Tech C because PORTx and LATx is nothing different.btw again, ANSELx register is dedicated for input purposes so its should noting to do with output.Code:[/void main(void){OSCCON = 0b11110000;TRISA1 = 0;while(1){LATA1 = ~LATA1;__delay_ms(50);}code]

author: JPortici
author_rank: Super Contributor
timestamp: September 16, 2016, 07:37:57 am
content: wrong and wrongLATx and PORTx are NOT INTERCHANGEABLE and i explaiend whyolder devices didn't even have the LATx register, that's why you learned by using directly PORTxANSELx do affect the output. you know, disconnecting the digital pin driver... i agree that in theory it shouldn't affect the output but in reality it does.

author: AndyC_772
author_rank: Super Contributor
timestamp: September 16, 2016, 08:56:23 am
content: Quote from: JPortici on September 16, 2016, 06:17:58 amWho told you that?Writing to LATx governs the state of the pins which are defined as outputs.Reading from LATx reports the values that were written to LATx, regardless of what's actually happening on any of the pins.Reading from PORTx reports the state of the pins. Normally this will be the same as the LATx bits for those pins which are defined as outputs, and the current state of any pins defined as inputs.So, the golden rule is, write to LATx and read from PORTx - on parts which have both registers, of course.The distinction between the two is nothing to do with the compiler, it's to do with the target device. Some very small PICs don't have separate registers.Quote from: JPortici on September 16, 2016, 07:37:57 amANSELx is primarily used to control whether or not the digital *receiver* is connected.TRISx is the register which controls whether or not the digital *driver* is connected.It may well be that pins programmed as analogue using ANSEL are also set as inputs, overriding the corresponding TRIS bit - but I wouldn't rely on it. Make them consistent with each other (ie. define your analogue inputs as inputs) as a matter of good practice, and you won't have a problem.The 'gotcha' here is that many devices have their pins default to analogue, so you have to clear ANSEL bits before using the pins as digital I/O.This confuses some people, but it's good design practice on Microchip's part because if a digital input is fed a voltage that's not a clean 1 or 0, it can cause the input buffer to draw excess current. By disabling the digital input by default, the chip won't waste current unnecessarily during the time between power-up and the time at which the software gets around to setting ANSEL correctly.

author: JPortici
author_rank: Super Contributor
timestamp: September 16, 2016, 09:19:24 am
content: Quote from: AndyC_772 on September 16, 2016, 08:56:23 amdirect experience.witing a "1" on an analog pin using the PORTx register resulted in glitches in the reading.writing on the PORTx register trying to force a pin output state (with the pin controlled by another peripheral) resulted in glitches on the pin, constant duration, about 1 XTAL cycle (or 1/4 instruction cycle)

author: rstofer
author_rank: Super Contributor
timestamp: September 16, 2016, 01:12:36 pm
content: Then there's the whole read-modify-write issue and whether it causes a problem. To that end, I usually keep a shadow copy of the outputs in a variable. I modify the variable and the write the output to the port. I don't read the port at all.http://www.microchip.com/forums/m147383.aspx

author: AndyC_772
author_rank: Super Contributor
timestamp: September 16, 2016, 04:07:41 pm
content: Quote from: JPortici on September 16, 2016, 09:19:24 amOK, fair comment. Do you remember the part number? I'd quite like to test this for myself.

author: JPortici
author_rank: Super Contributor
timestamp: September 16, 2016, 05:20:40 pm
content: last time i had this problem was quite some time ago after that i really learned not to use PORTx for outputs unless with extreme caution.ehr.. dspic4013, pic16f1847 i think. i have a couple of these and some older pics laying around. i'll make some tests too in the weekendmy theory: if a peripheral like CCP is synchronyzed to the crystal clock edge, maybe at the excecute clock cycle the output is driven by the instruction. the successive clock cycle the control is regained by the peripheral. if we had a schematic of the actual output stage it would be possible to really tell if i'm saying gibberish or if there is actual truth in my words..

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: September 16, 2016, 05:58:17 pm
content: Quote from: AndyC_772 on September 16, 2016, 08:56:23 amMore specifically, read from PORTx when you want to get theexternalstate of the port pins. In this case the OP probably wants to 'flip' the output bitregardlessof the actual voltage on the pin, so the correct register to read is LATx.Confusion occurs on PIC's that don't have LATx because the output and input registers are at the same address and so have the same name. But on these PICs youcannotread the output register. So you either use a 'shadow' variable, or read the pin and hope that it is not being pulled up or down by some external signal (watch out for capacitive loading!).Another thing that may cause confusion is that when a pin is switched to certain alternative functions (eg. ADC) it is disconnected from the input port, but is still connected to the output port. So you can write to the pin, but you can't read from it!Thankfully Microchip usually includes a block diagram of each GPIO bit in the datasheet. This helps to visualize what is going on when various options are selected, and what the port is capable of. For example in the 12F617 you can see that on GP2 (only) the digital input to the GPIO register is conditioned by a schmitt trigger. Some other pins have schmitt trigger inputs to alternate functions butnotto the GPIO register.

author: forrestc
author_rank: Unknown
timestamp: September 18, 2016, 08:42:31 pm
content: Quote from: singlarrysong on September 16, 2016, 02:52:51 amMCC is a free code generation tool from Microchip. Among other features, it allows you to define a given pin as an input, output, adc, etc.... AND name it.Once you do this, MCC automatically generates you a whole slew of macros which do the correct things. So, if you name a pin 'OUTPUT1', then you get "functions" which include:OUTPUT1_SetHigh(), OUTPUT1_SetLow(), OUTPUT1_Toggle(), OUTPUT1_GetValue(), etc.It also generates correct initialization code so the pin is set as you requested - input, output, ADC input, etc.Assuming you don't want to use that tool:Looking at some generated code, the toggle it generates for a pin which happens to be on A1 is:LATA1=~LATA1;Supposedly LATAbits.LATA1 would be equivalent.

author: dannyf
author_rank: Super Contributor
timestamp: September 18, 2016, 09:10:39 pm
content: QuoteBecause you did it wrong.