マイコンボードでは、UART(シリアル通信)でパソコンと通信を行うことも多いかと思います。そこで今回は、コンパクトなUARTドライバを紹介したいと思います。
ドライバは、必要最低限の機能しかないので必要に応じて機能を拡張していけば良いでしょう。基本的な関数として以下のものがあるだけです。
・IO設定
・1文字の受信
・文字列の受信
・1文字の送信
・文字列の送信
/*
* uart_small.h
*
* Created on: 2013/09/16
* Update : 2014/06/06
*
* Author: easylabo
*/
#ifndef UART_SMALL_H_
#define UART_SMALL_H_
#if CONFIG_ENABLE_DRIVER_UART_SMALL == 1
#define LSR_THRE 0x20
#define LSR_RDR 0x01
#define UART_ECHO 0
extern void UartInit(uint32_t baudrate);
extern void UartPutC(const char c);
extern int UartPutS(const char *s) ;
extern int UartGetC(void);
extern char *UartGetS(char * const buf, const int size);
#endif
#endif /* UART_SMALL_H_ */
/*
* uart_small.c
*
* Created on: 2013/09/16
* Update : 2014/07/05
*
* Author: easylabo
*/
#include "driver_config.h"
#if CONFIG_ENABLE_DRIVER_UART_SMALL == 1
#include "uart_small.h"
// initialization
void UartInit(uint32_t baudrate) {
uint32_t Fdiv; // clock divisor ratio
// P01_7, select function TXD
LPC_IOCON->PIO1_7 &= ~0x07; // reset FUNC=0x0
LPC_IOCON->PIO1_7 |= 0x01; // set FUNC=0x1 (TXD)
// P01_6, select function RXD
LPC_IOCON->PIO1_6 &= ~0x07; // reset FUNC=0x0
LPC_IOCON->PIO1_6 |= 0x01; // set FUNC=0x1 (RXD)
// enable UART clock
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); // UART=1
LPC_SYSCON->UARTCLKDIV = 0x01; // divided by 1
// calculate Fdiv
Fdiv = (
SystemCoreClock // system clock frequency
* LPC_SYSCON->SYSAHBCLKDIV // AHB clock divider
) / (
LPC_SYSCON->UARTCLKDIV // UART clock divider
* 16 * baudrate // baud rate
);
// set the baud rate divisor value
LPC_UART->LCR |= 0x80; // DLAB in LCR must be one in order to access the UART divisor latches
LPC_UART->DLM = Fdiv / 256; // set DLM, divisor latches
LPC_UART->DLL = Fdiv % 256; // set DLL, divisor latches
LPC_UART->LCR &= ~0x80; // disable access to divisor latches (DLAB = 0)
// UART setting
LPC_UART->LCR = 0x03; // 8 bit, 1 stop bit, no parity
LPC_UART->FCR = 0x07; // enable an reset TX and RX FIFO
}
// send a character
void UartPutC(const char cPut) {
while (!(LPC_UART->LSR & LSR_THRE)); // wait for TX buffer ready
LPC_UART->THR = cPut;
}
// send a string
int UartPutS(const char *sPut) {
int n;
for (n = 0; *sPut; sPut++, n++) {
UartPutC(*sPut);
}
return n;
}
// receive a character
int UartGetC(void) {
while (!(LPC_UART->LSR & LSR_RDR)); // wait for RX buffer valid
return LPC_UART->RBR;
}
// receive a string, delimiter is CR
char *UartGetS(char * const bufStr, const int sizeOfBuf) {
// bufStr: line buffer
// sizeOfBuf: size of bufStr
int chr;
int n = 0;
while (n < sizeOfBuf - 1) {
chr = UartGetC();
// detected delimiter CR
if (chr == '\r') {
//echo ON or Off
if(UART_ECHO){
UartPutS("\r\n");
}
break;
}
//echo ON or Off
if(UART_ECHO){
UartPutC(chr);
}
bufStr[n++] = chr;
}
bufStr[n] = 0;
return bufStr;
}
#endif
上記のソースコード例は、LPC1114のハード設定になっています。
受信のデリミタ(区切り文字)は、キャリジリターンです。受信時に割り込みを使っていないので、受信時は待ち受け状態になります。
driver_config.hに以下を記述すればドライバが有効になります。
Sponsored Link