|
|
View previous topic :: View next topic |
Author |
Message |
brianm
Joined: 08 Mar 2008 Posts: 17
|
ADC on 16f690 using CCS |
Posted: Wed Oct 15, 2008 9:31 am |
|
|
I am using the following code to read 3 temperature sensors attached to a 16F690 .... I use 3 of the ADCs at a0, a1, a2.
Now my problem is that I have tried to use b4 and b5 and I get very erratic reading from those pins....same program just changing the read ADC ports.
Is there something special about the b4 & b5 pins that my code doesn't take into account or maybe my code is not taking something into account period.
Any thoughts
Thanks
Code: |
// version1.01
//
#include <16F690.h>
#device adc=10
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT , NOMCLR
#use delay(clock=4000000)
#use rs232(baud=4800, xmit=PIN_B7, rcv=PIN_B6)
#include <MATH.H>
#include <stdlib.h>
#define pc3 pin_c3
#define pc0 pin_c0
int digit1;
int digit2;
int digit3;
int digit4;
int i;
int y;
int adcchannel;
int rem2;
int rem3;
long rem4;
int var1;
int var2;
int var3;
int var4[12];
long value;
long min;
long max;
//long avg;
long tavg;
long tvalue;
//long adc;
float voltage;
float temperature;
int abstemp;
long absroundtemp;
long ivoltage;
//===============================
void main() {
//setup_comparator(NC_NC_NC_NC);
output_c(0);
var1 = 0;
var2 = 3;
var3 = var1 / var2;
// common anode
//
// segment pin
// ------- ---
// a rc0
// b rc1
// c rc2
// etc
// g rc6
//
// var4 is the decimal equivalent output for the numbers 0 thru 9
//
var4[0] = 64; /* 1000000 */
var4[1] = 249; /* 1111001 */
var4[2] = 36; /* 0100100 */
var4[3] = 48; /* 0110000 */
var4[4] = 25; /* 0011001 */
var4[5] = 18; /* 0010010 */
var4[6] = 2; /* 0000010 */
var4[7] = 120; /* 1111000 */
var4[8] = 0; /* 0000000 */
var4[9] = 16; /* 0010000 */
var4[10] = 63; /* 0111111 */
setup_adc(adc_clock_internal);
setup_adc_ports(sAN0|sAN1|sAN2);
//===========================================
while (true){
for(y=1; y<=3; ++y) {
//printf(" For y = ");
//printf(" %u",y);
//printf("\n\r");
if (y<=1)
adcchannel = 2; // pin a2
if (y==2)
adcchannel = 0; // pin a0
if (y==3)
adcchannel = 1; // pin a1
set_adc_channel(adcchannel);
delay_us(20);
//adc = read_adc();
//===================================
//do {
min=0xffff;
max=0;
tvalue = 0;
for(i=0; i<=29; ++i) {
delay_ms(100);
value = read_adc();
tvalue=tvalue+value;
//printf(" %5Lu",value);
if(value<min)
min=value;
if(value>max)
max=value;
}
tavg = tvalue/30.0;
value=tavg;
// printf("\n\r Average adc reading is %4Lu",avg);
// printf("\n\r Total: %5Lu Average: %5Lu",tvalue,tavg);
// printf(" Min: %4Lu Max: %4Lu",min,max);
//===================================
voltage = (tavg/1023.0)*(500.0)/100.0;
//voltage = 213.4533434343;
temperature = (voltage-2.73)*100;
//printf("BEFORE ROUNDING Temperature is : ");
//printf("%4.1f",temperature);
//printf(" C\n\r");
abstemp = abs(temperature);
//printf("ABS Temperature is : ");
//printf("%u",abstemp);
//printf(" C\n\r");
//now round the temperature to the nearest integer
if((temperature-abstemp) > 0.5)
{
temperature=ceil(temperature);
}
else
{
temperature=floor(temperature);
}
absroundtemp = abs(temperature);
//printf(" Temperature is : ");
printf("%Ld",absroundtemp);
printf(" ");
//printf(" y= ");
//printf("%u",y);
if (y == 3)
printf("\n\r");
ivoltage = voltage;
//value = adc;
//value = ivoltage;
//value = 987;
digit4 = absroundtemp/1000;
rem4 = absroundtemp-(digit4*1000);
//rem4 = 654;
digit3 = rem4/100;
rem3 = rem4 -(digit3*100);
digit2 = rem3/10;
rem2 = rem3 -(digit2*10);
digit1 = rem2;
//digit4=0;
//digit3=8;
//digit2=7;
//digit1=6;
//printf("\n\rADC Value:");
//printf("%4Lu",tavg);
//printf(" Voltage:");
//printf("%4.3f",voltage);
//printf(" Temperature is : ");
//printf("%4.1f",temperature);
//printf(" C\n\r");
output_high(pin_b5);
output_c(var4[y]);
delay_ms(1000);
output_low(pin_b5);
// output_high(pin_a5);
//output_c(var4[y]);
// output_c(var4[9]);
//delay_ms(10);
//output_low(pin_a5);
//output_c(0x00); // All pins low
delay_ms(500);
for(i=0; i<=50; ++i) {
if (digit4 != 0.0)
{output_high(pin_b5);
output_c(var4[digit4]);
delay_ms(10);}
else
{};
if (digit3 != 0.0)
{output_high(pin_b5);
output_c(var4[digit3]);
delay_ms(10);
output_low(pin_b5);}
else
{};
output_high(pin_a4);
output_c(var4[digit2]);
delay_ms(10);
output_low(pin_a4);
output_high(pin_a5);
output_c(var4[digit1]);
delay_ms(10);
output_low(pin_a5);
}
var1 ++;
if (var1 == 10){
var1 = 0;
}
//} while (TRUE);
}
} //for the y loop
} |
|
|
|
ECACE
Joined: 24 Jul 2006 Posts: 94
|
|
Posted: Wed Oct 15, 2008 12:39 pm |
|
|
Looking at your code...you are touching b5, this will throw off your A/D readings. See below:
Code: | output_high(pin_b5);
output_c(var4[y]);
delay_ms(1000);
output_low(pin_b5); |
You do this a couple times in your code. I would guess this is causing some of your problems. _________________ A HW Engineer 'trying' to do SW !!! Run!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 15, 2008 12:48 pm |
|
|
Quote: | ....same program just changing the read ADC ports. |
Your setup_adc_ports() and set_adc_channel() code will also affect
the ability to make channels sAN10 and sAN11 work (pins B4 and B5).
As a general rule, post the code that fails. Don't post the good code
that doesn't fail. We need to see the bad code in order to recommend
how to fix it.
Also, use symbolic names for your pins. It's much easier to revise your
program if you do this. Example:
Code: |
#define RED_LED PIN_B5
void main()
{
output_high(RED_LED);
delay_ms(500);
output_low(RED_LED);
while(1);
} |
With this code, if you want to change the pin for the Red LED, you only
need to edit one line at the top of your program, instead of doing tedious
and error-prone edits all over the program. For example, if you want
to move the LED to pin C0, you just do this:
Code: | #define RED_LED PIN_C0 |
|
|
|
|
|
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
|