PIC16F1508 - Output Voltages

Thread Starter

agsuresh

Joined Dec 28, 2023
66
This is regarding PIC16F1508
I wrote a simple program to switch on and off ports
Originally it was a large program filling almost 93% of the capacity. Since I found some strange behavior I decided to bare minimum for testing and understanding the system.

It runs at 16Mhz internal
#pragma config FOSC = INTOSC
#define _XTAL_FREQ 16000000
inside main()
OSCCON = 0b01111000;
TRISAbits.TRISA5=0;
TRISAbits.TRISA4=0;
TRISCbits.TRISC5=0;
TRISCbits.TRISC4=0;
TRISCbits.TRISC3=0;
TRISCbits.TRISC7=0;
inside while(1)
I just switched the ports to high

RA5=1; // pin -2 4.90v
RA4=1; //PIN 3 2.62v
RC5=1; // PIN 5 4.90v
RC4=1; // PIN 6 4.90V
RC3=1; // PIN 7 0.33V
RC7=1; // PIN 9 1.64V

The output voltage at the pins are different.
Why the difference ? I have checked it with another same microcontroller too. the result is same.

Some of these pins have priorities. for ex :
RA4 has CLKOUT-SOSCO-RA4
RC3 has PWM2- RC3

will such priorities determine the output ?
How can change / surpass those if it is relevant ?
what should be set to get full output voltages.
Is the __XTAL_FREQ not enough ?
Am I missing something here - looking at the wrong place?

any suggestions are greatly appreciated.
 

Attachments

BobTPH

Joined Jun 5, 2013
11,515
ANSEL has no effect on the pin when it is set as an output.

Look at the datashheet section on the IO ports. It will tell you what you need to do to initialize them properly.

Look akso at the configuration section.

Since RA4 is CLKOUT, that function must be disabled by a CONFIG setting. Since it reads at nearly 1/2 Vdd it looks like CLKOUT is enabled. If your multimeter has a frequency range, you can verify that.
 
Last edited:

Thread Starter

agsuresh

Joined Dec 28, 2023
66
Sensacell
boostbuck
BobTPH


On page 107 , it is stated
"Note: The ANSELA bits default to the Analog
mode after Reset. To use any pins as
digital general purpose or peripheral
inputs, the corresponding ANSEL bits
must be initialized to ‘0’ by user software."

This put me off from setting ANSEL initially.
However I just set them to ANALOG and it started working as expected.
There is only one ADC and UART output that I use to watch the logic flow and check values. This will be removed after completion of the project. These need not interfere with other ports. So , as per the document , the pins should be ANALOG by default after reset. Or that is my understanding. but setting the ANSELbits to ANALOG did help.
 

tumbleweed

Joined Jun 27, 2023
19
ANSEL has no effect on the pin when it is set as an output.
That is true to a certain extent. However, pins that are in analog mode will always read as a '0', which will cause issues with OTHER pins when you use an instruction that generates a read-modify-write operation, such as single bit PORT operations.

For example:
Code:
RA5=1; // pin -2 4.90v
will read all of PORTA, modify RA5, and write the port. Any pins of PORTA that are in analog mode will get written back as a '0'

So, as per the document, the pins should be ANALOG by default after reset. Or that is my understanding. but setting the ANSELbits to ANALOG did help.
If you use the pins in digital mode then set the appropriate ANSEL bits to digital (a '0' for this chip)

Also, be sure to check the CONFIG settings... osc mode, WDT disabled, etc
 

trebla

Joined Jun 29, 2019
599
The datasheet is somewhat confusing -in the PORTC section it tells that PWM2 output is with higher priority than RC3 but the PWM2OE bit should be off at power on.
Try always write to corresponding LAT register if you want switching this output pin.
 

tumbleweed

Joined Jun 27, 2023
19
That could indeed be a problem, but it cannot cause the symptoms seen by the TS.
It could if the pins are being measured with a dvm... different duty-cycles.

All the pins he's having an issue with are analog pins...
 

Thread Starter

agsuresh

Joined Dec 28, 2023
66
The datasheet is somewhat confusing -in the PORTC section it tells that PWM2 output is with higher priority than RC3 but the PWM2OE bit should be off at power on.
Try always write to corresponding LAT register if you want switching this output pin.
I had tried that too before posting here. I had not set ANSEL because the datasheet said (my quote) , analog pins shall be defaulted to analog after rest. Which to my understanding, we need to set it as digital only if the pins are used in digital mode. So it should be analog throughout.
 

BobTPH

Joined Jun 5, 2013
11,515
It could if the pins are being measured with a dvm... different duty-cycles.
And what duty cycle do you think the register is setting them to? Ansel sets the mode when used as an input. It has no effect on pins set as outout.

I suspect his readings are because the code is not actually setting them to outputs, or is setting them as PWM outputs. Nothing is set that way be default.
 

tumbleweed

Joined Jun 27, 2023
19
The code IS setting the pins to outputs (TRIS register bits=0). That's not the problem. Nor is it a peripheral "priority" issue.

I had not set ANSEL because the datasheet said (my quote) , analog pins shall be defaulted to analog after rest. Which to my understanding, we need to set it as digital only if the pins are used in digital mode.
In your code in post #1 the pins are ONLY used in digital mode.

Reread the datasheet section 11.3.3 Analog Control closely...
Setting the appropriate ANSELA bit high will cause all
digital reads on the pin to be read as 0
and allow
analog functions on the pin to operate correctly.
Note: The ANSELA bits default to the Analog mode after Reset.
To use any pins as digital general purpose or peripheral inputs,
the corresponding ANSEL bits must be initialized to 0 by user software.
You must set the ANSELx register bits to 0 to properly use them as digital outputs without issues.

And what duty cycle do you think the register is setting them to?
Since all dual-mode analog/digital pins WILL READ AS A 0 when left in analog mode,
instructions that cause a PORT register to be read will read the pins as a 0.

This includes bit-set/bit-clear instructions like 'RC7=1;'
This is a classic 'read-modify-write' operation.

On a PIC this will:
- read the entire PORTC
- internally set bit 7 to 1
- write the result back to PORTC

ALL pins of PORTC that are in analog mode will end up being written back as a 0
except for RC7.

Now take another look at the 'while 1' code in the original post and think about it.

If you want this to work (and your chip supports it), you should always write to the LAT register, and read from the PORT register.
This is one of the reasons why they added the LAT registers in the first place.
 

Thread Starter

agsuresh

Joined Dec 28, 2023
66
The code IS setting the pins to outputs (TRIS register bits=0). That's not the problem. Nor is it a peripheral "priority" issue.


In your code in post #1 the pins are ONLY used in digital mode.

Reread the datasheet section 11.3.3 Analog Control closely...




You must set the ANSELx register bits to 0 to properly use them as digital outputs without issues.


Since all dual-mode analog/digital pins WILL READ AS A 0 when left in analog mode,
instructions that cause a PORT register to be read will read the pins as a 0.

This includes bit-set/bit-clear instructions like 'RC7=1;'
This is a classic 'read-modify-write' operation.

On a PIC this will:
- read the entire PORTC
- internally set bit 7 to 1
- write the result back to PORTC

ALL pins of PORTC that are in analog mode will end up being written back as a 0
except for RC7.

Now take another look at the 'while 1' code in the original post and think about it.

If you want this to work (and your chip supports it), you should always write to the LAT register, and read from the PORT register.
This is one of the reasons why they added the LAT registers in the first place.
Thank you for putting it in right perspective.
 

BobTPH

Joined Jun 5, 2013
11,515
Since all dual-mode analog/digital pins WILL READ AS A 0 when left in analog mode,
instructions that cause a PORT register to be read will read the pins as a 0.
Okay. I had not noticed the writes to ports. If you read the datasheet, you will know that you should never write to the port registers. You write the corresponding lat register, which overcomes that problem.
 

Thread Starter

agsuresh

Joined Dec 28, 2023
66
Okay. I had not noticed the writes to ports. If you read the datasheet, you will know that you should never write to the port registers. You write the corresponding lat register, which overcomes that problem.
Actually it doesn't. I had originally written to LAT. It didn't help in this case.

setting the ANSEL only worked.
 

Thread Starter

agsuresh

Joined Dec 28, 2023
66
Thank you for putting it in right perspective.
The code IS setting the pins to outputs (TRIS register bits=0). That's not the problem. Nor is it a peripheral "priority" issue.


In your code in post #1 the pins are ONLY used in digital mode.

Reread the datasheet section 11.3.3 Analog Control closely...




You must set the ANSELx register bits to 0 to properly use them as digital outputs without issues.


Since all dual-mode analog/digital pins WILL READ AS A 0 when left in analog mode,
instructions that cause a PORT register to be read will read the pins as a 0.

This includes bit-set/bit-clear instructions like 'RC7=1;'
This is a classic 'read-modify-write' operation.

On a PIC this will:
- read the entire PORTC
- internally set bit 7 to 1
- write the result back to PORTC

ALL pins of PORTC that are in analog mode will end up being written back as a 0
except for RC7.

Now take another look at the 'while 1' code in the original post and think about it.

If you want this to work (and your chip supports it), you should always write to the LAT register, and read from the PORT register.
This is one of the reasons why they added the LAT registers in the first place.
ALL pins of PORTC that are in analog mode will end up being written back as a 0
except for RC7.

This is absolutely correct. Actually you nailed it correctly.


I was writing code for another project using the same PIC.

Instead of One ADC in the previous one , This projects has 4 ADC inputs. in addition there is LCD also.

As usual all the PINs and LCD were initialized and defined.

However the funny part is three of the ADC started working nicely, one failed on RC1. At first I thought it was due to some settings in the ADC code. Then I remembered what you wrote.

I moved the Pin initialization of RC1 from the top to below the lcd initialization And IT WORKED.
I believe when LCD got initialized, the PORT changed its state from analog to digital. LCD uses all the PORTC pins except RC0 and RC1.
 

Thread Starter

agsuresh

Joined Dec 28, 2023
66
Did you ALL writes to use LAT? That should fix it.
in the search for the right answer I even wrote his code , though it is childish

void lowSwitch(int y )
{
TRISCbits.TRISC2= 0 ;
if (y==1){
RC2=1; //lowLed 14
LATCbits.LATC2 = 1 ; // RC2=1; //LOW_PORT=0; //14
// reversed just for testing
LATCbits.LATC2 = 1 ; // RC2=1; //LOW_PORT=0; //14
RC2=1; //lowLed 14


}
else if (y==0) {
RC2=0; //lowLed 14
LATCbits.LATC2 = 0 ; // RC2=1; //LOW_PORT=0; //14

}

}

However it didn't work till ANSEL was set.

In another project with same PIC
I had written
INB1_TRIS = INPUT ;
INB1_ANS =ANALOG ;
/*
INB2_ANS = 1; //ANALOG ;
INB2_TRIS = 1; // INPUT ;
*/

INB3_TRIS = INPUT ;
INB3_ANS =ANALOG ;

INB4_TRIS = INPUT ;
INB4_ANS =ANALOG ;


lcd_init();
INB2_ANS = 1; //ANALOG ;
INB2_TRIS = 1; // INPUT ;

Had to bring down INB2 ... below lcd_inti() . It doesn't work before the call.

LCD and the two ADC are on PORTC (RC0 - works and RC1 - problem) The other two are on PORT A.

RC1 has PWM4 output too. I might be wrong in thinking that this could be creating the issue. Another friend here pointed it out.
Unfortunately I don't have a oscilloscope to confirm, planning to buy one .
 
Top