Tutorial: printf() and “Hello World!” with the Freedom KL25Z Board

Sometimes I show to much in a tutorial: only writing something to the UART? Sounds boring, so why not adding tasks, LEDs and a full shell implementation to the mix as in this post? Yes, definitely too much to start with at the beginning :-(. So less is more, and if it is just about the UART. And I promise: it is doable with around 50 lines of application code :shock:.

AND: I admit, this post title is a trap ;-). It is not about printf(). But it *is* about using the UART on the KL25Z Freedom board and to do things like printf(), and even more. Trust me. It is about how to write *and* read from the UART. While I’m using here the Kinetis-L ARM Cortex-M0+ KL25Z Freedom board, it is applicable to any other Kinetis device.

Goal

What I’m going to implement here, is how to use an UART to send/receive characters.To have things a little challenging: using interrupts and buffering :-).

Without Processor Expert?

I’m going to use (again) Processor Expert with gcc and CodeWarrior for MCU10.3. But if you do not like it, then download the project here and remove Processor Expert. Done, and you have a normal C/C++ project.

Why not printf()?

In my opinion, using printf() (or sprintf() and all the other variants) in an embedded project is a bad thing. printf() can easily can add 10-15 KByte to the code size alone. My goal is to have an application which reads and writes to the UART with less than 5 KByte *total* code size. Using it for something like

printf("Hello world!\n");

is just a wast of resources. If I want to use the standard library, then using it like

puts("Hello world!\n");

is a better alternative. In the example below I’m using my version of puts().

And: printf() can result in a severe problem: buffer overflow.

Creating the project

Creating the project is simple (I hope): Use the menu File > New > Bareboard and create a Processor Expert project. If not: this tutorial goes through the project creation steps.

Adding the Processor Expert Components

In this tutorial I need two components: Serial_LDD which is part of CodeWarrior and RingBufferUint8 which is available here. If you do not have loaded the RingBufferUint8, this tutorial shows how to load additional components.

Project with Components

Project with Components

After adding the RingBufferUInt8 component, I have renamed it to ‘RxBuf’.

💡 In order to be able to rename the component (change the component name), the Inspector needs to be in ‘Expert’ mode. See this post about how to switch to the Processor Expert ‘Expert’ mode.

UART Configuration

As the FRDM-KL25Z board does not have a physical UART connector, I’m going to use the P&E OpenSDA virtual USB CDC port on UART0. This means my target device will use an UART which is connected to the OpenSDA debugging device, which implements an USB CDC (Communication Device Class) on the host, enumerating as virtual COM port.

I configure the Serial_LDD for UART0, with Interrupts enabled, 38400 baud and using the TPM2_CH0 and TPM2_CH1 pins:

UART Configuration

UART Configuration

RingBuffer Configuration

I need a buffer for my incoming characters, so I’m using a circular ring buffer. All what I need here is the size of the buffer:

RingBuffer Configuration

RingBuffer Configuration

Generating Code

That’s it from the configuration side: time to generate the driver code: I select the project/.pe file and use the button to generate the code:

Generating Code

Generating Code

Adding Application Code

I’m adding my application files (Application.h and Application.c) with File > New Source File and Header File to the project:

Application Files added

Application Files added

Application.h Header File

In Application.h I define the following interface:

#ifndef APPLICATION_H_
#define APPLICATION_H_

#include "PE_Types.h"
#include "PE_LDD.h"

typedef struct {
  LDD_TDeviceData *handle; /* LDD device handle */
  volatile uint8_t isSent; /* this will be set to 1 once the block has been sent */
  uint8_t rxChar; /* single character buffer for receiving chars */
  uint8_t (*rxPutFct)(uint8_t); /* callback to put received character into buffer */
} UART_Desc;

void APP_Run(void);

#endif /* APPLICATION_H_ */

APP_Run() is my application main routine (called later from main()). With UART_Desc I declare a structure which I will use for accessing the UART. It has a device handle, a flag which is reset in the send interrupt routine, a single character buffer for receiving characters and a callback function pointer which stores the incoming characters into the ring buffer.

Application.c Implementation File

The Application.c file looks like this:

#include "Application.h"
#include "RxBuf.h"
#include "AS1.h"

static UART_Desc deviceData;

static void SendChar(unsigned char ch, UART_Desc *desc) {
  desc->isSent = FALSE;  /* this will be set to 1 once the block has been sent */
  while(AS1_SendBlock(desc->handle, (LDD_TData*)&ch, 1)!=ERR_OK) {} /* Send char */
  while(!desc->isSent) {} /* wait until we get the green flag from the TX interrupt */
}

static void SendString(const unsigned char *str,  UART_Desc *desc) {
  while(*str!='\0') {
    SendChar(*str++, desc);
  }
}

static void Init(void) {
  /* initialize struct fields */
  deviceData.handle = AS1_Init(&deviceData);
  deviceData.isSent = FALSE;
  deviceData.rxChar = '\0';
  deviceData.rxPutFct = RxBuf_Put;
  /* set up to receive RX into input buffer */
  RxBuf_Init(); /* initialize RX buffer */
  /* Set up ReceiveBlock() with a single byte buffer. We will be called in OnBlockReceived() event. */
  while(AS1_ReceiveBlock(deviceData.handle, (LDD_TData *)&deviceData.rxChar, sizeof(deviceData.rxChar))!=ERR_OK) {} /* initial kick off for receiving data */
}

void APP_Run(void) {
  Init();
  SendString((unsigned char*)"Hello World\r\n", &deviceData);
  for(;;) {
    if (RxBuf_NofElements()!=0) {
      SendString((unsigned char*)"echo: ", &deviceData);
      while (RxBuf_NofElements()!=0) {
        unsigned char ch;

        (void)RxBuf_Get(&ch);
        SendChar(ch, &deviceData);
      }
      SendString((unsigned char*)"\r\n", &deviceData);
    }
  }
}

There are routines to send a character (SendChar()) and a string (SendString()). In the Init() routine the device structure gets initialized, along with the ring buffer.

APP_Run() first calls the initialization, then puts a hello world message to the UART and then goes into an endless loop. In this loop it checks if there are any incoming characters. If so, then it echoes them to the UART.

UART Interrupt Event Code

As I am are using interrupts, I need to fill out the event functions (OnBlockReceived() and OnBlockSent()) in Events.c:

UART Event Code

UART Event Code

As I’m using the UART descriptor, I need to include the header file with its declaration at the beginning of Events.c:

/* User includes (#include below this line is not maintained by Processor Expert) */
#include "Application.h"

In the receiver interrupt callback routine I store the received character into my ring buffer and prepare for receiving the next character:

void AS1_OnBlockReceived(LDD_TUserData *UserDataPtr)
{
  UART_Desc *ptr = (UART_Desc*)UserDataPtr;

  (void)ptr->rxPutFct(ptr->rxChar); /* but received character into buffer */
  (void)AS1_ReceiveBlock(ptr->handle, (LDD_TData *)&ptr->rxChar, sizeof(ptr->rxChar));
}

In the sender interrupt callback routine I reset my flag to indicate that the block has been sent successfully:

void AS1_OnBlockSent(LDD_TUserData *UserDataPtr)
{
  UART_Desc *ptr = (UART_Desc*)UserDataPtr;

  ptr->isSent = TRUE; /* set flag so sender knows we have finished */
}

Integrating Application Files

Last step is to call my routine from the main file (ProcessorExpert.c). For this I include my application header file and call the application:

/** ###################################################################
**     Filename    : ProcessorExpert.c
**     Project     : ProcessorExpert
**     Processor   : MKL25Z128VLK4
**     Version     : Driver 01.01
**     Compiler    : GNU C Compiler
**     Date/Time   : 2012-07-17, 22:22, # CodeGen: 0
**     Abstract    :
**         Main module.
**         This module contains user's application code.
**     Settings    :
**     Contents    :
**         No public methods
**
** ###################################################################*/
/* MODULE ProcessorExpert */

/* Including needed modules to compile this module/procedure */
#include "Cpu.h"
#include "Events.h"
#include "AS1.h"
#include "RxBuf.h"
/* Including shared modules, which are used for whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"

/* User includes (#include below this line is not maintained by Processor Expert) */
#include "Application.h"

int main(void)
{
  /* Write your local variable definition here */

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  PE_low_level_init();
  /*** End of Processor Expert internal initialization.                    ***/

  APP_Run();

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;){}
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
  return 0;
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

/* END ProcessorExpert */
/*
** ###################################################################
**
**     This file was created by Processor Expert 5.4 [05.02]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/

Running the Application

Time to compile/build the application. Running it on the board prints a ‘hello world’, and the sends back the incoming strings and characters:

Hello World from the Freedom Board

Hello World from the Freedom Board

Summary and Sources

Using the UART is not that difficult: With the drivers and around 50 lines of source code things are not that difficult. The above application compiled with gcc and -Os (optimize for size) is only around 4 KByte of code:

'Invoking: ARM Ltd Windows GNU Print Size'
"C:/Freescale/CW MCU v10.3/Cross_Tools/arm-none-eabi-gcc-4_6_2/bin/arm-none-eabi-size"  --format=berkeley Freedom_HelloWorld.elf
  text       data        bss        dec        hex    filename
  4176         40       1172       5388       150c    Freedom_HelloWorld.elf

The project with the sources at the time of writinig this article is available here.

The latest and greates project maintained by me is available on GitHub here.

Happy Printing 🙂

224 thoughts on “Tutorial: printf() and “Hello World!” with the Freedom KL25Z Board

  1. Hello. I find the tutorial helpful, but I’ve got some questions 🙂
    Where do you define that you’re going to use the virtual USB CDC port. Is it because of the specifics of UART0 or does it happen by choosing the TPM pins? At the same time you’re choosing PTA1 and PTA2 pins. What if I wanted to to use PTA1&2 pins with an external device?

    I asked these questions hoping that the answers would clarify things a bit. But what I really want to do is use simultaneously two UART modules. One for MCUPC communication, and one for MCU external Bluetooth module communication. Could I achieve that by using modified code from your tutorial for the first communication and adding a second Serial_LDD component, configuring it for UART1 and using the PTE1 and PTE0 pins?

    Like

    • Hi Filip,
      UART0 with PTA1/PTA2 is connected to the OpenSDA/K20 device. So the OpenSDA/K20 is implementing the USB CDC. For the KL25Z it is like a normal serial/RS-232 connection. If you want to use PTA1/PTA2 for anything else on the Freedom board: you would have to cut these lines to the K20. As for your case: I suggest that you use the UART0 through openSDA to communicate with the PC, while using the other UART for communication with the Bluetooth device. Simply add another Serial_LDD and route it to the UART.
      Hope this helps,
      Erich

      Like

      • Yes this helped, but it still doesn’t seem to work.
        I added another Serial_LDD and another buffer ring. Is this Init_2() function correct for UART1?

        static void Init_2(void) {
        /* initialize struct fields */
        deviceData_2.handle = AS2_Init(&deviceData_2);
        deviceData_2.isSent = FALSE;
        deviceData_2.rxChar = ”;
        deviceData_2.rxPutFct = RNG2_Put;
        /* set up to receive RX into input buffer */
        RNG2_Init(); /* initialize RX buffer */
        /* Set up ReceiveBlock() with a single byte buffer. We will be called in OnBlockReceived() event. */
        while(AS2_ReceiveBlock(deviceData_2.handle, (LDD_TData *)&deviceData_2.rxChar, sizeof(deviceData_2.rxChar))!=ERR_OK) {} /* initial kick off for receiving data */
        }

        Like

  2. hi, i tried to use the program without using the CW, i tested it in debug mode and run and it works just fine, but when i just plug the usb and wait for the communitacion to start it doesnt work. i dont know what i should do to fix it. ill be great if you could help with this.

    Like

    • Hard to tell what the problem is. But maybe it is this one: if you have a terminal program open to that COM port, and unplug/plug the USB cable, then the port might be locked. Try to close the COM port, unplug the board, plug it in and then open the COM port.

      Like

  3. Pingback: Tutorial: Printf() with (and without) Processor Expert | MCU on Eclipse

  4. Will I be able to you use the above settings for a case where I am using a uart pin to directly communicate to a serial port of the pc(providing appropriate voltage level shifters)? If yes , is there anything in addition to be done or to be removed?

    Like

  5. Hi Erich,

    I tryed to run example. But i have this problem:
    RxBuf.h: No such file or directory
    Where is the RxBuf.h? I didnt find in the projects.

    Thank you!

    Like

  6. Hello,

    I’m using your code and i have a problem…
    Output from my board in terminal is: 80 D7 1E 13 A4 C7 11 D3 5E 71 1D in HEX, which is is ASCII somethink like “€×¤ÇÓ^q”. But it should be “Hello World\r\n”.

    I’m using your whole code, so where can be problem? I have my board’s TxD pin connected to RxD pin on Serial-USB converter… Can be problem in him? But he works fine with C# code for serial communication.

    Thx for help, Fbi.

    Like

  7. Outstanding work! In the latest version of CodeWarrior the UART baud fix seems to be implemented. One thing I missed when I first went through this (and made me scratch my head for a few minutes) was that you have to set the Component Name for the RingBufferUInt8 component to “RxBuf” for the correct header files and function prefixes to get generated by PE. Thanks so much.

    Like

    • Hi Victor,
      thanks for that feedback, always appreciated :-). And thanks to your comment about renaming the component: that piece is indeed missed. I have updated the post to reflect this.
      About that UART problem: I don’t think it is fixed. But it only shows up if you have a different bus and core clocks on Kinetis-L. At least in my MCU10.3 it is not fixed for that case.

      Like

  8. Hi Erich,

    i am facing a problem with a component AsynchroSerial. I am using KL05 board. Whatever pin I select in Tx is copied into the Rx pin. I can see this when i change the pin. Look at the name of the pin provided ADC0_SE4/TSI0_IN2/PTB2/IRQ_10/LLWU_P5/UART0_RX/UART0_TX !! How can it be both Tx and Rx? Rx = PTB2 and Tx = PTB1 according to the datasheet. Can anything be done?

    Like

    • sorry correction. Datasheet says both. The issue is that Processor Expert copies my pin into both Rx and Tx not allowing me to use Rx = PTB2 and Tx = PTB1.

      Like

      • I actually went to that link you have given. But I don’t know how to download the project from there. Should I download it file by file? I had actually used the clock settings you had given for the FreeRTOS on the FRDM-KL05Z Board tutorial. I guess that has nothing to do with whatever error I am facing in the PE component inspector window of AsynchroSerial component. I tried restarting PC etc. But even in a new project with just the AsynchroSerial component, the same thing happens. I had used this component in KL25FRDM board which worked perfectly fine.

        Like

      • Hey Erich,

        I just incidentally came across this post. Even I didn’t find any download button or zip button. Please would you explain where I could find the .zip download button in github? Nice blog.

        Like

      • hi Erich,

        I opened the project as per your instruction. Again the same pin assignment on both Rx and Tx is what I saw and am unable to change it. And the asynchroserial component had the red wrong sign indicating error. I saw the same error in another PC with code warrior installed with a project just containing AsynchroSerial component. I would like to know what could be the issue.

        Like

        • I have no clue what this could be? Maybe you could send me your project as a zip file to the email address noted at the end of the ‘About’ page of this blog?

          Like

  9. I followed the instructions you had given but I’m getting the following error in CPU.c file
    “undefined reference to Cpu_OnNMIINT”
    void Cpu_INT_NMIInterrupt(void)
    {
    Cpu_OnNMIINT(); // error
    }

    Like

  10. Hi Erich, Thank you for your tutorials,
    Can you tell me if this tutorial is for communicating with PC only, or we can use it also for communicating with second board ?

    Like

  11. Erich,

    I just noticed that the baud rates that I can achieve within 1.5% with UART0, UART1, and UART2 are differently constrained. Apparently “fastest” is UART0, followed by UART1, and then by UART2. Can you help me to understand why that is? Perhaps it’s a good subject for a broader blog post about the Kinetis architecture.

    Like

    • Hi Victor,
      I have not noticed this. The baud would depend on the possible clocks for the module. Are you saying it is more accurate for one UART, and not the same for another one?

      Like

  12. Erich,

    I just noticed that the baud rates that I can achieve within 1.5% with UART0, UART1, and UART2 are differently constrained. Apparently “fastest” is UART0, followed by UART1, and then by UART2. Can you help me to understand why that is? Perhaps it’s a good subject for a broader blog post about the Kinetis architecture.

    Like

    • Hi Victor,
      I have not noticed this. The baud would depend on the possible clocks for the module. Are you saying it is more accurate for one UART, and not the same for another one?

      Like

  13. Hi Erich,
    I am having a linker problem.
    I have built the project from scratch following your instructions and the linker cannot resolve the App_Run() function from main(). Application.c is being compiled though (there is an Application.o file generated).
    Application.c exists in the Sources directory, and Application/o is being generated in FLASH\Sources.
    Is there a linker flag to include other modules that I have missed?
    Thanks
    Bryon

    Like

    • Hi again Erich,
      A small update to the question. I have looked in the map file and Application.o is being linked but there App_Run() is not “public”.
      I copied the code directly so App_Run() is not a “static” function.
      Thanks

      Like

      • I resolved it. The problem was between the seat and the keyboard…
        It helps if I pay attention and don’t have a typo – I had App-Run() instead of APP_Run().
        It all works fine now.

        Like

  14. Great work Erich !

    Just a note when using 9 bit UART,

    The rxChar member of struct UART_Desc should be uint16_t instead uint8_t to allow one extra byte for passing the 8th bit value

    Thanks for sharing

    Like

  15. Hello Eric,
    another great tutorial 🙂 I installed CW w/ PE and everything works fine. I can establish a connection and via Termite I can write and read via UART.
    Since I have no real experience in “embedded c programming” I have a question to those who have 😉

    My received data is stored in RxBuf and resent via UART by the uC. Is there any possibility to compare the received data internally? I already tried strcmp but it doesn’t seem correct to me. My idea is to analyze the received date on the board and switching the LED eg if “red” is received. Hence the RingBuf is a “byte” type I thought there is a “uC-special” possibility to do if-else structure. Maybe if I compare the byte with the 8b Ascii-Code? o.O

    Maybe there is someone outh who can help me 🙂
    …and again great work 🙂

    Like

    • Hi Dennis,
      there is no direct way (right now) to do a strcmp() or something similar with the data in the ring buffer. But you could get the characters from ring buffer and then do the parsing, that’s very well doable.
      If you want to do do more: I have developed a ‘Shell’ component which parses input from the console (it even allows remote connection through Bluetooth/etc). So you could type in “LED1 on” and it will turn it on, or “LED1 off” and so on. That component basically parses the commands (well, you can provde the parsers).
      I have described an early version of it (FSShell) here: https://mcuoneclipse.com/2012/08/05/a-shell-for-the-freedom-kl25z-board/
      https://mcuoneclipse.com/2012/12/29/pwm-and-shell-for-a-led/

      The new shell is named “Shell”, but has the same capabilities. Let me know if you need pointers to demo programs.

      I hope this helps.

      Like

  16. Hi Erich,
    Thank you for whole your work.
    I wanted to implement your example for UART communication of two MCUs.The goal is to send and receive one char through TWR K60n512.I call Init method and SendChar.During debugging process the error occures.The method AS1_SendBlock returns Error message,to be specific in the line (DeviceDataPrv->OutDataNumReq != 0x00U).The problem is in the first argument of the method AS1_sendBlock(LDD_TDeviceData *DeviceDataPtr) where you set value desc->handle.Can you help me somehow please?If you need some additional informations I can send you 🙂 Thank you

    Like

    • Hi Marek,
      So it is returning an error here:
      if (DeviceDataPrv->OutDataNumReq != 0x00U) { /* Is the previous transmit operation pending? */
      return ERR_BUSY; /* If yes then error */
      }
      It sounds to me that the interrupts are not firing, so the previous data block is not sent. Are you sure you have the interrupts enabled?

      On another note: at the time writing that post, there was only the Serial_LDD available. With MCU10.4 there is now the AsynchroSerial component which does the same thing, but is much easier to use. I suggest to try the Asynchroserial instead of the Serial_LDD.

      You might have a look at my recent tutorial with the Term component too:
      https://mcuoneclipse.com/2013/11/16/tutorial-using-a-terminal-input-and-output-without-printf-and-scanf/
      This component is more for computer-user and not computer-computer communication, but might be helpful too.

      Like

      • Thank you, the problem really arised because my FreeRTOS disabled interrupts during initialization.I tried to use the component AsynchroSerial, and it works properly.:)

        Like

        • Hi Marek,
          ok, that makes sense now. During the initalization of the RTOS the interrupts have to be disabled, otherwise e.g. the tick interrupt could fire. Interrupts are then enabled with starting the scheduler.

          Like

  17. Hi,

    Thanks for your tutorial! However, I wasn’t able to print out anything on my serial terminal, I am using Putty and K60. I followed exactly your tutorial, except for when configuring Serial_LDD where my receiver port was set to PTA15 and Transmitter to PTA14, because I get errors if I try to set them PTA0 & PTA1 unless I enable pin sharing.

    Everything builds fine with no errors, but just one warning: “statement with no effect {-Wunused-value]”, and it was directed to “APP_Run” in ProcessorExpert.c. I am not sure if this matters or not.

    Any help troubleshooting this would be very much appreciated.

    Thanks,
    Dao.

    Like

    • Hello,
      for that warning: have you included Application.h in ProcessorExpert.c? That warning could indicate that nothing gets called.
      Have you debugged your code to see what is going on?
      Your note about the need to reconfigure the pins let me think that you have configured something wrong. It should not be needed to use pin sharing. If this is the case, you probably have a pin conflict.

      Like

      • Thanks for your reply!

        Yes I did include Application.h in ProcessorExpert.c. Turns out I didn’t quite call the function completely: I wrote “APP_Run” instead of “APP_Run()” in ProcessorExpert.c, that was a stupid mistake… =\

        I debugged it and still getting nothing out of my serial terminal. So I looked into the pin conflicts, it turns out the Receiver and Transmitter pin set up for the Serial_LDD were conflicting with the TDI(Test Data In) & TDO(Test Data Out) pins in JTAG Mode.

        What should be my next step?

        Thanks,
        Dao.

        Like

        • Hi Dao,
          if you do not need these pins for your debugging, then you can disable them in the CPU component (component inspector for the CPU) so they can be used by your application.

          Like

  18. Hi,
    I have followed each step and I don’t understand why it is not receiving a string, but single char. for example if I type hello, it will show like:
    h
    echo:h
    e
    echo:e
    l
    echo:l
    l
    echo:l
    o
    echo:0

    Like

    • Hy Yvonne,
      this is caused by the settings of your terminal. It looks it is configured to send characters as you type it. So if you type the ‘h’, it immediately sends it. That’s why you see one character after each other echoed. Most terminals (like the termite I use) have an option to send the text after you press the ENTER key. That way ‘hello’ is transmitted in one piece. Most terminal programs can configure what should happen if you press ENTER (e.g. if CR or CR+LF is sent).
      I hope this helps?

      Like

  19. Hi Erich, great tutorial as always.
    If I were to visualize values of variables using this method, in this case I want to see what values I am getting from the ADC how would I implement it? I have tried changing a few things but I can’t seem to get it yet. Any suggestions?
    Code here: http://www.sendspace.com/file/3nde2x
    Regards,
    Nick.

    Like

      • Hey Erich,
        Thanks for getting back; I store my ADC value to a 16 bit variable with the AD1_GetValue16(&value); after that I put the value in the UART buffer with RxBuf_Put(value) then I run the UART with APP_Run();
        I modifed your APP_Run to this:

        void APP_Run(void) {
        Init();
        while (RxBuf_NofElements()!=0) {
        unsigned char ch;
        (void)RxBuf_Get(&ch);
        SendChar(ch, &deviceData);
        }
        SendString((unsigned char*)”\r\n”, &deviceData);
        }

        So basically my program does:
        – read value from ADC;
        – put value to buffer;
        – show value in terminal with APP_Run;

        All it does is print newlines which points out the the buffer is probably empty so I think that I am not putting the value into the buffer correctly.
        Thanks in advance,
        Nick.

        Like

        • I think you want to use TxBuf_Put() and not RxBuf_Put() as you wrote?
          Anyway, you need to convert the number to a string first. Put() puts a 8bit decimal value, and not a character value.
          So you need to do something like this:
          uint16_t value;
          uint8_t buf[32];
          int i;
          AD1_GetValue16(&value); /* get value */
          UTIL1_Num16uToStr(buf, sizeof(buf), value); /* transform into string */
          i=0;
          while(buf[i]!=’) {
          TxBuf_Put(buf[i]); /* write string */
          }

          I hope this helps.

          Like

  20. Hey Erich,
    Thanks for replying; I’m a bit confused about the last 3 lines of the code you suggested. The while loop is putting each character of the string into the buffer one by one I assume? Shouldn’t i get incremented? Something like this maybe? :

    i=0;
    while(buf[i] != 0){
    TxBuf_Put(buf[i]);
    i++;
    }
    Furthermore, I don’t have the TxBuf_Put() function? Do I need to set up another ring buffer for the transmitter? I thought you can use the same buffer to send and transmit?

    Thanks,
    Nick.

    Like

  21. Hi Erich,
    Do I need to set up TxBuffer as well? If so how do I set it up to transmit data? Or is it enough to add component to project and define the size and just use it. Sorry for these questions as I just started working with embedded system.

    Thanks again,
    Nick.

    Like

  22. Hey Erich,
    According to this tutorial, you set up the buffer size as 64 so it shouldn’t be a problem anyway? I got your project from github and my PE gives me an error with the critical section component (CS1).
    I’m just puzzled why it is not working because my project is pretty much based on this UART tutorial, I only added an ADC component (also based on your other tutorial). The only change I made was to APP_Run, changed it to only write values from the buffer (code in my previous comment). The main() has a few extra line of codes to get the values from the ADC, values are then converted to string then put in the buffer with RxBuf_Put() then recall APP_Run.
    Really appreciate all the help Erich.
    Best regards,
    Nick.

    Like

  23. Hey Erich,
    I am using Codewarrior and Processor Expert, same thing you used as shown in the tutorials. It’s strange that it doesn’t load for you, if you have somewhere I can upload the files directly to you then please tell me so I can do that.

    Best regards,
    Nick.

    Like

        • Hi Nick,
          ok, I have received it, and there were several problems in your application: You should initialize the UART only once, and the Rx buffer is (as the name indicates) only for receiving characters. But you have overwritten that buffer with the characters you want to send to the Tx buffer, that’s why things did not work for you. You should have now the fixed code in your inbox. I hope this helps?

          Like

      • Hey Sir Erich,

        Would it be alright if I take a look at this project? (The one Nick is trying to do). I also need to implement and add a ADC component in my project for another module and it would be very much helpful if I can have a copy of the project and study it.

        I hope it’s alright. Thanks very much.

        Like

      • I’m referring to Nick who was trying to
        – read value from ADC;
        – put value to buffer;
        – show value in terminal with APP_Run;

        He sent you his project through email and you found out what was wrong with it and sent him back the corrected project. I hope you still have a copy of the project.

        Many thanks in advance! 🙂

        Like

  24. Hi Erich,

    I want to send a string via UART from Event.c, I tried it but it don’t send it.
    Could you help me ?

    Like

  25. Hey, I am trying to use two UARTs simultaneously on a K70 board. I have created two UART components in Processor Expert. I am debugging using IAR. I am sending out a set of printfs from the main. How do Initialize, and switch between the UARTs inside the main code?
    thanks.

    Like

  26. HELLO SIR
    I want to addapt the code to reverse a string i enter. I have actually used the code and it worked like magic. i want the one that could reverse the entered strings. thanks

    Like

      • i have used your code for my microprocessor mk20 and beaglebone. I can write some strings of characters from the beaglebone to the mk20 and have it printed back on putty. I want to collect the string of character i wrote to the mk20 in and array, reverse the character and send back the reversed characters and send back the reversed chracter to be printed on the putty.

        Like

        • An easy way to do this is just write a loop, starting from the end of the string and then go through the string one character by character and write that character.

          Like

  27. Hi Eric,

    Thanks for the detailed steps which is very useful for new users like me.
    I performed all the steps mentioned in the tutorial and while debugging it was bit unfortunate that I could not see any output in serial terminal (I am using Teraterm and have set the baud rate to 38400 as defined in project). Also there were no compilation errors or warnings.
    Further debugging I could see that after Init() call of APP_Run() successfully, it then calls Sendstring with ‘str’ correctly holding the ‘Hello world\n’ string but the another argument ‘desc’ doesn’t point to valid address and shows ‘no value available’

    Really not sure if I am missing something.
    Can you please help me in this regard.

    regards,
    Sen

    Like

  28. Hello sir
    I have implemented the code but am trying to save the received characters in an array so that i can use it further, how am i going to do that?

    Like

      • void storeData(){
        int i=0;
        char buff[50];
        if (RxBuf_NofElements()!=0) {
        while (RxBuf_NofElements()!=0) {
        buff[i]=RxBuf_Get(&ch);

        }
        }

        }
        Am new to microcontroller programming

        Like

      • uint8_t buff[64];

        void storeData(){
        int i=0;

        if (RxBuf_NofElements()!=0) {
        SendString((unsigned char*)”stored data is: “, &deviceData);
        while (i!=sizeof(buff))
        {
        unsigned char ch;
        (void)RxBuf_Get(&ch);
        buff[i]= ch;
        i++;

        }
        SendString(buff, &deviceData);
        SendString((unsigned char*)”\r\n”, &deviceData);
        }

        }

        i did it thanks the problem is that
        if i write a characters lesss than 64,
        eg hjlk
        it will write k to fill the array up
        hjlkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
        which is n ot what i want.

        Like

  29. Hi Erich,
    What’s the difference between using polling tx and INT tx. In your code i can see that you’re polling the flag isSent. What would be the code using only the polling mode maintaining Tx interrupt disabled?

    Thanks in advance!

    Like

    • Hi Gorka,
      the difference is if the data is sent within the interrupt service routine, so the interrupt handler does all the heavy lifting. Otherwise if you are in ‘polling’ mode you would send the data outside the ISR.
      Polling the ‘isSent’ flag is still necessary if you want to avoid sending data while the old data is not sent out yet.

      Like

      • Thanks for your quick answer Erich!

        I think i’m not suitably explaining. I’m using FreeRTOs SO on my freedom board and i’m using uart to comunicate with another board. My goal is to use polling mode to send some bytes outside.
        I’ve chosen AsynchroSerial component from PE, and i noticed that i can’t have any tx buffer without selecting (interrupts -> enable), then i can’t use SendBlock method.
        I have implemented it myself but i have had an issue when sending more than one bytes.
        Deeping in the method SendChar i noticed that the code :

        if (ASerialLdd1_SendBlock(ASerialLdd1_DeviceDataPtr, (LDD_TData *)&OutBuffer, 1U) == ERR_BUSY) { /* Send one data byte */
        OutBuffer = TmpChr; /* If is device busy, restore OutBuffer value */
        return ERR_TXFULL;
        }

        is not waiting bloqued until the byte is sent. So, i can’t guarantee that the previous byte is sent.

        Thanks in advance

        Like

        • Hi Gorka,
          sorry, I think I still don’t get your problem 😦
          If you enable interrupts, then it is using an internal ring buffer, but it will send byte by byte depending on the microcontroller used.
          But there are methods to check the number of characters in the input and output buffers. Maybe this is what you need?
          Erich

          Like

  30. Hi erich,

    I am using uart1 for sending the strings onto the terminal.
    => In cpu settings I have set the core clock frequency to 48MHz and bus clock frequency to 24MHz.
    => I have set the uart1 baud rate to 115200 in component settings.

    I have observed that If i set the baud rate of the terminal to 57600, then only I am receiving the exact string onto terminal. otherwise i am getting garbage value.

    cpu settings:
    http://postimg.org/image/4r4wrqffb/
    uart settings:
    http://postimg.org/image/s1orq0qoz/

    Like

    • Hi durgesh088,
      your settings look fine. Have you measured the 115200 baud with a logic analyzer/oscilloscope? Typically communication still works if the baud is in the 1.5% error range. So two possible issues: the KL25Z is not producing the 115200 baud (verify with a scope): this might be because of temperature drift. I have one application running on the KL25Z which uses 115200 baud (most of my other applications use 38400 as this is usually enough), and I have not seen problems.
      If you see garbage on the ohter side, this means either the baud is not correct, or your other side is not able to deal with that high baud rate. Again, you need to check the signals with a scope/analyzer to be sure what is the problem.
      I hope this helps.

      Like

      • Hello Erich,

        Thanks for your reply,
        I have checked the output with logic analyser. I am getting the output on logic analyser if i am setting the channel baud rate to 57600(which is half of the baudrate i have set in component settings).
        I have checked by changing the baud rate in component settings to 19200. Then I am receiving the data if my docklight’s and logic analyser’s baud rate is set to 9600
        I have taken your Freedom_Helloworld project from github and changed the cpu settings(coreclock to 48M and busclock to 24M) and changed the uart configurations I have selected uart1. I am receiving the string at 19200 which is half of 38400.

        Like

  31. Sir Erich! Good day!

    I am trying out a project in which I would like to use the FRDM KL25Z as sort of an interface for my devices. Specifically, I am trying to control a DC motor (but I am not directly wiring it to the board, of course) to activate or deactivate depending on my C++ code. I have no idea how to make my code communicate with the FRDM, and I would like to know how exactly. I am thinking this could be done through UART? But I have read some of your tutorials on UART and I honestly have a hard time in understanding (the code) further. I honestly do not know where to start. I would love it if you could give me a heads up.

    Thanks very much in advance sir! 🙂

    Like

    • Hi Jeany,
      It all depends what your requirements (especially about timing) are. A connection with UART is in the tens of milliseconds range, and will not be enough to make a closed loop control of your motor. It is good enough to turn it on or off, but not good enough to accurately control the speed.
      Furthermore, using C++ might be a bad choice depending on your realtime aspects, as it adds yet another layer of complexity and delays.
      As a side comment: if that simple printf() example is already hard to understand, you probably better start with C code than with C++ code, as C++ is by factors more complicated and difficult in my view. But again: if you need a simple way to communicate with the board (without hardware flow control), and if your timing requirements are in the hundreds of milliseconds range, then UART (or SCI over USB, aka USB CDC) might be a good choice. Otherwise you need to define your requirements and go from there.
      I hope this helps as a starter?
      Erich

      Like

      • Sir Erich, thanks for your reply.

        I need it in C++ because I am trying to do it by clicking a button in an MFC application for example. The setup I am trying to do is like this, there are two buttons: one activate button and one deactivate button. So if I click the activate button, I want a signal to be passed to the FRDM board maybe through UART. Then when the FRDM recognizes that specific signal, it will then enable the I/O ports needed to control the driver circuit for the DC motor. Something like that. The DC motor disables if the deactivate button is clicked.

        I want to know if this is still possible? What other approach do you suggest?

        Thanks in advance Sir! 😀

        Like

        • I thought you wanted to use C++ on the board to drive the motor. On the host PC this is of course ok (as you have a lot more processing power).

          Like

      • Yes. And will I be able to use the UART0 by simply connecting the FRDM board to the host PC through the Type B USB cable? As shown in this example. Or will I have to connect it through a USB-RS232 cable? Which is a better choice?

        Like

  32. Sir Erich, on another note, I also have a module which works with a near-infrared camera with serial interfacing. I can connect it to the UART1 of the FRDM board. Thing is, I do not know how to connect UART0 (PC-MCU communication) to UART1 (MCU-camera communication) programmatically. I doubt if they are physically connected. I know that I have to create two Serial_LDD components, with different baud rates each. So how do I let the two Serial_LDD components with different baud rates communicate with each other?

    I hope you can help me on this one.
    Thanks in advance Sir Erich! 😀

    Like

    • In order to have two serial devices communicating with each other, they have to use the same communication parameters (baud rate, number of data bits, number of stp bits). There is no way around this.

      Like

      • I was thinking of creating two UART_Desc objects. One for each Serial_LDD component. And 2 buffers as well. The bytes I get from the first buffer will be sent to the 2nd UART_Desc object instead of the first. Something like that. I have it in my mind but I still can’t quite get hold of it. Let me see and try it first 🙂

        Like

  33. Does the OpenSDA CDC Serial Port support hardware handshaking? If not, is it possible to implement software handshaking instead?

    Like

    • This is because I am experiencing a data loss with the image I am getting from the camera. And I think this could be remedied using handshaking. I just do not know how.

      Like

        • Can I do this using the USB connecting the FRDM to the host PC? If so, how can this be done. *crosses fingers that it is possible*

          Like

        • I see. And also, I see that the char values for XOFF and XON are DC3 and DC1 respectively. And this might cause problems since my camera also sends this values especially when I am about to read the image file. But I’m not sure if the host PC truly can’t handle the data being sent by the camera. After all, the PC is faster compared to the camera. Maybe it has something to do with the buffer size of the RxBuffer?

          On a different note, I have managed to connect two UART_Desc objects programmatically in FRDM. Here is a link to the project. https://github.com/jeanathegreat/FRDM-KL25Z

          Maybe there is also something wrong with how I am implementing this thus the data loss?

          Like

        • Your PC might be fast, but not fast enough to get the data. Keep in mind that there is USB in between, and this can add additional latency. USB CDC without flow control is useful for communication where some data loss is not a problem (e.g. a console command line interface), but not for data transfer, unless you use low speed. In any case for data, you need to add software flow control and CRC checking.

          Like

        • Oh I see. So what do you suggest? Maybe lowering the baud rate from 115200 to 34800 maybe lessen the data loss? And about the software flow control, how can I read whether the PC is giving off a XOFF signal (meaning it is receiving more data than it can handle)?

          Like

        • Hello Sir Erich! 🙂 I finally got the camera to work. I finally gave in and interfaced the camera to the host PC using a real RS232 connection (I was just using DB9-to-USB cables) and applying level shifters. No more hardware handshaking was needed. Just wired the circuit and voila! Works like magic. Although I did try your suggestion to lower the baud rate (when I was interfacing using FRDM board), it still resulted to data loss. However, thanks very much for still replying to my queries!

          More power to your blog! 🙂
          PS: I might be back for more questions though, for other modules. Tee-hee!

          Like

        • ah, cool that you have it working now. So yes, USB-CDC adds many layers of software and potential latency, depending on the implementation (of course). My experience is that especially if I want to run a serial connection over days/months/years, then I have to use the ‘real’ RS-232 as it is much more reliable. Come back with more questions only if I can answer them 😉

          Like

    • No, the USB CDC does not implement handshacking (you will not be able to have hardware handshaking with a USB connection anyway, this is only possible with a real RS-232 connection).

      Like

  34. Hello Sir Erich! 🙂 I’m back with another question hehe.

    So here at https://github.com/jeanathegreat/FRDM-KL25Z/tree/master/Freedom_HelloWorld I uploaded a simple application that uses UART0 through USB CDC. Depending on the commands I type in the terminal, I can enable and disable the green and red LED of the FRDM-KL25Z board.

    Here at http://pastie.org/9884662 is a pseudo-code for what I’m trying to do at a bigger scale. I have a servo, linear actuator, and ir (emitter and receiver ckt) all attached to the FRDM. The servo has a disc attached on it and the disc has black markings at the bottom, sub-dividing the disc into five equal parts. The small ir ckt would be placed below the disc so that it would serve as a reader for the number of black markings it has detected while the servo is rotating the disc.

    As you can see in the psuedocode, I have worked out the main algorithm for the different states. However, I’m having trouble how to create an interrupt to enable reading from the UART when there is data in the receive buffer of UART0. I hope you can help me on this one.

    Your replies are very much appreciated Sir! 🙂

    Like

    • You can use any of the OnXXXXX() events of the AsynchroSerial Processor Expert component to hook into the interrupts. This is very easy and straight forward: enable the OnRxChar() event and you are in!

      Like

        • You will get it character by character. You can use this to build up your strings. OnTxChar() is only for receiving (Rx) it.
          Send strings with SendBlock() or character by character with SendChar().

          Like

        • So maybe I should use onFullRxBuf() event? The way I understand, if the Input buffer is full this event will be fired. So if I set the Input Buffer Size property of the AsynchroSerial component to 2048 bytes, the buffer should be full (as in the number of received bytes should be 2048) so that the OnFullRxBuf() event can be called. Is this correct?

          Like

        • I have not used it in that way, but that certainly looks like it is a good approach too. Just make sure that you can clear up the buffer fast enough so while you are reading that buffer (after 2048 bytes), that there is no data lost.

          Like

        • I tried doing this, sending character ‘a’ through UART0 but when I open the terminal to read from the serial via USB CDC I’m not getting any output.

          byte i;
          int main(void)
          {
          for(;;)
          {
          i = AS1_SendChar(‘a’);
          }
          }

          Like

        • Are your UART pins (tx, rx) correctly used/wired? Then: are your interrupts enabled (globally and the UART ones)?
          If you are sending it to the K20 USB CDC, does it work otherwise properly?

          Like

        • I am only using UART0 for this trial, so there really is no interchanging the Rx/Tx connections. I’m not sure if I enabled interrupts globally. I’m not sure if I know how to do that. Well here is my setting for the AsynchroSerial AS1 Processor Expert component if this helps. http://tinypic.com/r/jg4iz7/8 http://tinypic.com/r/1z48oyb/8

          Also, I tried also this code here and still can’t ready any characters in my terminal.

          char message[] = “Hello world”;
          AS1_TComData ch;
          byte i, err;
          int main(void)
          {
          for(;;)
          {
          for(i = 0; i < sizeof(message); i++) {
          while(AS1_SendChar((byte)message[i]) != ERR_OK) {}
          }
          }
          }

          Like

        • You might have the Rx and Tx lines/pins swapped. Your code posted here looks good, so there must be something wrong elsewhere. Have you tried/used one of my working examples on GitHub already?

          Like

        • I haven’t tried your projects yet. I have only been analyzing your code, not really trying the entire project itself. But I assume something might be mistaken with how I have configured AsynchroSerial processor expert component? Here is my AsynchroSerial project I hope you can have a look at the different configurations. I applied the USB-CDC configuration for the Cpu component also.

          https://github.com/jeanathegreat/FRDM-KL25Z/tree/master/FRDM_AsynchroSerial

          Like

        • I’m affraid that I won’t have the bandwidth to check your project. I suggest that you try out one of my example projects, and have things simple: do not add USB in the first step, simply use AsynchroSerial to the SCI. Make baby steps to have things working, then add more functionality. At a glance, it seems you are tryinig too much in the first step?

          Like

  35. I tried to find out what the return value for SendChar() method was and it is ERR_SPEED, which is something that I shouldn’t want. I should want something like ERR_OK. I know ERR_SPEED means that the device (the FRDM KL-25Z board??) does not work in the active speed mode.

    Question is: what is the active speed mode? How do I know which speed is suitable for my device? How do I change speed to the appropriate suitable speed?

    I’m doing something like this in the main():
    for(;;)
    {
    AS1_SendChar(‘a’);
    }

    Like

      • I have tried changing the baud rates from 9600 to 34800 bps and back but still nothing. Well, my setup is really simple sir. I just have my FRDM board attached to the pc with a mini-B usb cable so I am using the P&E OpenSDA virtual USB CDC on UART0. No other connections. Just need the frdm communicate with the host pc. /sigh

        I have already tried your project (the one on this post) and have it worked, also on different baud rates. I even tweaked it so that at specific commands, the LED on frdm board will respond. I can also send specific strings through UART depending on received strings. 🙂

        But your project is using Serial_LDD component which is totally different from AsynchroSerial component (the one you suggested because of the interrupt-based sending to and receiving from UART).

        I am only trying to see if the SendChar() method of the AsynchroSerial component works and if it can be read by host pc through a terminal. But it returns ERR_SPEED instead. I dont see why ERR_SPEED would be the problem since I have used UART0 via USB CDC using Serial_LDD component on FRDM and set it to other baudrates but it still works! I dont really have a specific baud rate to work with (there is no requirement). But a 9600bps would do.

        Like

  36. Hello Erich,
    I need to realize a bridge between USB CDC and UART trought MK60DX.

    In detail: on my board I have an UART WiFi module connected to microcontroller via UART0. This module provide firmware upgrade via UART.
    My objective is update its firmware via PC using a bridge between USB CDC (PC) and UART (WiFi Module). The bridge will be implement in microcontroller.

    I think to proceed in this way:
    Using USB CDC and UART interrupt on received byte: if the byte arrive on UART I put it on USB CDC, vice verse if I receive a byte on USB, I put it on UART0.

    What do you think about this?
    Any suggestions?

    I have already implement USB CDC (with your component) in my project created with KDS.

    Thanks!

    Federico

    Like

      • Hi Erich,
        thanks for your reply.

        I used your tutorial to create USB virtual COM.

        I have two questions:
        * In which way I can handle the interrupt from USB (received data)?
        * Which function I need for write on USB the data comes from UART?

        I appreciate your help!

        Federico

        Like

        • Hi Federico, with that USB stack implementation (v4.1.1), you usually do not hook directly into the interrupt. You get an interrupt, it stores the data into a buffer and the application handles it from the ‘process()’ method. If you directly want to deal with this in the interrupt, be free to change the stack to your needs.

          Like

      • Erich could you specify which function I need to use for read the USB buffer managed by the USB stack?

        Is there a function to know how many bytes are available?

        Which is the function to write a byte on USB cdc?

        Sorry for the questions but I’m a beginner in the USB communication,

        Like

        • Hi Federico,
          have a look at the methods of the USB CDC example.
          CDC1_GetCharsInRxBuf() gives you the number of bytes available.
          CDC1_SendChar() is used to send a byte on USB CDC

          Like

      • Thanks Erich!

        Now I try to implement something with this function.

        Can I see the sent byte on USB with a terminal program like Putty?

        Thanks very much!

        Like

      • Good evening Erich,

        I realize one part of my Bridge.

        I implement FreeRTOS and I use two task: one is the main program and the other read the byte coming from PC through USB CDC.

        Everything works fine but when I test the send of byte over UART0 to WiFi module the system goes in stuck.

        In details the system stuck on PE_ISR(UART0_Interrupt).

        I use this tutorial to config the UART. Before the implementation of FreeRTOS the UART communication works fine.

        Any suggestions?

        Thanks

        Federico

        Like

      • Hi Erich,

        today I have a new problem, a very big problem.

        Yesterday my PC recognized for all the day the virtual com but this morning recognize only an unknown device.

        I think that’s a Firmware problem but if I load a previous working firmware the problem remain.
        Do you have any hint for the driver installation? I pick up the cdc driver from Documentation folder in my KDS project.

        Thanks

        Like

        • Can you you try on a different machine to elimiate a driver problem? Otherwise, uninstall the current driver and re-install it from the Documenation folder, following exactly the steps of that readme text file in that folder.

          Like

      • Hi Erich,

        sorry for the late reply but I’m away for the weekend.

        I solved my problem! The problem was due to driver issue.

        I edited the .inf DESCRIPTION filed in CDC Settings from “Freescale CDC Device” to a custom value. I suppose that is the cause of the problem.

        Now I restore that field to the original value and the system works.

        Thanks for your help!

        Federico

        Like

        • Hi Frederico,
          ok, that makes sense: if the description does not match your CDC settings, the driver will not be recognized. But I thought that I had the generated .inf matching the settings in the component, or I have missed something?
          Thanks,
          Erich

          Like

      • Hi Erich,

        I used the device driver generated by processor expert without changes. I changed the description in the CDC component.

        Like

        • The property in the Processor Expert component gets put into the DESCRIPTION of the cdc.inf file. To my understanding this is just a description text, and is not used anywhere else or has a function. I’m missing something? So I don’t see why this would break enumeration of the device 😦

          Like

    • Hi Erich, thanks for the reply.

      I try two different PCs with W7 and the problem remain.

      I follow the Readme instruction, but nothing has changed.

      I don’t understand why yesterday the CDC Virtual com worked well and today my PC find a Unknown device.

      Like

      • So then I think your hardware might be broken. Or could it be that the firmware somehow is not the same? I would exchange USB cables and boards to isolate the issue.
        I hope this helps,
        Erich

        Like

      • I used the same board, the same usb cable and the same firmware.

        Does the problem can derive from the firmware? But why yesterday everything works well? 😦

        Thanks for your help Erich!

        Like

        • Hi Federico,
          I don’t know what the problem is. But if the device does not properly enumerate, it is either
          a) a problem in the firmware (something has changed)
          b) a problem in the hardware (cable, connector, board)
          c) a problem on the host (drivers)

          Like

  37. I just want to thank you personally from the bottom of my heart about this blog you created. I nealy dropped out of my Msc program wit fustration of microcontroller programming and interfacing. I have implemented your code and it is working perfectly on my mk20 microcontoller. my problem is that i want to store the characters into an array and make use of it to perfom CRC check and I/O port contol and data exchange.

    Like

    • Hi Adeola,
      glad to hear that I rescued a microcontroller programming soul :-). If you want to store characters in an array, you could use either my Utility component functions (there are several functions to deal with arrays) or you use sscanf() or sprintf(): then you can do with that array whatever you want.

      Like

      • thanks check this code sir i
        uint8_t buff [100];
        static int noter;

        void storeData(void){

        //int g=0;

        unsigned char mych;

        if (RxBuf_NofElements()!=0){
        SendString((unsigned char*)”Stored data::”, &deviceData);

        // i = 0;
        while (RxBuf_NofElements() !=0)
        {
        (void)RxBuf_Get(&mych);
        buff[noter]= mych;
        noter++;
        }
        memcpy(&buff[noter],beefer,4);
        // for(g=0;g<=sizeof buff;){
        // nana[g]=buff[g];
        // g++;
        memset(nana,'',sizeof nana);
        memcpy(&mme[33],buff, 52);
        memcpy(nana,&mme[33],52);

        }
        noter=0;
        }

        main(){
        while(1){
        SendString(buff, &deviceData);
        }
        }
        if i write i write 50 characters on putty only few characters will be displayed

        results

        Enter data here: abcdefghijklmnopqrstuvwxyz
        Stored data::::::::::::::::::::::::::::abcdefghijklmnop

        only 16 character is printed in 26 i entered

        Like

        • Yes, that Serial_LDD does not have the buffering implemented. You have three options: either implement your own buffering, send it with a slower speed or using the AsynchroSerial component with buffering.

          Liked by 1 person

      • thanks for the guidance its pretty loely out here in the microcontroller world. mys of my friend stick to there ATMEL and run from mk20 microcontrollers. I have imported Asynchroserial with interrupt enabled, 128bytes of buff for TX and Rx But i keep getting the last characters inputed instead of the whole string. my code goes like this.

        for TX

        uint8_t buff[100];

        void SEND_DATA(void){
        word p;

        //AS2_SendChar((byte)’B’);
        while(AS2_SendBlock(buff, sizeof buff, &p )==ERR_OK){} ;
        }

        for RX

        void STORED_DATA(void){
        word p;

        while( AS2_RecvBlock(buff,sizeof(buff),&p)==ERR_OK){};
        }

        i never wrote any code in the event.c
        but i keep getting the last char instead of a string sent from my Beaglebone connected to the mk20.

        Like

  38. Hi, any chance of getting this updated? Some of the components used here are not available in the new KDS 2. I really need to be able to read bytes via interrupt. Freescale haven’t been much help and their forum didn’t yield much either. I can get the callback function to fire when I send a byte to the board but I can’t read it and the board crashes on exit from the callback even if I don’t add any code. Its a MQX application. I can’t find any documentation that describes how to actually use the PE callback function. Thanks Wayne

    Like

      • Hi Erich, thank you for the quick response. I did install your PE components and tried to build your project in KDS 2 using my K64F with a bluetooth radio on UART4. I have several issues. 1. I don’t have a Serial_LDD part, I can paste from your project but I worry that that might cause issues. The ring buffer component doesn’t have the Uint8 on the end of its name, hopefully that’s just a name change. My project is also not generating the PE_Type header files for some reason. I’ll keep digging into it a bit later.
        Thanks
        Wayne

        Like

        • Hi Wayne,
          yes, the RingBuffer component has changed to a more generic one.
          As for the Serial_LDD: I remember there was a service pack/add-on to have LDD device drivers for the K64F, as otherwise it only comes with drivers for the Kinetis SDK. Not sure if this helps.

          Like

  39. Hi Erich,
    Well I think I have come full circle. Looking at a post you commented on there seem to be issues with using the LDD drivers with KDS. (https://community.freescale.com/message/441275#441275). I view articles like your here as a tutorial and building block for my own applications. So, it looks like this is no longer applicable, for KDS at least. I have to think that the new fsl_uart component should be able to handle interrupt driven communications, something similar to what you are doing here. I am just not able to find any information about how to actually do it, especially with respect to the Callback option. I posted a question about this (https://community.freescale.com/thread/342541). David did reply but his solution wasn’t really what I was asking for and it looks like the thread died.

    Like

    • Hi Wayne,
      the fsl_* components only can be used with the Kinetis SDK, and are using a completely different API, as the Kinetis SDK is using a different driver architecture. If you want to use the fsl_* components, you have to learn the Kinetis SDK (www.freescale.com/kds).

      Like

      • Hi Erich,
        Thank you for taking the time to answer my questions. I was able to create a NMEA parser using the fsl_uart component. As you say it is completely different and requires a different approach. I did have to create my own ring buffer. It works but I am not a big fan of the approach that the developers took with the component. Its great for talking to things like modems but it gets more complicated when reading continuous streaming data from a GPS.

        Like

  40. Thank you. you have a great site.
    i downloaded and built your project in codewarrior 10.6 but i got a lot of errors

    mingw32-make: *** [Freedom_HelloWorld.elf] Error 1

    Do You know what it might be?

    Like

  41. Hello and thank-you for your great site. Can I ask you for a bit of advice? I am using
    Processor Expert to make a uart with AsynchroSerial using this code…

    //some declarations…
    char OutData[] = “Hello world”;
    LDD_TError Error;
    LDD_TDeviceData *MySerialPtr;
    //
    int main(void)
    /*lint -restore Enable MISRA rule (6.3) checking. */
    {
    PE_low_level_init();
    /* send a string */
    Error = AS1_SendBlock(MySerialPtr, OutData, sizeof(OutData)); /* Send block of characters */
    //
    // rest of code…etc…

    After building I get:
    passing argument 2 of ‘AS1_SendBlock’ makes integer from pointer without a cast [enabled by default]
    passing argument 3 of ‘AS1_SendBlock’ makes pointer from integer without a cast [enabled by default]

    Do you perhaps have some advice?
    Russell

    Like

    • Russel,
      SendBlock() uses as first argument the pointer to the data, the second argument is the size of the data in bytes, and the third argument is a pointer to a word/16bit variable where the function returns how many bytes have been sent.
      So you need to use ti like this:
      uint8_t res;
      uint16_t snt;

      res = AS1_SendBlock(OutData, strlen(OutData), &snt);

      Erich

      Like

  42. Hi Erich,
    I want to build a light weight event logger system in my embedded application. For now, I want to print all the data to the UART which will be connected to serial console on computer/laptop etc. Later, I want to print the same to SD card so that I can get logs in the SD Card.

    1. What is the better way to build event logging system.
    2. Do you have any tutorial on the same? or any links or suggestions?

    Like

    • Hi Vishal,
      It all will depend on the amount of data you want to log. You can use printf() style to log to the console, and use fprintf() to do the same to files. But keep in mind that both printf() and fprintf() have a lot of overhead and need a lot of RAM (stack).
      I recommend that you use the McuOnEclipse Utility module with the string functions and then write the string buffers to the SD card, instead using printf() and fprintf().
      If logging to the SD card, do not forget to call flush() frequently to push the data to the SD card, so if you loose power, the data is written to the disk. In general, loss of power is a problem for a file based system. Plus the file system has its own overhead. Instead, you might consider to write raw blocks to the SD card. But then you need a utility on the host to get that data too.
      I hope this helps on the direction.

      Like

  43. Hi Erich,
    I am using a Wifi Module which supports serial UART communication. In my design, I have a serial debug terminal which connects to PC and serial wifi terminal which connects to wifi module.

    =============

    I am using HF-LPB100 wifi module from HiFly CHina.

    I have two questions.
    1. I send commands and data to wifi module using the term wifi_termSendStr etc. functions which are from PE. I have to read characters from wifi module and display on the Debug_term. What is the best way to do it. For now I have seperate task which reads each character from wifi and displays on debug terminal . Is there a better way?

    2. I want to set high baud rates. Wifi module supports 115200, 230400, 380400, 460800. But in PE, i am not able to set 460800. It is not shown in possible settings. It shows 115200, 128000, 256000 in the possible settings of AsynchroSerial bean of Wifi Term. How can I use 460800?

    Any suggestions would be of great help.

    Like

    • Hi Vishal,
      1) Your approach with a task sending/receiveing data is a good one, I would use the same way.
      2) The max baud rate depends on your peripheral clock (and core clock). Make sure you run the CPU with max frequency (e.g. 120 MHz, see https://mcuoneclipse.com/2014/06/14/frdm-k64f-atmaximum-speed-of-120-mhz/). Then, in the AsynchroSerial component you can enter any baud rate. With that 120 MHz clock I can get up to 7500000 baud. In the Timing dialog, yes, there are some preconfigured (standard) baud settings available (1200, 2400, … 256000), but at the bottom it should say ‘from 916 baud to 7500000 baud’, so you can select and baud in that range 🙂

      I hope this helps.

      Like

  44. How sir. Is it possible to change the baudrate of the UART during run time on the freescale board?? I am currently doing a project that require the freescale MK20 microcontroller talk at baud 600 to an energy measuring chip cs5490 and tell it via UART to increase its baud rate to 19200Baud. I successfully change the CS5490 baud to 19200 from 600Baud by writing the serial register. To now change the Baud rate of thE freescale Mk20 microcontroller from 600 to 19200 at run time is elusive to me sir. How do i go about it??

    Like

    • That depends to some extend how you are programming your microcontroller. The easiest and simplest way is to use Processor Expert with the AsynchroSerial component: there you can configure it to use multiple clock configurations, as a list of different clock speeds). Then you can switch the baud at runtime. Of course you can directly change the baud/prescaler register too.

      Like

      • Whaoh thanks for the prompt response.I have already built the project arround the serial_ldd used in this project instead of Asynchrserial. I think the only option is to write the the register which is alittle bit messy trying to trace the address and the offset of the baud uart register. i just dont know where to start looking for the address of the UART to change to 19200Baud. Its very easy on the adurino unlike the freescale board mk20.

        Like

        • The Serial_LDD has a method/function SelectBaudRate() which does exactly what you want/need. Check the help information for that component and method: make sure you have specified a ‘list of values’ in the timing dialog.

          Like

      • this are the methods on Serial_LDD

        LDD_TDeviceData* AS1_Init(LDD_TUserData *UserDataPtr);

        LDD_TError AS1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size);

        LDD_TError AS1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size);

        static void InterruptRx(AS1_TDeviceDataPtr DeviceDataPrv);

        static void InterruptTx(AS1_TDeviceDataPtr DeviceDataPrv);

        PE_ISR(AS1_Interrupt);

        I cant find selectBaudRate(); there i want to try the register method.

        Like

        • Have a look at the list of component methods: it is disabled by default, you need to enable it, and as indicated by the tooltip help for it: you need to have a ‘list of values’ in the clock (baud) settings.

          Like

  45. Thank you very much for this great tutorial. I used kinetis design studio 3.0.0 with the processor expert feature (to set up a Kinetis Project for KL25Z). I needed to first update the processor expert library by using an internal kds 3.0.0 option to install the latest .PEupd files from sourceforge (after googling ‘processor expert updates sourceforge’). Once the .PEupd files were downloaded, I needed to install in KDS using File->Import->ProcessorExpert->Components to Component Library -> browse.

    From there, I was able to follow the steps in your excellent tutorial. I recall that when I added the component called RingbufferUint8, I needed to ‘rename’ the name of it from ‘Rng1’ to ‘RxBuf’ to align with this tutorial.

    Building was successful. Loading the program (.srec file) to the KL25Z worked. But no communications to begin with. I’m a newbie, so didn’t at first understand that this UART example will work as-is, with no other USB connection required, except for the original USB connection for loading the .srec program file to the KL25Z. The other important software I needed was the PE Micro driver software ‘PEDrivers_install.exe’, which I needed to install (in my Windows 8.1 with the ‘run as administrator’ option). It took me a while to understand that this driver will help to generate a COM port connection (via USB), so that the UART communications will work via a USB connection between computer and KL25Z. Using a baud rate of 38400, I pushed the ‘reset button’ on the KL25Z, and the UART communications started to work (via the USB link). The USB port used is the port that faces the green coloured LED (not the other USB port). The USB port that faces the processor chip remained unused. This UART tutorial really helped me a lot. Thanks again!

    Like

    • Hi Kenny,
      thank you so much for sharing the steps you had to do. I admit that too often I just assume some knowledge or steps because I’m so used to it. And over time things are changing in the tools as well, and it is hard to update all previous tutorials too. I understand that things are working now on your end, otherwise let me know.
      Thanks for sharing,
      Erich

      Like

      • Hi Erich,
        Thanks for letting me post here. It is the style of your tutorials that helps everybody tremendously here. Concise, step-by-step with code and screen-shots, with very useful side notes really gets us going and makes things really encouraging. Thanks for your time and tremendous amount of effort for showing us how to get started Erich. I forgot to mention that I downloaded the RingBufferUInt8 component after googling “RingBufferUInt8 freescale”. Without your tutorial, I think it would have been too overwhelming for me to make my own UART program. Countless people will benefit from these tutes. Thanks once again, and best regards.

        Kenny.

        Like

        • Hi Kenny,
          thanks :-). I have replaced later the RingBufferUInt8 component which only implements 8bit items with a more general RingBuffer component which implements items for 1, 2 and 4 bytes.

          Erich

          Like

  46. Hi Erich , how are you . I have implemented this gorgeous method , but now i need send some floats data from a sensor , i have been change the unsigned char* in the SendString but the argument is incompatible. what can i do int his case ? i need create a new function like sendtring but with float?

    Regards 🙂

    Like

  47. Hello there,I am making one project on rfdm-kl25z board.In that project we are using two UART..Which two UART are best for me to select.Like from ur example i can understand that uart0 is easy to program. I am conecting rfid reader and xbee with uart.

    Please help me if there any change that i need to do in hardware side?om ur example i can understand that uart0 is easy to program. I am conecting rfid reader and xbee with uart.

    Please help me if there any change that i need to do in hardware side?

    Like

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.