printf() with the FRDM-KL25Z Board and without Processor Expert


In this tutorial I explored how to use printf(), and this tutorial is so generic that it works for any processor/microcontroller. That flexibility is because I’m using Processor Expert. In case Processor Expert shall not be used, then some tweaks are needed. Here I show what is needed to have printf() working with the FRDM-KL25Z board. I use the UART0 connected to OpenSDA USB CDC for this.

Creating the Project

I create a new bareboard project. Nothing special here, except that ‘UART’ should be selected:

UART set for new project settings

UART set for new project settings

Low Level UART Support

As explained in this tutorial I, I need low-level UART support. CodeWarrior comes with the needed files for the TWR-KL25Z in “\MCU\ARM_GCC_Support\UART\TWR-KL25Z128″:

Low Level UART support files

Low Level UART support files

I copy these files into my project:

Copied Low Level UART Support Files

Copied Low Level UART Support Files

The TWR-KL25Z is using UART0 with PTA14/PTA15, while the FRDM-KL25Z is using UART0, but PTA1/PTA2. So I need to change the pin settings.

For this I disable in ConsoleIO.c, in ConsoleIO_Init() the settings for the Tower board, and add my change to use PTA1/PTA2:

void ConsoleIO_Init()
{
	InitClock();

	/* SIM_SCGC4: UART0=1 */
	SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
#if 0 /* TWR version: PTA14, PTA15 */
	/* PORTA_PCR15: ISF=0,MUX=3 */
	PORTA_PCR15 = (uint32_t)((PORTA_PCR15 & (uint32_t)~(uint32_t)(
				 PORT_PCR_ISF_MASK |
				 PORT_PCR_MUX(0x04)
				)) | (uint32_t)(
				 PORT_PCR_MUX(0x03)
				));
	/* PORTA_PCR14: ISF=0,MUX=3 */
	PORTA_PCR14 = (uint32_t)((PORTA_PCR14 & (uint32_t)~(uint32_t)(
				 PORT_PCR_ISF_MASK |
				 PORT_PCR_MUX(0x04)
				)) | (uint32_t)(
				 PORT_PCR_MUX(0x03)
				));
#else /* FRDM-KL25Z: PTA1/PTA2 */
	  /* PORTA_PCR1: ISF=0,MUX=2 */
	  PORTA_PCR1 = (uint32_t)((PORTA_PCR1 & (uint32_t)~0x01000500UL) | (uint32_t)0x0200UL);
	  /* PORTA_PCR2: ISF=0,MUX=2 */
	  PORTA_PCR2 = (uint32_t)((PORTA_PCR2 & (uint32_t)~0x01000500UL) | (uint32_t)0x0200UL);
#endif
	UART0_PDD_EnableTransmitter(UART0_BASE_PTR, PDD_DISABLE); /* Disable transmitter. */
	UART0_PDD_EnableReceiver(UART0_BASE_PTR, PDD_DISABLE); /* Disable receiver. */
	/* UART0_C1: LOOPS=0,DOZEEN=0,RSRC=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */
	UART0_C1 = 0x00U;                    /*  Set the C1 register */
	/* UART0_C3: R8T9=0,R9T8=0,TXDIR=0,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */
	UART0_C3 = 0x00U;                    /*  Set the C3 register */
	/* UART0_S2: LBKDIF=0,RXEDGIF=0,MSBF=0,RXINV=0,RWUID=0,BRK13=0,LBKDE=0,RAF=0 */
	UART0_S2 = 0x00U;                    /*  Set the S2 register */
	UART0_PDD_SetClockSource(UART0_BASE_PTR, UART0_PDD_PLL_FLL_CLOCK);
	UART0_PDD_SetBaudRate(UART0_BASE_PTR, 313U); /* Set the baud rate register. */
	UART0_PDD_SetOversamplingRatio(UART0_BASE_PTR, 3U);
	UART0_PDD_EnableSamplingOnBothEdges(UART0_BASE_PTR, PDD_ENABLE);
	UART0_PDD_EnableTransmitter(UART0_BASE_PTR, PDD_ENABLE); /* Enable transmitter */
	UART0_PDD_EnableReceiver(UART0_BASE_PTR, PDD_ENABLE); /* Enable receiver */
}

:idea: To use different UART/port settings, the easiest way is to use a Processor Expert project as explained in this tutorial.

Example Code

For testing, I print a ‘hello world’ from the main() in main.c:

/*
 * main implementation: use this 'C' sample to create your own application
 *
 */

#include "derivative.h" /* include peripheral declarations */
#include
#include "ConsoleIO.h"

int main(void)
{
	int counter = 0;

	ConsoleIO_Init();
	for(;;) {
	   	counter++;
	   	printf("Hello world!\r\n");
	}
	return 0;
}

:!: Do not forget to include the correct header files, and to call ConsoleIO_Init()!

That’s it! Build, download and hopefully you see the messages printed to the console :-).

Floating point or not

Whenever possible, I avoid using floating point values in my projects: using floating point is adding a lot of code overhead I can avoid if I use integral or fixed point values. But if I want to use floating point in the ANSI library with printf() or scanf(), then I need to use the proper libraries. If I use

    printf("float value: %f\r\n", 3.75f);

And I get

float value: %f

then this means that I’m not using the correct library.

The ‘FP’ for (Floating Point) suffix in the library name for ARM gcc enable floating point support:

Floating Point Library Option

Floating Point Library Option

With this, I get the correct output:

float value: 3.750000

Project on GitHub

For reference, I have committed the CodeWarrior project and sources on GitHub here.

Happy Printing :-)

About these ads

10 thoughts on “printf() with the FRDM-KL25Z Board and without Processor Expert

  1. Pingback: Why I don’t like printf() | MCU on Eclipse

  2. Awesome tutorial, although it seems a little outdated compared to what you currently have on your github repository (for the example project FRDM-KL25Z_printf). In that example, you seem to have the intent of flashing the red LED while it waits for stream input. That LOOKS like the intent. What actually happens is my KL25Z waits at gets(), waiting for stdin input. I basically have to send a bunch of “things” into the terminal before the counter finally gets high enough to toggle the red LED. How can I fix this so it doesn’t actually wait/hang at gets() (or something similar like scanf() or getchar() )? I would expect it to look, see if anything is coming in, and if it isn’t it goes on with the rest of the code. That’s not the case in this example.

    • Hi Robert,
      thanks for your feedback!
      Yes, I had changed that demo project so it uses gets(). I have updated the project on GitHub now so it does the original thing, plus as a #define to enable the gets() part.
      As for your problem, I think the issue is with your terminal program, maybe? Does it send \r\n (linefeed) at the end? If not, then this might cause a problem as gets() waits until there is a new line.
      See http://en.cppreference.com/w/c/io/gets
      I hope this helpsl

      • When I hit return on my terminal (I’m using PuTTY) the characters are successfully sent to the KL25Z. My question is how to go about setting up some sort of interrupt for serial communication, such that the MCU does its business in an infinite loop but either has an interrupt for the terminal, or an if-statement it evaluates on every run-through of the loop. I don’t want it to hang, WAITING for user input. I checked out kbhit(), but it seems CodeWarrior doesn’t have conio.h and even if it did, it doesn’t make sense that the KL25Z would know what to do with it (the keyboard is connected to the COMPUTER, not the KL25Z). Does that make sense?

        Thanks,
        Robert

      • Hi Robert,
        I’m using the Asynchroserial component with Processor Expert. And this one is interrupt driven and features a FIFO buffer.
        So I do not need to wait for input: things come in by interrupt. And I can check the FIFO periodically (if something arrived), or getting events for every single character coming in.
        So what you describe is what I’m doing. But I’m not using the standard libraries as they are too much limited for this use case and for me. I’m using Processor Expert to generate that driver code for me.

        I hope this helps?

  3. Hello Erich,
    I tried to print a float number, but it would not work do yo have an idea why??

    Example:
    float var = 3.56;
    printf(“%f”,var);

    Result:

    %f

    Best regards…

  4. I´m using PE with GCC and Eclipse. Do you have or can point any place where I can find information on how to create or download the NewLib stubs c file ? I´m using your FSShell with CDC components. Thanks a lot.

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s