View previous topic :: View next topic |
Author |
Message |
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
Posted: Thu Mar 21, 2013 1:50 am |
|
|
Thanks everybody once again. There is no problem with LCD control pins and data pins defines. LCD is now working but adc is giving strange values.
See my code and image in the link. I am testing it both in real hardware and Proteus. I am getting the same adc values in both.
I should get 1023 for 5 V adc input. In the example I have given 2.5 V adc input. So I should get 1023/2 as the adc raw value.
Ofcourse I am using PIC16F877 MCU.
Code: |
#include <16F877.h>
#device adc=16
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use delay(clock=4000000)
#include <stdio.h>
#include <math.h>
#define LCD_ENABLE_PIN PIN_B2 ////
#define LCD_RS_PIN PIN_B0 ////
#define LCD_RW_PIN PIN_B1 ////
#define LCD_DATA4 PIN_B3 ////
#define LCD_DATA5 PIN_B4 ////
#define LCD_DATA6 PIN_B5 ////
#define LCD_DATA7 PIN_B6
#include <lcd.c>
void main()
{
int16 adc_val = 0;
float volts = 0;
set_tris_a(0x01);
set_tris_b(0x00);
delay_ms(250);
lcd_init();
delay_ms(250);
lcd_putc("\fADC Example...\n");
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(20);
//while(TRUE)
//{
adc_val = read_adc();
//volts = (float)(adc_val * 5)/1023.0;
//printf(lcd_putc, "\f%3.4f", volts);
printf(lcd_putc, "%ld", adc_val);
delay_ms(10);
//printf(lcd_putc,"%lu",voltage);
//}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Mar 21, 2013 3:21 am |
|
|
Your link doesn't work.
Read temtronics reply. The very first reply in this thread. Second item.
You are now selecting 'HS', but running at 4MHz. This is 'borderline'. Should work with most crystals, but may give problems with oscillating on an overtone on some.
Also as a comment, be aware that 'ALL_ANALOG', will encourage pickup on the other pins. It implies connecting all the pins to the analog multiplexer, which can then introduce crosstalk. Only pins you are actually going to use should be connected to the multiplexer if possible.
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Thu Mar 21, 2013 5:46 am |
|
|
other items...
1) #device adc=16
hmm ,suprised compiler doesn't give error, as adc is only 10 bit or 8 bit...
2) adc_clock setting is still wrong..
3) 10ms for main loop(rad adc..display...loop) is to fast
LCD probably can't keep up giving 'flicker'.200-500ms would be better
4) source of analog input? pot ? any filter caps?
5) Vref of ADC is Vdd.How stable is your power supply? ANY ripple will be seen in the ADC readings.A 'scope wil show this,DMM will not.
6) you commented out your 'forever loop', so program only runs once.
7) always best to delete commented out(//....) lines of code
makes it easier to see mistake, see logic flow,etc.
8) get rid of the set_tris....lines.not needed,compiler is smart !
9) would have to check but is f3.4 a valid print format?
compiler probably corrects it,just looks wrong to me
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Mar 21, 2013 6:39 am |
|
|
adc=16, triggers left justified output. Reading*64.
Gives a problem though that this won't then fit in an int16, when multiplied by 5 (this multiplication is being done in an int16), and the maths won't be correct.
Best Wishes |
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
Posted: Thu Mar 21, 2013 7:02 am |
|
|
Thank you everybody once again. making adc = 10 (10 bit) solved the problem. Now I am getting 511 for 2.5 V which is int val of 1023 / 2
I don't know why the wizard generated adc=16
I have some more questions that I will ask later. The links I posted is working for me.
http://www.pixhost.org/show/3158/16381333_adc3.jpg
http://www.pixhost.org/show/2227/16379460_adc2.jpg
Code: |
#include <16F877.h>
#device adc=10
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use delay(clock=20000000)
#include <stdio.h>
#include <math.h>
#define LCD_ENABLE_PIN PIN_B2 ////
#define LCD_RS_PIN PIN_B0 ////
#define LCD_RW_PIN PIN_B1 ////
#define LCD_DATA4 PIN_B3 ////
#define LCD_DATA5 PIN_B4 ////
#define LCD_DATA6 PIN_B5 ////
#define LCD_DATA7 PIN_B6
#include <lcd.c>
void main()
{
int16 adc_val = 0;
float volts = 0;
set_tris_a(0x01);
set_tris_b(0x00);
output_b(0x00);
delay_ms(250);
lcd_init();
delay_ms(250);
lcd_putc("\fADC Example...\n");
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(20);
//while(TRUE)
//{
adc_val = read_adc();
volts = (float)(adc_val * 5)/1023.0;
printf(lcd_putc, "\f%3.4f", volts);
//printf(lcd_putc, "%ld", adc_val);
delay_ms(10);
//printf(lcd_putc,"%lu",voltage);
//}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Thu Mar 21, 2013 7:15 am |
|
|
glad you're 'up and running'!
As you've found out...
...the 'Wizard' isn't the smartest guy in the forest! Gets his information from someone else.
I never use the Wizard, relying on first hand information aka the PIC datasheet , the appropriate device header file ,CCS C examples AND the compiler's help files.
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Mar 21, 2013 8:23 am |
|
|
The compiler automatically corrects it if the field width (left figure in the %f formatter), is too small.
Basically you are saying print a number using 3 locations, that has four decimals. Formatter should probably be %06.4f, which (remembering that the decimal is a character in the output), will print "0.0000", etc..
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Thu Mar 21, 2013 9:09 am |
|
|
too bad the compiler doesn't generate a warning--saying format invalid, autocorrecting-- it might up novice or sloppy programming .. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Mar 21, 2013 9:18 am |
|
|
Problem with that one is that 'C', simply says 'at least this wide', and that if extra space is needed this will automatically be allocated. Implies that it is realistically 'legitimate' to use a number smaller than is always going to be needed, even if it is not 'nice'....
This is where an 'option' to have a more 'lint like' check made would be nice, having it point out that the field should be larger, but leaving it up to you.
Best Wishes |
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
format |
Posted: Thu Mar 21, 2013 10:19 am |
|
|
I thought %3.4 in printf tells to print value like 000.0000 i.e., 3 digits before decimal point (dp) and 4 digits after dp. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1348
|
|
Posted: Thu Mar 21, 2013 11:17 am |
|
|
I believe the 3 specifies the "total" number of characters output (as mentioned above) and has nothing to do with the decimal place. It's for lining up outputs normally. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Mar 21, 2013 12:27 pm |
|
|
Spot on.
In C, the number in front of the dp in all output formats, is the 'total field width'. It is a common misunderstanding, that it has something to do with the numbers in front of the decimal in the result.
This comes down to reading a C book.
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Mar 22, 2013 4:34 am |
|
|
Quote: | Ofcourse I am using PIC16F877 MCU. | OK, I was just checking as it is only one letter different from the PIC16F877A.
Pin layout is compatible but programming specifications are slightly different.
Please note that your 877 is 15 years old design and Microchip has declared it a 'mature' product, meaning that it is not recommended for new designs. It's successor the 877A is also in 'mature' state. Now the PIC16F887 is recommended as an alternative.
The 877 costs $4.64 in large quantities, the newer 887 costs $1.87
Fun fact: after 13 years without changes Microchip just last month made a minor update to the PIC16F877 data sheet. |
|
|
|