CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Incorrect output from pic16f877

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








Incorrect output from pic16f877
PostPosted: Sun Nov 12, 2006 8:18 pm     Reply with quote

I'm tryin to integrate an A/D converter ADS7816 with a PIC16F877. Without adding the ADC, i've programmed my pic with the following code.

Code:
#include <16F877.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)   //tell compiler clock is 20Mhz for delay function
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)   //baud rate 9600; output pin C6; input pin C7;

void main(){

   /*Declare Variables*/
   int8 msb,lsb;   // 8 bit upper,lower, bit storage
   int16 result;
   //defined as char for transmitting using putc()
   
   /*Initialise Ports*/
   //Settings: input 1 output 0; Format: Port7-Port0; Default:inputs;
    //set port A for analog and digital input/output
   set_tris_A(0b01111110); //set Port A7 as output or CS ADC
   set_tris_C(0b10110111); //Port C6:tx to rx232 & C3: SCK to ADC
   //Programming C5=SDO as input, SPI module only receives data
   set_tris_E(0b1111110);//Port E2 (CS) for ADC
   output_high(PIN_E2);   //switch off CS for external ADC
   
   /*Setup SPI*/
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
   //master mode, trigger low to to high edge, spi clock:20/16=1.25Mhz, T=0.8us
   output_high(PIN_A0);   //show SPI has started up
   
   delay_ms(3); //delay for microcontroller to get ready
   
   /*Data Acquisition & Transmission*/
   while(true){
   output_low(PIN_E2); //chip select for ADC
   delay_us(2); //wait for data conversion 2 clk cycles (1.6us)
   msb=spi_read(0);  //1 byte (8bits) filled. |B11|B10|B9|B8|B7|B6|B5|B4|
   lsb=spi_read(0);  //first 4 bits filled. last 4 bits repeated.  |B3|B2|B1|B0|---|B1|B2|B3|B4|
   output_high(PIN_E2); //stop ADC read (required by ADC) Hi to Lo to restart
   
   result = make16(msb, lsb);
   result >>= 3;
   
   putc(msb);   //transmit upper bits
   putc(lsb);   //transmit lower bits
   
   delay_ms(4);   // Delay: Sample every 4ms for sampling of 250Hz for ECG
   }

}




my tx pin keeps fiving me rubbish.. i tot it shld give mostly bits zero when i input 0V into the SPI pin (C4) and mostly bits one if i input 5V in. Am i wrong? or is my code wrong? My email address is ghostz13[at]hotmail[dot]com. Thanks in advance.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 12, 2006 8:37 pm     Reply with quote

You're sending the raw data. You need to convert it to ASCII characters
so that it can be displayed in the terminal window.

Get rid of the two putc() statements, and use a printf() statement instead.
The following line will display the result in Hexadecimal:
Code:
printf("%LX \n\r", result);


Also, you need a delay in your loop of much more than 4 ms.
Try using 500 or 1000 ms. That's much more reasonable, if your
goal is to periodically display the output on a serial terminal, to see
if your program is working properly.
Guest








PostPosted: Sun Nov 12, 2006 9:00 pm     Reply with quote

Hi, Thanks for quick reply. I'm using an oscilloscope to check my output from the tx pin(C6) of the pic16f877. if that is the case, is my raw data output wrong?

also, i intend to connect it to a max232cpe to convert it (tx pin) to rs232 format. i dun really know how to use a terminal (noob) but am i correct to say i shld use a hyperterminal in windows, increase my delay and connect it to com 1?

PCM programmer wrote:
You're sending the raw data. You need to convert it to ASCII characters
so that it can be displayed in the terminal window.

Get rid of the two putc() statements, and use a printf() statement instead.
The following line will display the result in Hexadecimal:
Code:
printf("%LX \n\r", result);


Also, you need a delay in your loop of much more than 4 ms.
Try using 500 or 1000 ms. That's much more reasonable, if your
goal is to periodically display the output on a serial terminal, to see
if your program is working properly.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 12, 2006 9:10 pm     Reply with quote

Quote:

I'm using an oscilloscope to check my output from the tx pin(C6) of the
pic16f877. if that is the case, is my raw data output wrong?

No, but it's better to view it on a terminal window because you easily
see the data in decimal or hex format, instead of having to watch
pulses moving around.

See this thread for links on how to setup Hyperterminal and the MAX232
chip, etc.
http://www.ccsinfo.com/forum/viewtopic.php?t=26898
Guest








PostPosted: Mon Nov 13, 2006 12:18 am     Reply with quote

thanks for the help, i've been able to connect to my pic through the hyperterminal n receive output. My question now is my ADC outputs format in the way...

MSB: |B11|B10|B9|B8|B7|B6|B5|B4|
LSB: |B3|B2|B1|B0|---|B1|B2|B3|B4|

so i've done tis to remove the repeated bits

lsb=(0xF0 & lsb); //remove repeated bits in lsb

how does the make16 function work? also i get a 0000 for a 0V input and a 1ffe for a 5V input. Was thinkin i wld get a 0000 for a 0V input and a 00ff for a 5V input.

still cannot get my adc (ADS7816) to work properly so i m throwing values to the SPI.

Thanks in advance..
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 13, 2006 1:07 am     Reply with quote

Comments:

1. You haven't told the compiler to use fast i/o mode, so your set_tris
statements aren't necessary. Because you are using standard_io
mode (which is the default mode of the compiler), the compiler will
automatically insert code to properly setup the TRIS for these
functions: output_high(), output_low(), setup_spi(), #use rs232().
You can delete all the set_tris_x() statements.

2. According to the bottom diagram in Figure 1 of the ADS7816
data sheet (page 9), the chip requires 3 "run-in" clocks before
it will start outputting data to the PIC. You're doing two calls
to spi_read(), which will generate 16 clocks. The A/D chip puts
out 12 bits of data, so that means a cycle consists of 3 run-in
clocks, 12 data bits, and then 1 more clock. So it looks like
you need to do this, to get a 12-bit, right-justfied result:
Code:

result = make16(msb, lsb);
result &= 0x1FFE; // Mask off the top 3 bits and the LSB.
result >>= 1;     // Shift it right by 1 bit.


3. Your SPI mode is incorrect. You're using SPI mode 1, and you
you should be using SPI mode 0. Here's how to do it:

Put these #define statements above main().
Code:

#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010


Then in main(), do the setup_spi() statement like this:
Code:
setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_16);
Guest








PostPosted: Mon Nov 13, 2006 2:24 am     Reply with quote

Thanks PCM programmer!! you've solved all my problems! After integrating with my ADS7816 (works!), with an input of 0V i now get 0026~0028 and with a 5V input i get 0fff (in hyperterminal). Thanks again!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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