Send int or double as ascii through uart

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

Send int or double as ascii through uart

3,847件の閲覧回数
blakehodder
Contributor III

I am not using example code, and I need to send the ADC value through a uart, also as ascii printable. What is the best way to accopmlish this.

 

I know that if I was using example code I could use pirntf or sprintf but I do not have those in place.

 

Thanks,

 

Blake

ラベル(1)
タグ(3)
0 件の賞賛
返信
11 返答(返信)

1,740件の閲覧回数
JimDon
Senior Contributor III

Why do you have to be using example code to use sprintf?

0 件の賞賛
返信

1,740件の閲覧回数
blakehodder
Contributor III

Hi Jim,

Sorry I do not have sprintf included in my code and would rather not use the resources  Is there an easy way to accomplish this otherwise.

Blake

0 件の賞賛
返信

1,740件の閲覧回数
JimDon
Senior Contributor III

Depends on what you consider easy. I don't recall that ltoa is in the CW libs.

Try this (for long):

http://www8.cs.umu.se/~isak/snippets/ltoa.c

0 件の賞賛
返信

1,740件の閲覧回数
blakehodder
Contributor III

Hi Jim,

It turns out it was one of my variables I was setting caused my program to crash.

I do not know if this is the right spot to ask this question,however; I need to now how many times a second I am sampling an accelerometer which is connected to the ADC and send this also with the ADC value. Would I use the RTC for this or the counter/timer module.

Blake

0 件の賞賛
返信

1,740件の閲覧回数
TomE
Specialist II

> I need to now how many times a second I am sampling an accelerometer

It seems to me you don't know how often you're sampling it. I guess you are probably reading it in a simple loop, with or without a delay.. Yes, you were dumping data into a UART without even waiting for it to finish sending:

https://community.freescale.com/thread/304594

Rather than writing code with uncontrolled timing and then trying to measure it, you're way better off writing code with controlled timing. The simplest way is to start a timer (doesn't matter which one) that runs at 100Hz, or 1kHz, or whatever is a suitable "execution heartbeat" for your application. Then have your main loop wait for your timer to trigger, and then  run through whatever your program does (like sampling the ADC) *ONCE*. Then you know it runs 100 or 1000 or 10,000 times per second. You can even have the timer interrupt run (or start) ALL of your code with the mainline in a "STOP" instruction. That reduces power consumption (if that matters). Or use the timer interrupt to kick the mainline out of the "STOP" and then run the application code once, and then back to the "STOP".

> I need to now how many times

The simpler answer is to use an Operating System. It should come with 95% of the stuff you're otherwise going to have to write from scratch. And given your example code above, that could take a while.

Use it to schedule your tasks, send your data and to measure time for you. Can you use MQX on your project? How about uTasker?

http://www.utasker.com/

Tom

0 件の賞賛
返信

1,740件の閲覧回数
JimDon
Senior Contributor III

I don't know all the details of yous project, but be advised that if you did not want to use the "resources" for sprintf, you may not care for an RTOS either. RTOS offer a great number of useful features but the are very costly in terms of resources, both time and memory.

The suggestion that you use a tick is pretty much the way to go, if you do not have the bandwidth for an RTOS.

Which mcu are you using?

0 件の賞賛
返信

1,739件の閲覧回数
blakehodder
Contributor III

Hi Jim,

I am using the MCF52255. I am using it to sample the ADC which is connected to accelerometers and need to sample them as fast as possible, preferably above 2000 samples/second.

Theoretically this chip can do 1.6 million samples/second.

0 件の賞賛
返信

1,740件の閲覧回数
JimDon
Senior Contributor III

This uses loop mode, which means the converters are always running and you can just read them at any time.

It uses all 8 channels.

#define ADC_80MHZ_CLK          3  // /8  40/8
#define ADC_CLK ADC_80MHZ_CLK

int  ADCLoopModeReadChannel(uint8 ch);
// Put this in the header file so it is inlined.
inline int ADCLoopModeReadChannel(uint8 ch)
{
     return (int) (MCF_ADC_ADRSLT(ch)>>3);
}


void ADCLoopInit()
{
    
     MCF_ADC_POWER &= ~(MCF_ADC_POWER_PD0|MCF_ADC_POWER_PD1|MCF_ADC_POWER_PD2);

     while (MCF_ADC_POWER & (MCF_ADC_POWER_PSTS0|MCF_ADC_POWER_PSTS1|MCF_ADC_POWER_PSTS2)) 
     ; // Wait for converters to power up.
    

     /* set pin function to ADC for all channels */
     MCF_GPIO_PANPAR = ALL_PINS_ADC;
     /* Set loop mode */
     MCF_ADC_CTRL1   = MCF_ADC_CTRL1_SMODE(3);     /* SMODE: This field controls the scan mode of the ADC module.                                                 For Loop parallel mode it has to be set 011 bin (3).  */
     // For an 80Mhz clock, this will give a 5MHz ADC clock see 30-7 to adjust.
      MCF_ADC_CTRL2   = MCF_ADC_CTRL2_DIV(ADC_CLK+2); //2*DIV+1.
      MCF_ADC_CTRL2   |=  MCF_ADC_CTRL2_SIMULT;

     /* set the ADC  conversion order */
    MCF_ADC_ADLST1     = (MCF_ADC_ADLST1_SAMPLE0(0) |
                           MCF_ADC_ADLST1_SAMPLE1(1) |
                           MCF_ADC_ADLST1_SAMPLE2(2) |
                           MCF_ADC_ADLST1_SAMPLE3(3));

    MCF_ADC_ADLST2     = (MCF_ADC_ADLST2_SAMPLE4(4) |
                           MCF_ADC_ADLST2_SAMPLE5(5) |
                           MCF_ADC_ADLST2_SAMPLE6(6) |
                           MCF_ADC_ADLST2_SAMPLE7(7));

     /* enable all channels */
    MCF_ADC_ADSDIS  = ALL_CHANNELS;


    
    /* set the power-up delay in ADC */
     MCF_ADC_POWER   = DEFAULT_PDELAY;
     /* wait until module is powered-up */
    while (MCF_ADC_POWER & (MCF_ADC_POWER_PSTS0|MCF_ADC_POWER_PSTS1|MCF_ADC_POWER_PSTS2))           
         ;                     
    // Start it up...
    MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_START0;          /* CTRL1: is used to configure and control the ADC module.
                                                               START0: A scan is started by writing a 1 to this bit.*/
    return;
}


0 件の賞賛
返信

1,740件の閲覧回数
TomE
Specialist II

I don't think Freescale make any Coldfire CPUs small enough that the "not enough memory" reason still holds.

The following claims MQX Lite runs on Kinetis L-Series CPUs in 4k of RAM.

http://www.freescale.com/webapp/sps/site/overview.jsp?code=MQXLITERTOS

I've read somewhere else (can't find it now) how little ROM it can take up too.

An "Operating System" doesn't have to be Windows CE, Linux or Android. It can just be a well written scheduling system with device drivers and some useful libraries.

Tom

0 件の賞賛
返信

1,740件の閲覧回数
blakehodder
Contributor III

Hi Jim,

I tried using that snippit with my code but I get the following:

identifier 'ltoa(long, char, int)' redeclared as '__regabi char * (long, char *, int)'

So I also tried this next piece, but it seems to crash my program after using it:

short int xtt  = temp_val;

    short int count = 0;

char te[4];

    te[0]=(xtt/10000)+48;

    xtt%=10000;

    te[1]=(xtt/1000)+48;

    xtt%=1000;

    te[2]=(xtt/100)+48;

    xtt%=100;

    te[3]=(xtt/10)+48;

    te[4]=(xtt%10)+48;

any thoughts?

Thanks,

Blake

0 件の賞賛
返信

1,740件の閲覧回数
TomE
Specialist II

> any thoughts?

That's a really obvious bug. I spotted it instantly. So does gcc version 4.3.3.

I could point it out (I did, and then edited this post to remove it) as doing so will prevent you from finding it yourself.

It has nothing specifically to do with Coldfire. It belongs in a "C programmer" forum.

> any thoughts?

You have a bug. Debug it. That's part of the job.

You should be able to single-step through your program and see where it goes wrong.

Tom

0 件の賞賛
返信