|
|
View previous topic :: View next topic |
Author |
Message |
lotfibedui
Joined: 17 Mar 2013 Posts: 3
|
16F887 ADC problem |
Posted: Wed Mar 20, 2013 7:40 am |
|
|
hi
I work on a project to realize a temperature acquisition card based in a 16F887 microcontroller,and controlled by computer, so I tried to realize my program in C (with pic C compiler) to be able to read temperature value,convert this value to numeric value and exchange data between my card and the PC via the rs 232 connection, but I can not succeed in this task as I am new in this field.
then I will post my code and I'll be grateful if someone can help me to modify it to be functional
Code: |
#include <16F887.h>
#DEVICE ADC=10
#use delay(clock=4000000)
#use rs232(Baud=9600,Xmit=pin_C6,rcv=pin_C7,parity=N,BITS=8)
#byte PORTA= 0x05
#byte PORTB= 0x06
#byte PORTC= 0x07
#byte PORTD= 0x08
#byte TRISA= 0x85
#byte TRISB= 0x86
#byte TRISC= 0x87
#byte TRISD= 0x89
#byte TXSTA= 0X98
#byte RCSTA= 0X18
#BYTE SPBRG= 0x99
#byte ADRESL=0x9E
#BYTE TXREG= 0x19
#byte ADCON1=0x9F
#byte ADCON0=0x1F
#byte RCSTA= 0x18
#byte ANSEL= 0x188
#byte PIE1 = 0x8c
#byte PIR1 = 0x0c
#BYTE SPBRG=0x99
#BYTE TRISB=0x86
#BYTE TRISA=0x85
#BYTE PCON= 0x8E
#BYTE PORTA=0x05
#bit GODONE= ADCON0.1
#bit ADFM = ADCON1.7
#bit VCFG0=ADCON1.4
#bit VCFG1=ADCON1.5
#bit adcs1=ADCON0.7
#bit adcs0=ADCON0.6
#bit ADON=ADCON0.0
#bit ADIE=PIE1.6
#bit ADIF=PIR1.6
///////////////////////
#BIT RCIE=PIE1.5
#BIT TXIF=PIE1.4
#BIT RA1=PORTA.0
#BIT RA2=PORTA.1
#BIT TRMT=TXSTA.1
int i=0;
float v;
/////////////// Initialisation des ports ///////////////
void pic_init()
{
set_tris_A(0XAF);
set_tris_B(0X3F);
set_tris_C(0X81);
set_tris_D(0X80);
set_tris_E(0X07);
}
/////////////// Configuration du CAN ////////////////
void config_adc()
{
setup_adc(ADC_clock_internal);
setup_adc_ports(ALL_ANALOG);
set_adc_channel(0);
delay_us(500);
}
//////// lecture et conversion de la température capté par les sondes ///////
void lect_temp()
{
int R;
ADON=1;
GODONE=1;
ADIF=0;
ADIE=1;
while(GODONE)
{
v=read_adc()/205.7;
}
ADON=0;
R=v/0.001;
t=(R-1)/25974.025;
delay_us(1000);
}
///////////////////////////// configuration du USART ///////////////////////////
void config_UART( )
{
TXSTA=0X24;
RCSTA=0X90;
}
/////////////////// Configuration du rs232 /////////////////////
void send_data(int x)
{
x=v;
TXREG=x;
while(TRMT==1);
{
delay_ms(50);
}
}
void enable_serial()
{
SPBRG=0x19; //0x19 = 9600 Baud - 4MHz
TXSTA=0x24;
RCSTA=0x80;
}
void disable_serial()
{
TXSTA=0x00;
RCSTA=0x00;
}
////////////////////// programme principal //////////////////////
void main()
{
float temp;
pic_init();
ADRESL=0;
ADFM=1;
ANSEL=0XFF;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
config_adc();
temp=lect_temp();
config_uart();
TXREG=temp;
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab
enable_serial();
bit_set(PCON,3);
enable_serial();
send_data(i);
delay_ms(1000);
} |
Note that when I compile it works without error, but when i simulate with ISIS that gives a wrong result (always zero) ;(
I'm not a professional in programing so please make it simple |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Wed Mar 20, 2013 8:20 am |
|
|
Please read PIC101.
Please note that this forum is NOT for ISIS/Proteus projects.
Please read the various examples CCS gives in the EXAMPLES folder.
There are programs there that do work,though will have to be slightly modified to work with an '887.
Actually 99% of the code you show is NOT required is using the CCS C compiler.
oh ...always add 'errors' to the use rs232(...options).
hth
jay |
|
|
lotfibedui
Joined: 17 Mar 2013 Posts: 3
|
|
Posted: Fri Mar 22, 2013 5:02 am |
|
|
thanx man,i'll try to do what you say ) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Fri Mar 22, 2013 6:11 am |
|
|
Seriously, though I would not post 'solutions' normally, this is so hideously 'wrong', that I'll post a mini version of what I think you might be trying to do. One critical thing is to remember that you are generating a floating point number, and hasn't got a hope of being sent in one byte....
Code: |
#include <16F887.h>
#DEVICE ADC=10
#use delay(clock=4000000)
#use rs232(Baud=9600,Xmit=pin_C6,rcv=pin_C7,parity=N,BITS=8,ERRORS)
//Good so far
void config_adc(void)
{
setup_adc(ADC_CLOCK_DIV_8);
//Read the data sheet on the ADC clock requirements and when
//not to use ADC_CLOCK_INTERNAL
setup_adc_ports(sAN0);
//Only select the bits you want here. Every bit connected to the
//ADC is extra noise
set_adc_channel(0);
delay_us(20);
}
//////// lecture et conversion de la température capté par les sondes ///////
float lect_temp()
{
float R;
R=read_adc()*0.0001867;
//Multiplication is always faster than division
return R;
}
////////////////////// programme principal //////////////////////
void main()
{
float temp;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
config_adc();
do
{
temp=lect_temp();
printf("Val = %7.4F\n\r",temp);
delay_ms(250);
} while (TRUE);
//Remember you need to keep doing what you are trying to do
}
|
Now, seriously value is probably not going to be what you want, but it is based on your (screwy) arithmetic, where you take the value from the ADC (0 to 1023), divide by 205 to get approx 0 to 4.97 (volts approx), then multiply this by 1000 (approx mV), then divide this by 25974 to give a value from 0 to 0.191. What significance this value has, I have no idea. You probably need to 'rethink' your maths, but seriously, multiplication is always faster and smaller than division, so I've just done one multiplication to give a result of the same sort of value your original code does, and then returned this to the main code where I print it. You try to put the value into the TXREG. Remember can accept a single _byte_ only. Not a floating point value. I show how printf does this. You also don't want to switch the port on/off, or the receiving device will see 'break' being sent.
The compiler handles enabling things, TRIS, etc. etc..
Fiddling directly with registers is a sign of somebody trying to use assembler, not CCS C.
Best Wishes |
|
|
lotfibedui
Joined: 17 Mar 2013 Posts: 3
|
|
Posted: Fri Mar 22, 2013 12:34 pm |
|
|
Thanks alot for your help man |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Mar 23, 2013 2:58 am |
|
|
Second line in your program should always be the #fuses line, i.e. the line immediately after the include file for your processor model. Code: | #include <16F887.h>
#fuses XT, NOLVP, NOWDT | More fuses can be added if you want to, but the above will suffice for 95% of the programs.
Change XT to HS for crystal frequencies > 4MHz.
Perhaps you have the #fuses line added to the header file, but that is not the correct location. It will create problems when a newer compiler version comes out. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sat Mar 23, 2013 7:07 am |
|
|
This in Proteus so it likely doesn't care about many of his syntax errors.
One of the many major problems with Proteus! _________________ Google and Forum Search are some of your best tools!!!! |
|
|
|
|
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
|