|
|
View previous topic :: View next topic |
Author |
Message |
artohautala
Joined: 17 Nov 2011 Posts: 187
|
<stdlib.h> problem with PIC16F88 |
Posted: Sun Jan 21, 2018 9:46 am |
|
|
Hello , I'm very pleased if you can help me about that little problem ...
I can't understand why there's no pulses in output PWM1 pin RB0 if I use this:
////#include <stdlib.h> //this: poison !!!! //this: poison !!!!
I want to use atoi() or atol() functions to send data from my PC
to PIC16F88
In that code there's pulses normally way but if I activate this:
//#include <stdlib.h> //this: poison !!!!
there's no pulses anymore!
all the best
-arto-
Code: |
//#device PIC16F88
#include <16F88.h>
//#device PIC16F88
#device ADC=10
#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=16000000)
//#include <stdlib.h> //this: poison !!!!
#include <math.h>
#define green_led_ON output_high(pin_B2)
#define green_led_OFF output_low(pin_B2)
#define red_led_ON output_high(pin_B1)
#define red_led_OFF output_low(pin_B1)
#define lowbat_led_ON output_high(pin_B5)
#define lowbat_led_OFF output_low(pin_B5)
void led_demo(void);
int16 test_battery(int16 ad_battery);
int16 meas_temp(int16 kty_temp);
//*********************************************************************************************
void main(void){
int16 kty_temp,ad_battery,PWM_value;
int1 loop;
char chones,chtens,chhundreds;
unsigned int ones,tens,hundreds;
delay_ms(500);
#use rs232(baud=9600, xmit=PIN_B4,rcv=PIN_B3)
//set_tris_b(0B11111110);
// pin A0 measures temperature,pin A1 measures battery voltage:
setup_adc_ports(ALL_ANALOG);
setup_adc_ports(sAN2 | VREF_VREF | VREF_LOW);
setup_adc_ports(sAN3 | VREF_VREF | VREF_HIGH);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_CLOCK_DIV_16);
led_demo();
goto ohi;
chhundreds = getch();
chtens = getch();
chones = getch();
/*
hundreds = atoi(chhundreds);
tens = atoi(chtens);
ones = atoi(chones);
*/
//ohi:
hundreds = 1;
tens = 2;
ones = 3;
PWM_value = hundreds *100;
PWM_value = PWM_value + (tens *10) ;
PWM_value = PWM_value + ones ;
//hundreds = atoi(chhundreds);
//PWM_value = atol(string);
ohi:
//PWM_value = 255; //PWM value 255 = 50 %
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,127,1); //PWM freq. = (1/16000000)*4*1*128=32 us = 31250 Hz
//hundreds = 'n';
//set_pwm1_duty(PWM_value);
PWM_value = 123;
//set_pwm1_duty(155);
while(loop){
set_pwm1_duty(PWM_value);
ad_battery = test_battery(ad_battery);
kty_temp = meas_temp(kty_temp);
//\r = carriage return, \n = next row:
printf("%Lu %Lu %Lu \n \r ",ad_battery, kty_temp,pwm_value);
delay_ms(1500);
}
}
//*********************************************************************************************
void led_demo(void){
int8 led_counter;
//blink green and red leds 5 times:
for(led_counter=0; led_counter<6; ++led_counter){
green_led_ON ; delay_ms(150);
green_led_OFF ; delay_ms(150);
}
for(led_counter=0; led_counter<6; ++led_counter){
red_led_ON ; delay_ms(150);
red_led_OFF ; delay_ms(150);
}
for(led_counter=0; led_counter<6; ++led_counter){
lowbat_led_ON ; delay_ms(150);
lowbat_led_OFF ; delay_ms(150);
}
}
//*********************************************************************************************
int16 test_battery(int16 ad_battery){
set_adc_channel(1);
delay_ms(10);
ad_battery = read_ADC();
if(ad_battery <= 512) //battery voltage below 8.3 V turn lowbat_led_ON
lowbat_led_ON;
else
lowbat_led_OFF;
//setup_adc(ADC_OFF);
return ad_battery;
}
//*********************************************************************************************
int16 meas_temp(int16 kty_temp){
set_adc_channel(0);
delay_ms(10);
kty_temp = read_ADC();
return kty_temp;
}
//********************************************************************************************* |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19563
|
|
Posted: Sun Jan 21, 2018 11:58 am |
|
|
You problem is not stdlib.
It is your code.
This:
#use rs232(baud=9600, xmit=PIN_B4,rcv=PIN_B3)
Is a _preprocessor_ directive, not a line of code. It has to appear up just after the clock statement, and _must_ appear before any code that uses the stdio functions. Without this there is nothing for 'standard I/O' to route to.
When you load stdlib, it _requires_ this to have already be defined..... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jan 21, 2018 12:12 pm |
|
|
Also,
This is wrong. These ADC functions do not operate sequentially.
Only the last one takes effect:
Quote: | setup_adc_ports(ALL_ANALOG);
setup_adc_ports(sAN2 | VREF_VREF | VREF_LOW);
setup_adc_ports(sAN3 | VREF_VREF | VREF_HIGH);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_CLOCK_DIV_16);
|
You should change these 5 lines into just 2 lines. You can combine
ADC pin setups in one call to setup_adc_ports(). You need to do that.
Also, decide what ADC clock divisor you need, and just have one line for it.
In addition to that, you have the following lines in your program:
Quote: | set_adc_channel(0);
set_adc_channel(1); |
These lines use ADC channels 0 and 1. But look at your setup lines
above this. You are attempting to configure ADC channels 2 and 3 for use.
The ADC channel selection has to match the setup.
This is seriously messed up code. You need to fix this. |
|
|
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Sun Jan 21, 2018 12:27 pm |
|
|
Ttelmah wrote: | You problem is not stdlib.
It is your code.
This:
#use rs232(baud=9600, xmit=PIN_B4,rcv=PIN_B3)
Is a _preprocessor_ directive, not a line of code. It has to appear up just after the clock statement, and _must_ appear before any code that uses the stdio functions. Without this there is nothing for 'standard I/O' to route to.
When you load stdlib, it _requires_ this to have already be defined..... |
Thank's for your good answer
I was sure that it is my error and stdlib() is ok for sure
but I found my very stupid error
main loop must be set loop = TRUE...
because it randomly is FALSE or TRUE when power is ON and OFF...
Thank you so much ... have good days and be happy
|
|
|
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Sun Jan 21, 2018 12:43 pm |
|
|
PCM programmer wrote: | Also,
This is wrong. These ADC functions do not operate sequentially.
Only the last one takes effect:
Quote: | setup_adc_ports(ALL_ANALOG);
setup_adc_ports(sAN2 | VREF_VREF | VREF_LOW);
setup_adc_ports(sAN3 | VREF_VREF | VREF_HIGH);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_CLOCK_DIV_16);
|
You should change these 5 lines into just 2 lines. You can combine
ADC pin setups in one call to setup_adc_ports(). You need to do that.
Also, decide what ADC clock divisor you need, and just have one line for it.
In addition to that, you have the following lines in your program:
Quote: | set_adc_channel(0);
set_adc_channel(1); |
These lines use ADC channels 0 and 1. But look at your setup lines
above this. You are attempting to configure ADC channels 2 and 3 for use.
The ADC channel selection has to match the setup.
This is seriously messed up code. You need to fix this. |
I'm not sure about it ... what you mean ...
I have very accurate reference +5V ic ref02 connected to pin RA3 it is
Vref high and pin RA2 is reference low connected to gnd via 270 ohms resistor ...
so I'm gonna use better reference than +5V power supply to PIC...
I understand that maybe this line is better to comment away: setup_adc(ADC_CLOCK_DIV_16);
anyway my AD functions works rather well in practice
Thank you for your good advice !
all the best for you
-arto- |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19563
|
|
Posted: Sun Jan 21, 2018 1:22 pm |
|
|
Comments inline:
Code: |
setup_adc_ports(ALL_ANALOG);
//at this point the ADC is set with all pins analog, and the default VREF
setup_adc_ports(sAN2 | VREF_VREF | VREF_LOW);
//Now it is set to only have AN2 analog, and VRef+ to Vref-. This then
//goes wrong because 'VREF_LOW' is not a setting for the ADC
//You cannot mix settings to the wrong command.....
setup_adc_ports(sAN3 | VREF_VREF | VREF_HIGH);
//Now the ADC is set to use the Vref+ to Vref- pin. Again then goes wrong
//because VREF_HIGH is not a setting for the ADC
setup_adc(ADC_CLOCK_INTERNAL);
//Now it is set to use the internal clock (don't use above 1MHz)
setup_adc(ADC_CLOCK_DIV_16);
//Now the master oscillator/16.
//From your code you are using AN0 and AN1:
//All that is needed is:
setup_adc_ports(sAN0 | sAN1 | VREF_VREF);
//It is now set to use the two external Vref pins and allow readings
//from AN0 and AN1.
setup_adc(ADC_CLOCK_DIV_16);
|
When you repeat settings, it is only the last one that applies... |
|
|
|
|
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
|