芯科公司的EFM32单片机与ST的STM32同为32位ARM架构的单片机。它的特点是能耗管理做的更细更到位。所以在很多对能耗非常在意的场合,比如用电池供电的指纹锁、物联网传感器等领域应用比较广泛。但芯科公司的单片机比较缺乏系统的学习资料,虽然网站上提供了应用实例与说明。但总体上给人不成系统并且零乱的感觉。对想使用芯科单片机的开发人员造成不小的入门困扰。在这里我们通过一个系列,拿出真正可运行的代码实例来帮到相关的开发者。
单片机开发中,非常重要的第一步就是能够调通串口。只要串口一通,就可以让单片机随时告诉我们程序的运行状态。为开发工作带来很大的便利。所以本系列从串口的使用开始。
EFM32单片机的串口相比较于STM32系列,特殊之处在于提供了一个可以在EM2模式下使用的LEUART串口。这个EM2模式是EFM32单片机关闭了绝大部分外设的一种低功耗模式。在这种模式下LEUART串口的时钟源可以被调整到32.768k时钟晶振上。在超低功耗模式EM2下,这个串口可以唤醒MCU,也可以直接与DMA配合自动完成数据收发而不打扰MCU的睡眠。以保持更低的功耗。
下面就是USART串口的精要版实现代码:
void setupUsart(void)
{
/* Enable peripheral clocks */
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
/* To avoid false start, configure TX pin as initial high */
GPIO_PinModeSet(gpioPortD,0, gpioModePushPull, 1);
GPIO_PinModeSet(gpioPortD,1, gpioModeInput, 0);
USART_TypeDef *usart = USART1;
USART_InitAsync_TypeDef initAsync = USART_INITASYNC_DEFAULT;
CMU_ClockEnable(cmuClock_USART1, true);
initAsync.enable = usartDisable;
initAsync.baudrate = 115200;
USART_InitAsync(usart, &initAsync);
USART1->IFC = _USART_IFC_MASK;
NVIC_ClearPendingIRQ(USART1_RX_IRQn);
NVIC_EnableIRQ(USART1_RX_IRQn);
USART1->IEN = USART_IEN_RXDATAV;
/* Enable I/O and set location */
USART1->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | USART_ROUTE_LOCATION_LOC1;
/* Clear previous RX interrupts */
USART_IntClear(USART1, USART_IF_RXDATAV);
NVIC_ClearPendingIRQ(USART1_RX_IRQn);
/* Enable RX interrupts */
USART_IntEnable(USART1, USART_IF_RXDATAV);
NVIC_EnableIRQ(USART1_RX_IRQn);
/* Finally enable it */
USART_Enable(usart, usartEnable);
}
这段代码是USART功能的一段初始化代码,可以在主程序开始后使用。其中的加粗显示部分都是可以更改的,而且也必须要根据你选用的单片机的具体型号和具体资源的配置的不同而改变。
这段初始化代码完成后还需要注意需要补充一个USART串口的接收中断服务:
void USART1_RX_IRQHandler(void)
{
static uint8_t data;
__IO uint32_t usartif;
usartif =USART_IntGet(USART1);
USART_IntClear(USART1,usartif);
if(usartif & USART_IF_RXDATAV)
{
data = USART1->RXDATA;
UsartReciveFlag=true;
UsartBuffer[UsartCounter]=USART1->RXDATA;
UsartCounter++;
//TIMER_Enable(TIMER0,true);
}
}
要注意的是这段代码的函数名不可以随便改动,和所有的CortexM3单片机一样。中断处理函数的名字在startup.s文件中已经设定好了。所以不要随意改动。至此,在程序主While循环前,你就可以调用这段初始化代码。并把中断处理程序放在主程序之后。
EFM32的USART提供了两个库函数可以用来发送单字节字符与双字节字符,他们分别是:
void USART_Tx(USART_TypeDef * usart,uint8_t data ) ;
void USART_TxDouble(USART_TypeDef * usart,uint16_t data);
用这样的命令就可以通过USART1来发送字符'A'了:USART_Tx(USART1,0x41)。其他的USART以此类推。
在基本的串口收发功能调通了以后,如果要使用全功能的USART,那就要详细参考EFM32的库函数说明,并参考EFM32开发环境SimplicityIDE中提供的例子。
EFM32的库函数参考网址:http://devtools.silabs.com/dl/documentation/doxygen/5.6/efm32g/html/index.html