|
|
View previous topic :: View next topic |
Author |
Message |
mayur.k.vadukul
Joined: 07 Jul 2022 Posts: 40
|
PIC18F14K50 - Setting Pin C7 as Analogue Input |
Posted: Tue Apr 30, 2024 4:16 am |
|
|
Can anyone please let me know whether the settings below are correct, if I want to set Pin C7 as the Analogue Input using the internal reference voltage.
I am using the internal crystal with PLL.
See the fuse settings below:-
#include <18F14K50.h>
#device ADC=10
#FUSES WDT //Watch Dog Timer
#FUSES WDT256 //Watch Dog Timer uses 1:256 Postscale
#FUSES BROWNOUT
#FUSES BORV19
#FUSES MCLR
#use delay(internal=32MHz)
#use FIXED_IO( B_outputs=PIN_B6 )
#use FIXED_IO( C_outputs=PIN_C5,PIN_C4 )
And settings for analogue pins in my main program as below:-
restart_wdt ();
setup_adc_ports(NO_ANALOGS, VSS_FVR);
setup_adc_ports(sAN9, VSS_FVR); //Set up the ADC Channel
setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_2);
I should be able to sort it with debugging, but because ICD U80 does not work as debugger with this micro with internal crystals, I can't find out easily what is happening.
Thanks. _________________ MVadukul |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Tue Apr 30, 2024 5:48 am |
|
|
my comments
1) disable the WDT ! It's not needed until your entire program has been 100% coded/compiled and working.
2) The PIC.hdr file I have doesn't have 'VSS_FVR' as an option for the ADC range. Please explain what you really need(analog input range ? )
3) debugging... use an external xtal/caps or osc module for testing. When program works, then edit for internal osc/compile/run
4) start putting comments at the end of most lines of code. It will really help you(and others) as to what you're trying to do.
others will reply...seems Mr. Sun comes up at different times in the world ! |
|
|
mayur.k.vadukul
Joined: 07 Jul 2022 Posts: 40
|
|
Posted: Wed May 01, 2024 6:22 am |
|
|
temtronic wrote: | my comments
1) disable the WDT ! It's not needed until your entire program has been 100% coded/compiled and working.
- I tried with both WDT enabled and disabled.
2) The PIC.hdr file I have doesn't have 'VSS_FVR' as an option for the ADC range. Please explain what you really need(analog input range ? )
-The option is available in the header file of ccs. 18F14K50.h.
3) debugging... use an external xtal/caps or osc module for testing. When program works, then edit for internal osc/compile/run
My hardware does not have facility to connect the crystal. The hardware works perfectly with old MPLAB -Hi-Tech compiler code. As the compiler isn't supported any more, I have converted all the codes into CCS. Whilst I was going through, I ran into the issue for this one.
4) start putting comments at the end of most lines of code. It will really help you(and others) as to what you're trying to do.
I can put comments and resend the codes. But initially I wanted to check whether my settings relating to make the C7 as analogue input is correct or not.
|
_________________ MVadukul |
|
|
mayur.k.vadukul
Joined: 07 Jul 2022 Posts: 40
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Wed May 01, 2024 11:45 am |
|
|
Not going to download code, but what you originally posted does not
have a set_adc_channel call.
I don't think the define VSS_FVR, is for the setup_adc_ports call.
That is for using FVR as the reference for the ADC.
You don't have to select the FVR in the setup_adc_ports at all. It is
always available. You just select it in the set_adc_channel call. |
|
|
mayur.k.vadukul
Joined: 07 Jul 2022 Posts: 40
|
|
Posted: Wed May 01, 2024 2:21 pm |
|
|
Ttelmah wrote: | Not going to download code, but what you originally posted does not
have a set_adc_channel call.
I don't think the define VSS_FVR, is for the setup_adc_ports call.
That is for using FVR as the reference for the ADC.
You don't have to select the FVR in the setup_adc_ports at all. It is
always available. You just select it in the set_adc_channel call. |
My whole code is below. Very Simple if the analogue input is less than 0.6V then the LED should go off else LED should come ON. The input is read every second and before being read, it flashes LED at 50uSec rate.
#include <2WPSUG_TEST_CODE.h>
#define UBYTE unsigned char
#define UINT unsigned int16
#define bit unsigned int1
#INT_TIMER0
void TIMER0_isr(void)
{
}
bit KICKED_ON;
UINT A2D_RESULT;
void LED_LOW (void)
{
output_bit (TEST_LED,0);
}
void LED_HIGH (void)
{
output_bit (TEST_LED,1);
}
void LOAD_BATT_ON (void) //We cannot have this condition otherwise the micro will keep on resetting
{
output_bit (BATT_TEST_ON, 1);
}
void LOAD_BATT_OFF (void)//We must have this as default for the purposes of the testing otherwise the micro will keep on resetting
{
output_bit (BATT_TEST_ON, 0);
}
void main()
{
restart_wdt ();
output_bit (BATT_TEST_ON, 0);
setup_adc_ports(sAN9, VSS_FVR); //Set up the ADC Channel Pin C7 should be analogue input and
LED_HIGH ();
setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_2);
KICKED_ON = FALSE;
while(TRUE)
{
restart_wdt();
if (KICKED_ON == FALSE) //if the flag is Off Read the channel
{
KICKED_ON = TRUE;
LED_LOW ();
delay_ms(50); //Blink ON-OFF to visually see it is beginnning to read the channel
LED_HIGH ();
delay_ms(50);
LED_LOW ();
set_adc_channel(sAN9);
delay_us (20); // Small delay for the channel to be ready
read_adc (ADC_START_ONLY);
}
else
{
if (adc_done() == 1)
{
A2D_RESULT = 0;
A2D_RESULT = read_adc (ADC_READ_ONLY);
if (A2D_RESULT > 600)
{
LED_HIGH (); //LED ON
}
else
{
LED_LOW (); //LED OFF
}
delay_ms(250); // Show the status for 1 second before re-reading the input
delay_ms(250);
delay_ms(250);
delay_ms(250);
KICKED_ON = FALSE; //Clear the flag only after it is read properly
}
//TODO: User Code
}
}
}
The header is below:-
#include <18F14K50.h>
#device ADC=10
#FUSES WDT //Watch Dog Timer
#FUSES WDT256 //Watch Dog Timer uses 1:256 Postscale
#FUSES BROWNOUT
#FUSES BORV19
#FUSES MCLR
#use delay(internal=32MHz,restart_wdt)
#use FIXED_IO( B_outputs=PIN_B6 )
#use FIXED_IO( C_outputs=PIN_C5,PIN_C4 )
#define BATT_TEST_BUTTON PIN_A5
#define MAINS_IP PIN_B4
#define BATT_TEST_ON PIN_B6
#define BATT_OP PIN_C4
#define TEST_LED PIN_C5
You can easily compile this by creating this and the options relating to ADC in the 18F14K50.h are below:-
////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
// SET_ADC_CHANNEL(), READ_ADC(), ADC_DONE()
// ADC Prototypes:
_bif void setup_adc(int16 mode);
_bif int8 read_adc(void);
_bif int8 read_adc(int8 mode);
_bif int16 read_adc(void);
_bif int16 read_adc(int8 mode);
_bif int1 adc_done(void);
// Constants used for SETUP_ADC() are:
#define ADC_OFF 0 // ADC Off
#define ADC_CLOCK_DIV_2 0x100
#define ADC_CLOCK_DIV_4 0x04
#define ADC_CLOCK_DIV_8 0x01
#define ADC_CLOCK_DIV_16 0x05
#define ADC_CLOCK_DIV_32 0x02
#define ADC_CLOCK_DIV_64 0x06
#define ADC_CLOCK_INTERNAL 0x07 // Internal 2-6us
// The following may be OR'ed in with the above using |
#define ADC_TAD_MUL_0 0x00
#define ADC_TAD_MUL_2 0x08
#define ADC_TAD_MUL_4 0x10
#define ADC_TAD_MUL_6 0x18
#define ADC_TAD_MUL_8 0x20
#define ADC_TAD_MUL_12 0x28
#define ADC_TAD_MUL_16 0x30
#define ADC_TAD_MUL_20 0x38
//ADC Prototypes:
_bif void setup_adc_ports(int32 pins);
_bif void setup_adc_ports(int32 pins, int32 reference);
_bif void set_analog_pins(int32 pins);
_bif void set_analog_pins(int32 pins, int32 reference);
_bif void set_adc_channel(int8 channel);
// Constants used in SETUP_ADC_PORTS() and SET_ANALOG_PINS() are:
// First argument:
// OR together desired pins
#define sAN3 0x80000 //| A4
#define sAN4 0x100000 //| C0
#define sAN5 0x200000 //| C1
#define sAN6 0x400000 //| C2
#define sAN7 0x800000 //| C3
#define sAN8 0x1 //| C6
#define sAN9 0x2 //| C7
#define sAN10 0x4 //| B4
#define sAN11 0x8 //| B5
#define NO_ANALOGS 0 // None
#define ALL_ANALOG 0xF00FF // A0 A1 A2 A4 C0 C1 C2 C3 C6 C7 B4 B5
// Optional Second argument:
#define VSS_VDD 0x000 //| Range 0-Vdd
#define VSS_FVR 0x800 //| Range 0-FVR
#define VREF_VREF 0x500 //| Range VrefL-VrefH
#define VSS_VREF 0x400 //| Range 0-VrefH
#define VREF_VDD 0x100 //| Range VrefL-Vdd
// Constants used in SET_ADC_CHANNEL() are:
// either use the channel number or one of the following
#define DAC_CHANNEL 14
#define FVR_CHANNEL 15
// Constants used in READ_ADC() are:
#define ADC_START_AND_READ 7 // This is the default if nothing is specified
#define ADC_START_ONLY 1
#define ADC_READ_ONLY 6 _________________ MVadukul |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Fri May 03, 2024 1:51 am |
|
|
OK.
First comment _USE THE CODE BUTTONS_....
Now that having been said, this was what I was puzzled by:
setup_adc_ports(NO_ANALOGS, VSS_FVR);
Pointless line. The _last_ setup_adc_ports is the one that applies. This
line is turning on the Vref, but then effectively disabling the ADC from
actually doing anything..... I was thinking you were trying to read the
FVR.
Get rid of this.
But, the reason it is not working, is simple:
set_adc_channel(sAN9);
This is wrong. set_adc_channel, _does not accept a setup_adc_ports
define. This is the key thing everywhere. The #defines _only_ apply
to the function they are offered with. set_adc_channel just accepts a
channel number. Nothing else. The channel number for AN9, is 9.
You are trying to read channel2, which is not enabled, so will read
garbage.
set_adc_channel(9);
Is the correct setting here.
Repeat 50 times, "#defines _only_ apply to the function they are declared
to be for. Using them elsewhere will not work"..... |
|
|
mayur.k.vadukul
Joined: 07 Jul 2022 Posts: 40
|
|
Posted: Fri May 03, 2024 3:17 am |
|
|
Ttelmah wrote: | OK.
First comment _USE THE CODE BUTTONS_....
Now that having been said, this was what I was puzzled by:
setup_adc_ports(NO_ANALOGS, VSS_FVR);
Pointless line. The _last_ setup_adc_ports is the one that applies. This
line is turning on the Vref, but then effectively disabling the ADC from
actually doing anything..... I was thinking you were trying to read the
FVR.
Get rid of this.
But, the reason it is not working, is simple:
set_adc_channel(sAN9);
This is wrong. set_adc_channel, _does not accept a setup_adc_ports
define. This is the key thing everywhere. The #defines _only_ apply
to the function they are offered with. set_adc_channel just accepts a
channel number. Nothing else. The channel number for AN9, is 9.
You are trying to read channel2, which is not enabled, so will read
garbage.
set_adc_channel(9);
Is the correct setting here.
Repeat 50 times, "#defines _only_ apply to the function they are declared
to be for. Using them elsewhere will not work"..... |
Thanks for your help.
It is all working now.
The reason why i use below as I found for some micros, the compiler enables analogue inputs. So as practice i disabled all the analogues first before settings up as I need.
setup_adc_ports(NO_ANALOGS, VSS_FVR);
The mistake which I did was obviously in the setting up the channel but also turning on the Vref.
I was foxed by the datasheet as the datasheet suggests there is no selection of vref selection. But the CCS compiler still needs setup_vref(VREF_1v024); argument.
for PIC18F14K50 device its either FVR which is fixed at 1.024V or VSS or VDD or external. Therefore I thought setting the analogue reference as VSS_FVR, it should turn on the FVR, but instead it required another line of code setup_vref(VREF_1v024); and the header file shows various selection voltage as well but I tried what the datasheet suggested.
Thanks for your help. _________________ MVadukul |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Fri May 03, 2024 6:25 am |
|
|
Problem here is the datasheets these days are not as well laid out as they
used to be. If you look at the FVR itself, it has a programmable 'multiplier',
when feeding the internal 'FVR' signal.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|