|
|
View previous topic :: View next topic |
Author |
Message |
sebalitter
Joined: 05 May 2015 Posts: 47
|
16f1823 adc constant value |
Posted: Mon Mar 18, 2019 4:22 pm |
|
|
Hi There!
I'm using 16F1823 with flex_lcd420. PICKIT4 , CCS v5.081 , MPLAB X 5.15 , win 7
Don't know what wrong in my project.
The ADC is always showing 130 in the lcd despite of the potentiometer regulation in PIN A4 (AN3)
some advice?
Thank you
Code: |
#include <16F1823.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin enabled
#use delay(clock=1M) // Configuracion reloj interno
#include <flex_lcd420.c>
int8 segundos=0;
void mostrar_lcd(void){
lcd_putc("\f"); // borramos la palabra para entrar a otra instruccion
delay_us(10); // (0-1023)
int16 value = read_adc();
// entree=0-1023;
//lcd_gotoxy (1,1);
//Orden -> columna , fila
//printf(lcd_putc, " VOLTAJE "); // manifestamos la palabra en nuestro lcd
lcd_gotoxy (1,2); //Ubicamos la palabra en la segunda fila y la primera columna
printf(lcd_putc, "ADC Value %ld ",value);
lcd_gotoxy (1,3);
printf(lcd_putc, "RELOJ %02u", segundos );
}
#INT_TIMER1
void oscilacion(void)
{
segundos++;
mostrar_lcd();
set_timer1(0x85EE);
}
void ini_pic(void)
{
set_tris_c(0b000000); // Configuramos salidas y entradas
set_tris_a(0b111111);
lcd_init();
//CONFIG ADC
setup_vref(VREF_ON|VREF_ADC_4v096);
setup_adc_ports(sAN3|VSS_VDD); // ADC entre Vdd et Vss
setup_adc(ADC_CLOCK_INTERNAL);
//CONFIG TIMER
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); // Configuración timer1
setup_oscillator(OSC_1MHZ);
enable_interrupts(GLOBAL); // habilitar interrupciones
enable_interrupts(INT_TIMER1); // habilitar interrupcion timer 1
//1 s = 4/1000000Hz * 8 * (2^16 - TMR1) -> TMR1 = 34286 ( 0x85EE )
set_timer1(0x85EE); // tiempo desborde 1seg
}
void main()
{
ini_pic();
while(1);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 18, 2019 4:37 pm |
|
|
You need to select the adc channel before you read it. Example:
Code: |
set_adc_channel(3);
delay_us(5); // 16F1823 data sheet says Tacq = 4.42 usec
|
Put this at the end of your Config ADC section.
Also the 16F1823 datasheet recommends that you use
Code: | setup_adc(ADC_CLOCK_DIV_2); |
with a 1 MHz oscillator, instead of what you have in your code:
Quote: | setup_adc(ADC_CLOCK_INTERNAL); |
|
|
|
sebalitter
Joined: 05 May 2015 Posts: 47
|
float in lcd |
Posted: Wed Mar 20, 2019 9:01 pm |
|
|
Thank you PCM programmer .
one more please...
the compiler is throwing error to compile this...
3_phase_Volt.X\3_phase_Volt.c:132:2: Error#71 Out of ROM, A segment or the program is too large oscilacion
some problem to show float numbers
Code: |
char value_string[5] = "";
float value_adc = 5.54f;
sprintf(value_string, "%5.2f", value_adc);
lcd_gotoxy (1,1);
printf(lcd_putc, "%s ",value_string);
lcd_gotoxy (1,2);
printf(lcd_putc, "%f ",value_adc);
|
thank you |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: float in lcd |
Posted: Thu Mar 21, 2019 4:18 am |
|
|
sebalitter wrote: |
The compiler is throwing error to compile this...
3_phase_Volt.X\3_phase_Volt.c:132:2: Error#71 Out of ROM, A segment or the program is too large oscilacion
Some problem to show float numbers.
|
The 16F1823 has only one 2K segment for program memory. So your
program compiles to more than 2K. It won't fit in your PIC. You have
to cut part of it, or get a larger PIC. I suggest get rid of the floating point.
I made a test program:
Code: | #include <16F1823.h>
#fuses INTRC_IO, NOWDT, PUT, BROWNOUT
#use delay(clock=4M)
//=================================
void main()
{
float a, b, c;
a = b * c;
a = b / c;
a = b + c;
a = b - c;
while(TRUE);
} |
This program compiles to 763 words (out of 2048 total for the PIC).
If I comment out the five floating point lines above, it compiles to 16 words.
So floating point can easily take up 1/3 of your PIC. Try to find a way
to avoid using it. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Thu Mar 21, 2019 6:46 am |
|
|
He should look at scaled int32's using %5.2lw instead. Depends on what
arithmetic he is actually doing (which isn't shown), but likely he can save
a lot of time, and significant space. |
|
|
sebalitter
Joined: 05 May 2015 Posts: 47
|
16f1823 adc constant value |
Posted: Sat Mar 30, 2019 10:10 am |
|
|
I'm displaying read_adc() values from AC voltmeter, which should be between 0 - 1023, but never goes beyond 227. You know why ?
At the oscilloscope i see values from 1 to 4 volts (after resistor divider).
Code: |
#define SAMPLES 1000
void main (void)
{
int16 i;
int16 adc1, acum=0, valorMax=0;
lcd_init();
setup_adc_ports(sAN2|VSS_FVR);
setup_vref(VREF_ADC_4v096);
setup_adc(ADC_CLOCK_INTERNAL);
while(TRUE){
for(i=0;i<SAMPLES;i++){
set_adc_channel(2);
delay_us(10);
adc1=read_adc();
acum=adc1;
if(acum>valorMax)
valorMax=acum;
}
delay_ms(1000);
lcd_gotoxy(1,1);
printf(lcd_putc,"\fVr: %.2f V ",valorMax*0.707);
lcd_gotoxy(1,2);
printf(lcd_putc,"%lu",adc1);
valorMax=0;
acum=0;
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 30, 2019 12:18 pm |
|
|
Loook at read_adc() in the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
They have a nice little color chart. If you have a PIC
with a 10-bit ADC and you want read_adc() to give you
the full 0 to 3FF output, what #device ADC=?? line should
you place after your #include statement ?
Code: | #include <16F1823.h>
#device ADC=?? |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Sat Mar 30, 2019 1:20 pm |
|
|
Also as a long term comment, ADC_CLOCK_INTERNAL is not recommended
for operation above 1MHz, unless you sleep the processor during the
conversion. The data sheet will list the recommended clock divisor
to use from the Fosc. Use this.
Then your max 0.707, will drink ROM.
Instead use integer. Multiplying a maximum value of 1023, by 0.707
gives 723.26. Now with just 10bits, only four digits here actually contain
real data. So displaying with two decimals is pointless.
So to give the equivalent using integer, and one decimal, use:
Code: |
int32 temp;
temp=valorflex*905;
temp/=128;
printf(lcd_putc,"\fVr: %.1lw V ",temp);
|
This will give you 723.2 displayed for 1023, and be smaller and
faster.
905/128 = 7.07, giving you an integer value 10* the float result,
which *w displays as a decimal value. |
|
|
|
|
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
|