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
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
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
> 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?
Tom
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?
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.
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; }
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
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
> 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