Displaying ADC readout through SCI

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Displaying ADC readout through SCI

ソリューションへジャンプ
6,224件の閲覧回数
berb_15
Contributor I

Hello all.  I'm trying to read an analog input ranging from 0 to 2.5 volts, convert it to a digital signal, and read the bits outputted through hyperterminal (for now...).  I will eventually be using a gui to take these bits and make sense of them but just want to get a solid reading first.  I am getting a reading but it is a bunch of letters and symbols on hyperterminal and I'm not sure why.  When I remove my input I get a bunch of "]"'s, so I know it's reading something from the ADC when it's hooked up.  Below is my code and a picture of my output.  Any ideas would be appreciated.  Please let me know if anything should be changed or is unessesary as I'm new to microcontrollers, Thanks!

 

My hardware/Software:

 

* DEMOQE128 board

* MC9S08QE128

* Code Warrior

 

My code:

 

int PyrRding;

void main(void) {

 
/*******Set up SCI Registers********/
SCI1C1=0x40;
SCI1C2=0x08;
/***********************************/


PTCDD_PTCDD5=1;
PTCD_PTCD5=1;
SCI1BDL=0x1A;//baud rate=9600bps and bus freq=4MHz.


 /**********Pyranometer ADC**********/
ADCSC1_ADCO = 1;        // enable continuous conversion
ADCCFG_MODE = 0x00;     // 8 bit mode
PTADD = 0x00;           // initialize as input
/************************************/


/****************First ADC to SCI*************/
for(;;){

ADCSC1_ADCH = 0x00;           // set channel PTA0
ADCSC1 = 0;                   // Commence new conversion Ch0

while (ADCSC1_COCO == 0){}    // Wait until conversion complete
PyrRding = ADCRL;             // output 8bit ADC to PyrRding variable

   
while (SCI1S1_TDRE == 0){};   // Wait for the transmitter to be empty
SCI1D = PyrRding;             // Stores new data to be transmitted via serial port
SCI1S1_TDRE = 0;              // Clear flag to send

__RESET_WATCHDOG();

 }
/**********************************************/

}

 

My output:

 

 

 

Hyperterminal reading

ラベル(1)
0 件の賞賛
返信
1 解決策
3,693件の閲覧回数
bigmac
Specialist III

Hello,

 

Sorry about the misleading information.  Rich T is absolutely correct on both counts.  The following revised code should compile.

 

byte buffer[4], *p;

 

...

 

ADCSC1 = 0;                    // Commence new conversion Ch0
while (ADCSC1_COCO == 0){}     // Wait until conversion complete
conv_ASCII( ADCRL, buffer);

 

p = buffer;

while (*p) {                   // Check for null character

   while (SCI1S1_TDRE == 0){}; // Wait for transmit buffer empty
   SCI1D = *
p++;               // Write character to SCI

}

while (SCI1S1_TDRE == 0){};    // Wait for transmit buffer empty
SCI1D = ' ';                   // Separator space 


Regards,

Mac

元の投稿で解決策を見る

0 件の賞賛
返信
14 返答(返信)
3,693件の閲覧回数
RichTestardi
Senior Contributor II

Hi,

 

Here's a simple idea if you are looking for alternatives...

 

> I'm trying to read an analog input ranging from 0 to 2.5 volts,

> convert it to a digital signal, and read the bits outputted through

> hyperterminal (for now...).

 

You can just load StickOS onto the QE and then log into it with Hyper Terminal (9600/8/n) and write a program like:

 

  10 dim a as pin pta0 for analog input
  20 while 1 do
  30   print a
  40   sleep 500 ms
  50 endwhile

 

And then save and run it, and the number of millivolts on pin pta0 will be printed to the Hyper Terminal twice a second.  You can then set the program to autorun and it will do that whenever the MCU is powered up.

 

When I run it, I see my pot (on the DEMOQE board), like:

 

> run
2133
2132
2135
2133

<Ctrl-C>
STOP at line 40!
>

 

Press <Ctrl-C> to stop the program (to edit it, debug it, etc.).

 

If you want downloads of StickOS, for the 51QE128 or 9S08QE128, they are at:

 

  http://www.cpustick.com/downloads.htm

 

You can find full documentation there, as well.

 

-- Rich

0 件の賞賛
返信
3,693件の閲覧回数
berb_15
Contributor I
Thanks Rich I actually just learned about StickOS today.  I think I'm going to skip for this project but I'm definitely going to look into using StickOS in the future and see what it's all about...
0 件の賞賛
返信
3,693件の閲覧回数
PeterHouse
Contributor I

You are sending a raw byte value to a device which is expecting an ASCII value.

The byte valuereturned from the ADC varies between 0 and 255 decimal or 0 to FF in Hexadecimal.  To display the numeral "0" to "9" on hyperterminal you must send the hexadecimal values 30 to 39.

There are lots of ASCII tables on the internet if just google the acronym ASCII or just go to www.asciitable.com

You will probably need to write a conversion routine or use one of the stream formating functions like sprintf to format your data before sending it to the serial port to Hyperterminal.

Good Luck,

Peter House

0 件の賞賛
返信
3,693件の閲覧回数
berb_15
Contributor I
Thanks Peter House that makes perfect sense.  I'm going to do a little research on converting the data and the sprintf function but if you have any aditional suggestions or examples I'm all ears!!  Thanks again.
0 件の賞賛
返信
3,693件の閲覧回数
bigmac
Specialist III

Hello,

 

The use of sprintf() to do what you require is somewhat over-kill.  Here is a much more compact function to do the binary to ASCII conversion.  It uses inline assembly code for fast operation. The numeric ASCII characters are written to the buffer, and null termination also occurs.

 

void conv_ASCII( byte val, byte *buf)
{
   __asm {
      LDA   val
      CLRH
      LDX   #10      // Divisor
      DIV
      PSHH           // LS digit
      CLRH
      DIV
      PSHH           // 2nd digit
      LDHX  buf
      ADD   #'0'     // Convert to ASCII digit
      STA   ,X       // MS digit
      PULA
      ADD   #'0'     // Convert to ASCII digit
      STA   1,X
      PULA
      ADD   #'0'     // Convert to ASCII digit
      STA   2,X      // LS digit
      CLR   3,X      // Null termination
   }
}

 

The function might be used in the following manner -

 

byte buffer[4];

 

...

 

ADCSC1 = 0;                    // Commence new conversion Ch0
while (ADCSC1_COCO == 0){}     // Wait until conversion complete
conv_ASCII( ADCRL, buffer);

 

while (*buffer) {              // Check for null character

   while (SCI1S1_TDRE == 0){}; // Wait for transmit buffer empty
   SCID = *buffer++;           // Write character to SCI

}

while (SCI1S1_TDRE == 0){};    // Wait for transmit buffer empty
SCID = ' ';                    // Separator space 

 

Regards,

Mac

 

0 件の賞賛
返信
3,693件の閲覧回数
berb_15
Contributor I
Thanks Mac, I've heard the sprintf() function uses a lot of memory and like you said my program isn't that intricate...  It looks like the code you posted is exactly what I need.  I'm assuming I can run that assembly code right in with my standard c++ code?  I'm going to try to implement this after my classses today and let you know how it goes!  Thanks again.
0 件の賞賛
返信
3,693件の閲覧回数
bigmac
Specialist III

Hello,


berb_15 wrote:
... I'm assuming I can run that assembly code right in with my standard c++ code?

The code is actually a C function - for the moment I suggest that you stick with C code, rather than C++, for your program.

 

Regards,

Mac

0 件の賞賛
返信
3,693件の閲覧回数
berb_15
Contributor I
Mac, I tried to implement your code but I'm throwing an error. I think it's probably something small or dumb but unfortunately I'm not fluent in coding...

SCID = *buffer++; // Write character to SCI

At this line it says: Wrong type or not an lvalue

I used byte buffer[4]; at the beginning of my code to declare it but somethings still not right... Should the array be a different size??

Thanks in advance.
0 件の賞賛
返信
3,693件の閲覧回数
RichTestardi
Senior Contributor II

You might try "SCI1D", assuming you are using UART 1.

 

Or did you forget the ";" on the preceding line, or forget to include "MC9S08QE128.h"?

 

If you get really stuck, you can usually right-click on a .c file and select "Preprocess" to see exactly what the compiler is complaining about.

 

-- Rich

 

0 件の賞賛
返信
3,692件の閲覧回数
berb_15
Contributor I
I'm sorry I did actually use SCI1D I just copied Macs code above for my post.  I'll play around with it and see if I can come up with anything.
0 件の賞賛
返信
3,692件の閲覧回数
RichTestardi
Senior Contributor II

Oh, and *I'm* sorry -- I read your code too fast...

 

You can't do a "++" on a variable declared like:

 

byte buffer[4];

 

Change that to a "byte *buffer;" and make sure it points to allocated memory.

 

 

0 件の賞賛
返信
3,694件の閲覧回数
bigmac
Specialist III

Hello,

 

Sorry about the misleading information.  Rich T is absolutely correct on both counts.  The following revised code should compile.

 

byte buffer[4], *p;

 

...

 

ADCSC1 = 0;                    // Commence new conversion Ch0
while (ADCSC1_COCO == 0){}     // Wait until conversion complete
conv_ASCII( ADCRL, buffer);

 

p = buffer;

while (*p) {                   // Check for null character

   while (SCI1S1_TDRE == 0){}; // Wait for transmit buffer empty
   SCI1D = *
p++;               // Write character to SCI

}

while (SCI1S1_TDRE == 0){};    // Wait for transmit buffer empty
SCI1D = ' ';                   // Separator space 


Regards,

Mac

0 件の賞賛
返信
3,693件の閲覧回数
berb_15
Contributor I
Ahh ok that works for me now.  Thanks a lot for the help!!
0 件の賞賛
返信
3,693件の閲覧回数
pinkiler
Contributor I

Hi

 

berb_15 or you can send me your working code of the program. On my mail:smileysad:tomazvalic20@gmail.com).

 

Thanke you very much!

0 件の賞賛
返信