在单片机程序开发中除了单步调试外,最有效的调试方法算是打印调试了,所以这里先把串口功能调试好,也方便以后的调试开发。
nRF51822带有一个UART接口,但是没有固定的TX、RX引脚,是可以任意配置到不同的IO引脚上,这也为硬件上连线提供了方便。
Ok,我们在蓝牙样板程序中增加UART功能。
首先是串口初始化,串口初始化可以使用simple_uart.c提供的simple_uart_config()函数,但这是不带中断的,还需要自己编写一个UART0_IRQHandler()中断处理函数并做相应的配置。
如果只是简单的打印调试信息的话可以使用这种方式,这种方式也是单片机常见的写法。
但这里我们不打算使用这个接口,而使用app_uart_fifo.c中的app_uart_init()函数来做初始化,这里也可以使用宏APP_UART_FIFO_INIT。
uart部分代码如下:
nRF51822带有一个UART接口,但是没有固定的TX、RX引脚,是可以任意配置到不同的IO引脚上,这也为硬件上连线提供了方便。
Ok,我们在蓝牙样板程序中增加UART功能。
首先是串口初始化,串口初始化可以使用simple_uart.c提供的simple_uart_config()函数,但这是不带中断的,还需要自己编写一个UART0_IRQHandler()中断处理函数并做相应的配置。
如果只是简单的打印调试信息的话可以使用这种方式,这种方式也是单片机常见的写法。
但这里我们不打算使用这个接口,而使用app_uart_fifo.c中的app_uart_init()函数来做初始化,这里也可以使用宏APP_UART_FIFO_INIT。
uart部分代码如下:
#include <stdio.h>
#include <nrf51.h>
#include <app_uart.h>
#include <nrf51_bitfields.h>
#include <boards.h>
#include "uart.h"
#define UART_RX_BUF_SIZE 256
#define UART_TX_BUF_SIZE 256
void uart_event_handler(app_uart_evt_t *event)
{
uint8_t tmp;
switch (event->evt_type) {
case APP_UART_DATA_READY:
app_uart_get(&tmp);
printf("%c", tmp);
break;
case APP_UART_FIFO_ERROR:
break;
case APP_UART_COMMUNICATION_ERROR:
break;
default:
break;
}
}
void uart_init(void)
{
uint32_t err_code;
app_uart_comm_params_t comm_params = {
RX_PIN_NUMBER,
TX_PIN_NUMBER,
0,
0,
APP_UART_FLOW_CONTROL_DISABLED,
false,
UART_BAUDRATE_BAUDRATE_Baud115200
};
APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_event_handler,
APP_IRQ_PRIORITY_HIGH,
err_code);
APP_ERROR_CHECK(err_code);
}
int fputc(int c, FILE *stream)
{
return app_uart_put((uint8_t)c);
}
这部分代码主要有两部分:一是串口初始化部分,二是串口事件回调函数部分。
大家也可以去看一下app_uart_fifo.c中的代码,根据名字来看串口的发送和接收都有一个fifo,我们只需要配置这个fifo的大小就可以了。在app_uart_fifo.c中也有一个中断处理函数UART0_IRQHandler(),发送和接收都使用的中断方式,当接收到一个数据的时候会调用这里的uart_event_handler()这个事件回调函数,并发送事件消息APP_UART_DATA_READY。
在uart_event_handler()函数中,我们为了验证接收到的数据是否正确,在接收到数据的同时也把这个数据给打印出来了。
再来说printf函数,这是一个系统库函数,要使用这个函数,首先得实现fputc()函数,然后还需要在Keil中勾选Use MicroLIB库,配置如下:
好了,在main()函数中我们只需要调用uart_init()函数做初始化,然后就可以使用printf()来打印调试信息了,main()函数部分如下:
int main(void)
{
// Initialize
uart_init();
leds_init();
timers_init();
gpiote_init();
buttons_init();
ble_stack_init();
scheduler_init();
gap_params_init();
advertising_init();
services_init();
conn_params_init();
sec_params_init();
printf("Initialize end\r\n");
// Start execution
timers_start();
advertising_start();
// Enter main loop
for (;;)
{
app_sched_execute();
power_manage();
}
}