Hello, my name is Alex and I am new in this community. I recently started a project using the FRDM-KL05Z board and I am interested in some examples on how to configure the UART protocol without Processor Expert. So far I found some init and read/write methods but they don't seem to work properly.
Below you can find the code for this methods :
void uart_init (UART_MemMapPtr uartch, int sysclk, int baud)
{
register uint16 sbr, brfa;
uint8 temp;
/* Enable the clock to the selected UART */
if(uartch == UART0_BASE_PTR)
SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
else
if (uartch == UART1_BASE_PTR)
SIM_SCGC4 |= SIM_SCGC4_UART1_MASK;
else
if (uartch == UART2_BASE_PTR)
SIM_SCGC4 |= SIM_SCGC4_UART2_MASK;
else
if(uartch == UART3_BASE_PTR)
SIM_SCGC4 |= SIM_SCGC4_UART3_MASK;
else
if(uartch == UART4_BASE_PTR)
SIM_SCGC1 |= SIM_SCGC1_UART4_MASK;
else
SIM_SCGC1 |= SIM_SCGC1_UART5_MASK;
/* Make sure that the transmitter and receiver are disabled while we
* change settings.
*/
UART_C2_REG(uartch) &= ~(UART_C2_TE_MASK
| UART_C2_RE_MASK );
/* Configure the UART for 8-bit mode, no parity */
UART_C1_REG(uartch) = 0; /* We need all default settings, so entire register is cleared */
/* Calculate baud settings */
sbr = (uint16)((sysclk*1000)/(baud * 16));
/* Save off the current value of the UARTx_BDH except for the SBR field */
temp = UART_BDH_REG(uartch) & ~(UART_BDH_SBR(0x1F));
UART_BDH_REG(uartch) = temp | UART_BDH_SBR(((sbr & 0x1F00) >> 8));
UART_BDL_REG(uartch) = (uint8)(sbr & UART_BDL_SBR_MASK);
/* Determine if a fractional divider is needed to get closer to the baud rate */
brfa = (((sysclk*32000)/(baud * 16)) - (sbr * 32));
/* Save off the current value of the UARTx_C4 register except for the BRFA field */
temp = UART_C4_REG(uartch) & ~(UART_C4_BRFA(0x1F));
UART_C4_REG(uartch) = temp | UART_C4_BRFA(brfa);
/* Enable receiver and transmitter */
UART_C2_REG(uartch) |= (UART_C2_TE_MASK
| UART_C2_RE_MASK );
}
/********************************************************************/
/*
* Wait for a character to be received on the specified UART
*
* Parameters:
* channel UART channel to read from
*
* Return Values:
* the received character
*/
char uart_getchar (UART_MemMapPtr channel)
{
/* Wait until character has been received */
while (!(UART_S1_REG(channel) & UART_S1_RDRF_MASK));
/* Return the 8-bit data from the receiver */
return UART_D_REG(channel);
}
/********************************************************************/
/*
* Wait for space in the UART Tx FIFO and then send a character
*
* Parameters:
* channel UART channel to send to
* ch character to send
*/
void uart_putchar (UART_MemMapPtr channel, char ch)
{
/* Wait until space is available in the FIFO */
while(!(UART_S1_REG(channel) & UART_S1_TDRE_MASK));
/* Send the character */
UART_D_REG(channel) = (uint8)ch;
}
/********************************************************************/
/*
* Check to see if a character has been received
*
* Parameters:
* channel UART channel to check for a character
*
* Return values:
* 0 No character received
* 1 Character has been received
*/
int uart_getchar_present (UART_MemMapPtr channel)
{
return (UART_S1_REG(channel) & UART_S1_RDRF_MASK);
}
I was just wondering if anyone used those routines or something similar or has an example on how to communicate with a terminal using the UART protocol on the FRDM-KL05Z board.
This is my first time using a freescale microcontroller so I don't fully understand all it's aspects so any information will be greatly appreciated.
Hello ION,
- There is FRDM-KL05 sample code package , it have UART driver, after you download it , you can find here :
KL05-SC\KL05-SC\klxx-sc-baremetal\src\drivers\uart
you can download it here :
Freedom Development Platform for Kinetis MCUs|Freescale
- And why you do not use Processor Expert , it is a good tool help you develop the project , there also is sample code about how to use it .
For example : add the component "Serial_LDD" , right click it , you can find "help on component" , then in the "Typical Usage" you can find
how to configure it and the demo code :
Hope it helps
Have a great day,
Alice
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Thanks for the reply Alice, i am not using Processor Expert because i want to do everything from the start as a baremetal project and because further in the project i want to optimize the power consumption so i want to write as little code as possible. Below there is a code i edited for my board but it won't work.. the data register just won't save the value that a send to the terminal. Did anyone else encounter this problem ?
#include "MKL05Z4.h"
#include "uart.h"
void uart0_init (UART0_MemMapPtr uartch, int sysclk, int baud)
{
/* Enable the clock to the selected PORT */
SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;
/* Set the pins multiplexer to UART RX/TX mode */
PORTB->PCR[1] = ( PORT_PCR_ISF_MASK | PORT_PCR_MUX(3) );
PORTB->PCR[2] = ( PORT_PCR_ISF_MASK | PORT_PCR_MUX(3) );
/* Enable the clock to the selected UART */
SIM->SOPT2 = SIM_SOPT2_UART0SRC(1);
SIM->SCGC4 |= SIM_SCGC4_UART0_MASK;
/* Make sure that the transmitter and receiver are disabled while we
* change settings.
*/
UART0_C2 = 0x00U;
/* Configure the UART for a 9600 baud rate */
UART0_BDL = UART0_BDL_SBR(0xC8);
UART0_BDH = UART0_BDH_SBR(0x00);
UART0_MA1 = UART0_MA1_MA(0x00);
UART0_MA2 = UART0_MA2_MA(0x00);
UART0_C4 = UART0_C4_OSR(0x18);
UART0_C1 = 0x00U;
UART0_S1 = 0xC0U;
UART0_S2 = (UART0_S2_LBKDIF_MASK | UART0_S2_RXEDGIF_MASK);
(void) UART0_D;
UART0_C5 = 0x00U;
UART0_C3 = 0x00U;
/* Enable transmitter and receiver */
UART0_C2 |= (UART0_C2_TE_MASK | UART0_C2_RE_MASK);
}
/********************************************************************/
/*
* Wait for a character to be received on the specified uart
*
* Parameters:
* channel uart channel to read from
*
* Return Values:
* the received character
*/
char uart0_getchar (UART0_MemMapPtr channel)
{
/* Wait until character has been received */
while (!(UART0_S1_REG(channel) & UART0_S1_RDRF_MASK));
/* Return the 8-bit data from the receiver */
return UART0_D_REG(channel);
}
/********************************************************************/
/*
* Wait for space in the uart Tx FIFO and then send a character
*
* Parameters:
* channel uart channel to send to
* ch character to send
*/
void uart0_putchar (UART0_MemMapPtr channel, char *ch)
{
int i = 0;
while (*(ch + i) != '\0')
{
/* Wait until space is available in the FIFO */
while(!(UART0_S1_REG(channel) & UART0_S1_TDRE_MASK));
/* Send the character */
UART0->D = *(ch + i);
i++;
}
}
/********************************************************************/
/*
* Check to see if a character has been received
*
* Parameters:
* channel uart channel to check for a character
*
* Return values:
* 0 No character received
* 1 Character has been received
*/
int uart0_getchar_present (UART0_MemMapPtr channel)
{
return (UART0_S1_REG(channel) & UART0_S1_RDRF_MASK);
}
int main()
{
int i = 0;
char text[128] = "Hello world";
uart0_init(UART0, 48000, 9600);
while (1)
{
uart0_putchar(UART0, text );
}
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
Hello ION,
After i checked your code , i found one error here :
PORTB->PCR[1] = ( PORT_PCR_ISF_MASK | PORT_PCR_MUX(3) );
PORTB->PCR[2] = ( PORT_PCR_ISF_MASK | PORT_PCR_MUX(3) );
Please change it to :
PORTB->PCR[1] = ( PORT_PCR_ISF_MASK | PORT_PCR_MUX(2) );
PORTB->PCR[2] = ( PORT_PCR_ISF_MASK | PORT_PCR_MUX(2) );
For from the SCH we can see the FRDM-KL05 use the PTB2 as UART0_RX, use the PTB1 as UART0_TX.
Hope it helps
Have a great day,
Alice
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi
The amount of code will have no influence on the power consumption.
See the following for a report on using UARTs in low power mode: Using Kinetis Low Power Stop Modes with unrestricted UART operation - a report
In fact, using a blocking method as you have used to write a string will have higher current consumption than using an interrupt/DMA driven one that allows the processor to stop the core while waiting for each byte to be transmitted.
Regards
Mark
Kinetis: http://www.utasker.com/kinetis.html
KL05: http://www.utasker.com/kinetis/FRDM-KL05Z.html
UARTs: http://www.utasker.com/docs/uTasker/uTaskerUART.PDF
For the complete "out-of-the-box" Kinetis experience and faster time to market
:smileyinfo: Out-of-the-box boot loader support for 46 Kinetis boards, 8 modes and 10 IDEs (over 15'000 combinations from a single code source with no porting required)
Hi
Your code is for a K-type device and is not compatible with the KL parts.
Regards
Mark
Kinetis: http://www.utasker.com/kinetis.html
KL05: http://www.utasker.com/kinetis/FRDM-KL05Z.html
UARTs: http://www.utasker.com/docs/uTasker/uTaskerUART.PDF
For the complete "out-of-the-box" Kinetis experience and faster time to market
:smileyinfo: Out-of-the-box support for 46 Kinetis boards and 10 IDEs (460 combinations from a single code source with no porting required)