Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] PIC complete discussion for all

Status
Not open for further replies.
correction of my previous code for aDC..

This is the right code for left justified setting... . I just noticed Im discarding the MSB of my ADRESH..


**broken link removed**



PHP:
unsigned int adc_read()
{
	unsigned int adc_result;

	ADCON0 = 0x00;
	ADCON0bits.ADON = 1; //turn on adc

	ADCON0bits.GO_DONE = 1; //start converstion

	while(GO_DONE); //wait for converstion to finish
	ADCON0bits.ADON = 0; //turn off adc
	

	adc_result = ADRESH;
	adc_result = (adc_result << 2) | (ADRESL>>6);

	return adc_result;
	


}
 

There is no reason to do the assignment is two steps.

This is enough to do what you want, any bit that is not 1 in ADRESL or ADRESH will be set to 0 in adc_result
adc_result = ((unsigned int)adc_ADRESH<< 2) | (ADRESL>>6);

Alex
 

any bit that is not 1 in ADRESL or ADRESH will be set to 0 in adc_result

how about if the value of my ADRESH is 0b11111111 then we do like this

adc_reault = ADRESH<<2;

Is this line not discarding the MSB of ADRESH since it is only 8bit size? im confused..

---------- Post added at 15:13 ---------- Previous post was at 15:12 ----------

does the adc_result still received the 0b11111111 value from ADRESH??
 

Hi,
Since you're bit-shifting your ADC reading 2 times right, why read a 10-bit at all? Just asking. You could just use left-justification and read the ADRESH. Then, you'll get an 8-bit ADC reading.

It is also unnecessary to turn the ADC off and then turn it on again.

Hope this helps.
Tahmid.

---------- Post added at 19:15 ---------- Previous post was at 19:13 ----------

It's not discarding them. ADRESH is an 8-bit register, but adc_result is a 16-bit register. So, what you get is a 16-bit value: 0000001111111100

Hope this helps.
Tahmid.
 

how about if the value of my ADRESH is 0b11111111 then we do like this

adc_reault = ADRESH<<2;

Is this line not discarding the MSB of ADRESH since it is only 8bit size? im confused..

---------- Post added at 15:13 ---------- Previous post was at 15:12 ----------

does the adc_result still received the 0b11111111 value from ADRESH??

Actually it depends on the compiler, the resulting value after the shifting will be assigned to a 16bit variable so it is possible that the compiler will do the shifting for ADRESH using 16 bit to get the result.
In any case you can't depend on that so it is best to use typecasting, if you see my code i have placed (unsigned int) in front of the ADRESH and this is telling the compiler to treat it as a 16bit variable and then do the shifting, this way there is no change for the MSB to be lost.

Alex
 
Since you're bit-shifting your ADC reading 2 times right,
I shift my ADC result 2 times to feed my 8bit CCPR1L.

why read a 10-bit at all?
It's just that I want to read all the 10bit for future applications since I knew how to read when i need only 8bit result..


It is also unnecessary to turn the ADC off and then turn it on again.

okay.. noted.. thanks so much
 

In that case it's okay then. If you want a 10-bit value, however, I think you should use right-justification although left-justification is perfectly fine. By using right-justification, you only need to carry out bit-shift once.

Hope this helps.
Tahmid.
 

if you see my code i have placed (unsigned int) in front of the ADRESH and this is telling the compiler to treat it as a 16bit variable and then do the shifting, this way there is no change for the MSB to be lost.

I just know that now by putting like this (unsigned int) will tell the compiler to threat as 16bit variable.. thanks so much..



By using right-justification, you only need to carry out bit-shift once.

by doing like this I can get the 10bit result if it is right justified right?
adc_result = ADRES;
 

I don't know if Hi-Tech allows the read of ADRES as one register. If it does (it probably does), then that's all you need. Otherwise you can just use:
Code:
adc_result = (ADRESH << 8) + ADRESL;
or
Code:
adc_result = (ADRESH << 8) | ADRESL;

Hope this helps.
Tahmid.
 

yes Hi-techC allows that... Ive done that before.. but I have something in my mind that what if I will use left justified of getting the 10bit...
 

No problem. You can use left-justification and get 10-bit value. The justification is just a representative method for displaying the results. But the result is the same if left or right justification is used, only the way it is presented is different. I think you already know this.

Hope this helps.
Tahmid.
 

No problem. You can use left-justification and get 10-bit value. The justification is just a representative method for displaying the results. But the result is the same if left or right justification is used, only the way it is presented is different. I think you already know this.

Hope this helps.
Tahmid.

yes..

I think I should go back to SPI lesson... I need to know more about SPI interfacing..
 

I think this should help if you really want to get into the details of everything.

ww1.microchip.com/downloads/en/devicedoc/spi.pdf

And keep reading the datasheet, reference manual and all other related documents!

Hope this helps.
Tahmid.
 

No problem. You can use left-justification and get 10-bit value. The justification is just a representative method for displaying the results. But the result is the same if left or right justification is used, only the way it is presented is different. I think you already know this.

Hope this helps.
Tahmid.

thanks so much..

yes..

I think I should go back to SPI lesson... I need to know more about SPI interfacing..
 

Hi what does this mean

where I can get that 10bit resolution? in the microcontroller physical pins? sorry Im confused..

The 10-bits of resolution refers to the duty cycle of the PWM and is formed by the concatenation of both the CCPRxL register and to the CCPxCON<5:4> bits.

I assume we're still discussing the 18F4550.

Reference PIC18F2455/2550/4455/4550 Data Sheet, pg. 148, 15.4.2 PWM DUTY CYCLE
15.4.2 PWM DUTY CYCLE
The PWM duty cycle is specified by writing to the
CCPRxL register and to the CCPxCON<5:4> bits. Up
to 10-bit resolution is available. The CCPRxL contains
the eight MSbs and the CCPxCON<5:4> bits contain
the two LSbs. This 10-bit value is represented by
CCPRxL:CCPxCON<5:4>. The following equation is
used to calculate the PWM duty cycle in time:

Has anyone discussed the meaning of the term "resolution" with you? Or do you already understand the term?
 
The 10-bits of resolution refers to the duty cycle of the PWM and is formed by the concatenation of both the CCPRxL register and to the CCPxCON<5:4> bits.

I assume we're still discussing the 18F4550.

Reference PIC18F2455/2550/4455/4550 Data Sheet, pg. 148, 15.4.2 PWM DUTY CYCLE


Has anyone discussed the meaning of the term "resolution" with you? Or do you already understand the term?

yes I understand about reso..

The 10-bits of resolution refers to the duty cycle of the PWM
so meaning the Input of my PWM range from 0 to 1023?

still unclear to me.. CCPR1L is the 8bits MSB register of my PWM then the remaining two bits is in the CCPxCON<5:4> register then for example let's have this scenario

CCPR1L(8bits) + CCPxCON<5:4>(2bits) = 10bit resolution right?

so If Im going to put a 3 value for my duty cycle where do I put that? in CCPR1L which is the MSB or in the CCPxCON<5:4> which is the LSB ?

if you are going to ask me hehe since the value is 3 then I can place that to the LSB or in CCPxCON<5:4>... that confuses me If Im correct... hehe
 

yes I understand about reso..


so meaning the Input of my PWM range from 0 to 1023?

It means you can control the duty cycle of the PWM with 1024-bit resolution with '0' representing 0% or no duty cycle and 1023 representing 100% or all duty cycle.

still unclear to me.. CCPR1L is the 8bits MSB register of my PWM then the remaining two bits is in the CCPxCON<5:4> register then for example let's have this scenario

CCPR1L(8bits) + CCPxCON<5:4>(2bits) = 10bit resolution right?

so If Im going to put a 3 value for my duty cycle where do I put that? in CCPR1L which is the MSB or in the CCPxCON<5:4> which is the LSB ?

if you are going to ask me hehe since the value is 3 then I can place that to the LSB or in CCPxCON<5:4>... that confuses me If Im correct... hehe

If you want to take full advantage of the 10-bits of resolution, you would set both the CCPxCON<5:4> bits, this would represent a very small duty cycle in terms of time and percentage.

Do you want some examples?
 
If you want to take full advantage of the 10-bits of resolution, you would set both the CCPxCON<5:4> bits,
yes I read about this but I dont know how to apply.. hehe

yes example would be much better for my understanding... hehe
 

Let us perform a very simple example first.

Let's say you have a PWM frequency of 2.44 kHz or a period of approximately 410 µS. You have already setup the Time Prescaler and PR2 register correctly, but you need to generate a 50% duty cycle, 205µS on and 205µS off, in other words a normal square wave with a frequency of 2.44 kHz. You could use the formula provide by the datasheet, however is you realize that 1/2 or 50% of the possible range (0, 1023) values is 511. So there is the value you need to put into the CCPRxL:CCPxCON<5:4>, 10-bits to generate a 50/50 PWM.

Does this make sense? If not do not hesitate to tell me. I try a different scenario with less details.
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top