View previous topic :: View next topic |
Author |
Message |
Guest
|
Problem with 4.xx complier and read_adc |
Posted: Sat Apr 21, 2007 3:52 am |
|
|
When I change my complier PCH version to V. 4.xxx, my read_adc routine
returns adc value + 1024 (0x400) (max value is 0x3ff)
ADC=10
PIC18F452 and 18F4620
unsigned int16 value;
set_adc_channel(5);
delay_us(200);
value=read_adc();
// value&=0x3ff; THIS IS NOT WORK, why ?
rs232_buffer[2]=*(&value);
rs232_buffer[3]=*(&value+1);
rs232_buffer[3]&=0x03; // This remove 0x400 bit and work.
But, why read_adc give wrong value and why value&=0xff not work ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Apr 21, 2007 4:01 am |
|
|
Quote: | When I change my complier PCH version to V. 4.xxx |
There is a large difference between the operation of vs. 4.001 and
vs. 4.032.
http://www.ccsinfo.com/devices.php?page=versioninfo
What is your actual compiler version ? |
|
|
Ttelmah Guest
|
|
Posted: Sat Apr 21, 2007 5:03 am |
|
|
Also, as posted, the addressing, will 'hit' the change in syntax implemented here. CCS, now implements pointer arithmetic _correctly_ older versions didn't. However this means:
rs232_buffer[3]=*(&value+1);
will access the _next_ 16bit value, not the next byte.
This needs to change to:
rs232_buffer[3]=*(((int8 *)&value)+1);
To behave as it did on the older compiler.
There is probably nothing wrong with 'read_adc', but the wrong byte is being accessed for the MSB.
Best Wishes |
|
|
torpana
Joined: 21 Apr 2007 Posts: 1
|
THANKĀ“s VERY MUCH.... |
Posted: Thu Apr 26, 2007 12:46 pm |
|
|
I spend 6 hours and I never think, that the cause of error is in
the rows, which put 16 bit value to 8-bits array.
value=read_adc();
rs232_buffer[2]=value;
value>>=8;
rs232_buffer[3]=value;
It seems in C/ASM file, that I can do palcement this kind of way
and its generate very few rows code. _________________ Timo Orpana
Custom Control Inc
Finland |
|
|
Ttelmah Guest
|
|
Posted: Thu Apr 26, 2007 2:58 pm |
|
|
You can do it very quickly in C as well.
rs232_buffer[2]=make8(value,0);
rs232_buffer[3]=make8(value,1);
Or use a union.
Though the form you post, works for the first line, it unnecessarily accesses the whole variable, and then takes the low byte of this (the compiler may well be smart enough to not generate extra instructions for this). However the rotation is uneccessary, the second line, just accesses the second byte, without rotation etc.. A lot quicker.
Best Wishes |
|
|
|