NRF52832开发:普通串口驱动

来源:互联网 发布:革委会 知乎 编辑:程序博客网 时间:2024/04/30 03:40

NRF52832开发:普通串口驱动


本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

 

环境:

开发环境:MDK5.23


说明:
编写NRF52832普通串口的驱动,发送是查询方式,接收采用中断方式。接收时每20ms处理一次。


源代码:

drv_uart.h

/*** Copyright (c), 2015-2025* @file drv_uart.h* @brief 串口驱动层头文件* @author jdh* @email jdh821@163.com* @date 2017/7/4* @verbatim * 硬件连接说明* 电路标号单片机引脚* USART1_TX       P0.08* USART1_RX       P0.06* @endverbatim */#ifndef _DRV_UART_H_#define _DRV_UART_H_/**********************************************************************头文件**********************************************************************/#include "stdint.h"/**********************************************************************宏定义**********************************************************************//*** @brief 波特率值*/#define BAUD12000x0004F000#define BAUD24000x0009D000#define BAUD48000x0013B000#define BAUD96000x00275000#define BAUD144000x003B000#define BAUD192000x004EA000#define BAUD288000x0075F000#define BAUD384000x009D5000#define BAUD576000x00EBF000#define BAUD768000x013A9000#define BAUD1152000x01D7E000#define BAUD2304000x03AFB000#define BAUD2500000x04000000#define BAUD4608000x075F7000#define BAUD9216000x0EBED000#define BAUD1M0x10000000/*** @brief 默认的波特率*/#define DEFAULT_BAUDBAUD1M/*** @brief IO口*/#define PIN_UART_TX6#define PIN_UART_RX8/**********************************************************************函数**********************************************************************//*** @brief 初始模块*/void drv_uart_init(void);/*** @brief 串口发送数据* @param data:发送数据存放地址* @param size:发送数据字节数*/void drv_uart_tx(uint8_t *data, uint16_t size);/*** @brief 处理接收完成中断* @retval 接收到的字节*/uint8_t drv_uart_deal_irq_rx_end(void);#endif

drv_uart.c

/*** Copyright (c), 2015-2025* @file drv_uart.c* @brief 串口驱动层主文件* @author jdh* @email jdh821@163.com* @date 2017/7/4*//**********************************************************************头文件**********************************************************************/#include "drv_uart.h"#include "drv_gpio.h"#include "nrf.h"#include "drv_irq_priority.h"/**********************************************************************静态函数**********************************************************************/static void init_io(void);static void init_uart(void);static void enable_interrupt(void);/**********************************************************************函数**********************************************************************//*** @brief 初始模块*/void drv_uart_init(void){init_io();init_uart();}static void init_io(void){drv_gpio_config_output(PIN_UART_TX);drv_gpio_set_high(PIN_UART_TX);drv_gpio_config_input(PIN_UART_RX, GPIO_NOPULL);}static void init_uart(void){NRF_UART0->BAUDRATE = DEFAULT_BAUD;NRF_UART0->PSELTXD = PIN_UART_TX;NRF_UART0->PSELRXD = PIN_UART_RX;enable_interrupt();// 使能串口NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled;NRF_UART0->TASKS_STARTTX = 1;NRF_UART0->TASKS_STARTRX = 1;}static void enable_interrupt(void){NRF_UART0->EVENTS_RXDRDY = 0;NRF_UART0->INTENSET = UART_INTENSET_RXDRDY_Enabled << UART_INTENSET_RXDRDY_Pos;NVIC_SetPriority(UART0_IRQn, IRQ_PRIORITY_LOW);    NVIC_ClearPendingIRQ(UART0_IRQn);    NVIC_EnableIRQ(UART0_IRQn);}/*** @brief 串口发送数据* @param data:发送数据存放地址* @param size:发送数据字节数*/void drv_uart_tx(uint8_t *data, uint16_t size){for (int i = 0; i < size; i++){NRF_UART0->TXD = data[i];while (NRF_UART0->EVENTS_TXDRDY == 0);NRF_UART0->EVENTS_TXDRDY = 0;}}/*** @brief 处理接收完成中断* @retval 接收到的字节*/uint8_t drv_uart_deal_irq_rx_end(void){NRF_UART0->EVENTS_RXDRDY = 0;return NRF_UART0->RXD;}


console.h

/*** Copyright (c), 2015-2025* @file deal_console.h* @brief 控制台接收数据处理模块头文件* @author jdh* @date 2016/7/28* @update 2016/8/8* @update 2017/10/20*/#ifndef _DEAL_CONSOLE_H_#define _DEAL_CONSOLE_H_/**********************************************************************头文件**********************************************************************/#include "world.h"#include "console.h"/**********************************************************************函数**********************************************************************//*** @brief 接收处理* @param rx:接收数据*/void deal_console_rx(T_Buffer rx);#endif


console.c

/*** Copyright (c), 2015-2025* @file console.c* @brief 控制台主文件* @author jdh* @date 2015/3/16* @update 2015/6/30* @update 2015/8/12* @update 2016/10/25* @update 2017/10/20*//**********************************************************************头文件**********************************************************************/#include "console.h"/**********************************************************************宏定义**********************************************************************//*** @brief 观察者最大个数*/#define MAX_OBSERVER10/**********************************************************************静态变量**********************************************************************//*** @brief pt任务变量*/static struct pt Pt_Task;/*** @brief 接收数据观察者列表*/static T_Console_Rx Observer[MAX_OBSERVER];static uint8_t Len_Observer = 0;/*** @brief 接收数据*/static T_Buffer Buffer_Rx;static bool Is_Rx = false;/**********************************************************************静态函数**********************************************************************/static int pt_run(struct pt *pt);static void notify_observer(void);/**********************************************************************函数**********************************************************************//*** @brief 模块载入*/void console_load(void){PT_INIT(&Pt_Task);}/*** @brief 模块运行*/void console_run(void){pt_run(&Pt_Task);}static int pt_run(struct pt *pt){static T_Time time_delay;PT_BEGIN(pt);time_delay = get_time();PT_WAIT_UNTIL(pt,sub_time_safe(get_time(),&time_delay) > INTERVAL_CONSOLE * 1000);if (Is_Rx){Is_Rx = false;}else{if (Buffer_Rx.len > 0){notify_observer();Buffer_Rx.len = 0;}}PT_END(pt);}static void notify_observer(void){for (int i = 0;i < Len_Observer;i++){Observer[i](Buffer_Rx);}}/*** @brief 注册观察者* @param function:观察者函数指针*/void console_register_observer(T_Console_Rx function){Observer[Len_Observer++] = function;}/*** @brief 串口中断处理函数* @param data:接收数据存放地址*/void console_irq_handler(void)                              {   Buffer_Rx.buf[Buffer_Rx.len++] = drv_uart_deal_irq_rx_end();Is_Rx = true;} /*** @brief 向控制台发送数据* @param data:发送数据存放地址* @param size:发送数据字节数*/void console_tx(uint8_t *data,uint16_t size){drv_uart_tx(data, size);}


中断处理函数:

void UARTE0_UART0_IRQHandler(void){console_irq_handler();}


测试用例:

deal_console.h:

/*** Copyright (c), 2015-2025* @file deal_console.h* @brief 控制台接收数据处理模块头文件* @author jdh* @date 2016/7/28* @update 2016/8/8* @update 2017/10/20*/#ifndef _DEAL_CONSOLE_H_#define _DEAL_CONSOLE_H_/**********************************************************************头文件**********************************************************************/#include "world.h"#include "console.h"/**********************************************************************函数**********************************************************************//*** @brief 接收处理* @param rx:接收数据*/void deal_console_rx(T_Buffer rx);#endif


deal_console.c:

/*** Copyright (c), 2015-2025* @file deal_console.c* @brief 控制台接收数据处理模块主文件* @date 2016/7/28* @upate 2016/7/29* @upate 2016/8/1* @upate 2016/8/8* @upate 2016/8/10* @upate 2016/8/11* @upate 2016/8/17* @upate 2016/8/18* @update 2016/9/2* @update 2016/9/5* @update 2016/9/12* @update 2016/9/13* @update 2016/9/21* @update 2016/9/23* @update 2016/10/19* @update 2017/10/20* @update 2017/10/23*//**********************************************************************头文件**********************************************************************/#include "deal_console.h"#include "radio_rx.h"/**********************************************************************静态函数**********************************************************************//*** @brief 搜索字符串出现下标* @param src:源字符串* @param dst:目标字符串* @param begin:开始下标* @param num:第几次出现,从1开始* @retval -1:失败,其他:下标*/static int search_string(char *src,char *dst,int begin,int num);/*** @brief 复位基站* @param offset:正文偏移* @param rx:接收数据*/static void deal_cmd_bus_reset(uint16_t offset, T_Buffer rx);/*** @brief 设置接收频点* @param offset:正文偏移* @param rx:接收数据*/static void deal_cmd_bus_set_rx_freq(uint16_t offset, T_Buffer rx);/*** @brief 读取接收频点* @param offset:正文偏移* @param rx:接收数据*/static void deal_cmd_bus_get_rx_freq(uint16_t offset, T_Buffer rx);static void help(void);/**********************************************************************函数**********************************************************************//*** @brief 接收处理* @param rx:接收数据*/void deal_console_rx(T_Buffer rx){uint16_t offset = 0;uint8_t cmd = 0;int result = 0;//读取命令字//复位result = search_string((char *)rx.buf, "RESET", 0, 1);if (result != -1){//处理deal_cmd_bus_reset(result, rx);return;}//设置接收频点result = search_string((char *)rx.buf, "SET_FREQ", 0, 1);if (result != -1){//处理deal_cmd_bus_set_rx_freq(result, rx);return;}//读取接收频点result = search_string((char *)rx.buf, "READ_FREQ", 0, 1);if (result != -1){//处理deal_cmd_bus_get_rx_freq(result, rx);return;}if (rx.len == 1 && rx.buf[0] == 'H'){help();}}/*** @brief 搜索字符串出现下标* @param src:源字符串* @param dst:目标字符串* @param begin:开始下标* @param num:第几次出现,从1开始* @retval -1:失败,其他:下标*/static int search_string(char *src,char *dst,int begin,int num){int i = 0;int j = 0;int len1 = 0;int len2 = 0;int count = 0;if (num == 0){return -1;}len1 = strlen(src);len2 = strlen(dst);if (len1 < len2){return -1;}for (i = begin;i <= len1 - len2;i++){for (j = 0;j < len2;j++){if (src[i + j] != dst[j]){break;}}if (j >= len2){count++;if (count == num){return i;}}}return -1;}/*** @brief 复位基站* @param offset:正文偏移* @param rx:接收数据*/static void deal_cmd_bus_reset(uint16_t offset, T_Buffer rx){//回复console_tx((uint8_t *)"CONFIRM+RESET\r\n", strlen("CONFIRM+RESET\r\n"));//复位NVIC_SystemReset();}/*** @brief 设置接收频点* @param offset:正文偏移* @param rx:接收数据*/static void deal_cmd_bus_set_rx_freq(uint16_t offset, T_Buffer rx){int freq, len;sscanf((char *)rx.buf, "SET_FREQ+%d+%d", &freq, &len);// 判断频率是否正确if (freq < 2360 || freq > 2500){return;}// 判断长度是否正确if (len > 100){return;}//设置接收频点//radio_rx_start(freq, len);radio_rx_stop();radio_rx_start(freq, len);//drv_radio_set_frequency(freq);//drv_radio_set_playload_length(len);//回复console_tx((uint8_t *)"CONFIRM+SET_FREQ\r\n", strlen("CONFIRM+SET_FREQ\r\n"));}/*** @brief 读取接收频点* @param offset:正文偏移* @param rx:接收数据*/static void deal_cmd_bus_get_rx_freq(uint16_t offset, T_Buffer rx){int freq, len;char arr[128] = {0};//模块接收频点freq = drv_radio_get_frequency();len = drv_radio_get_playload_length();//回复sprintf(arr, "SEND_FREQ+%d+%d\r\n", freq, len);console_tx((uint8_t *)arr, strlen(arr));}static void help(void){char log_out[100] = {0};strcpy(log_out,"*******************************************\r\n");console_tx((uint8_t *)log_out,strlen(log_out));strcpy(log_out,"             Sniffer帮助界面            \r\n");console_tx((uint8_t *)log_out,strlen(log_out));sprintf(log_out,"硬件版本:%d 软件版本:%d\r\n", VERSION_HARD, VERSION_SOFT);console_tx((uint8_t *)log_out,strlen(log_out));sprintf(log_out,"H:帮助\r\n");console_tx((uint8_t *)log_out,strlen(log_out));sprintf(log_out,"RESET:复位\r\n");console_tx((uint8_t *)log_out,strlen(log_out));sprintf(log_out,"SET_FREQ:设置频点.例:SET_FREQ+2400\r\n");console_tx((uint8_t *)log_out,strlen(log_out));sprintf(log_out,"READ_FREQ:读取频点\r\n");console_tx((uint8_t *)log_out,strlen(log_out));strcpy(log_out,"*******************************************\r\n");console_tx((uint8_t *)log_out,strlen(log_out));}


在main.c中注册及调用:

int main(void){world_load();spi_load();reg_management_load();test_load();console_load();drv_radio_config(RADIO_TXPOWER_POS4DBM, 2400, RADIO_BAUDRATE_1M, 0x11223344, 14);//// test//radio_tx_stop();//radio_rx_stop();////RADIO_SR.FREQ = 40;//RADIO_SR.LENGTH = 14;//RADIO_SR.STATE = BITS_RADIO_STATE_RX;//radio_rx_start(RADIO_SR.FREQ + BITS_BASE_FREQ, RADIO_SR.LENGTH);// 观察者注册spi_register_observer(reg_management_deal_spi_rx);radio_tx_register_observer(reg_management_deal_radio_tx_events);radio_rx_register_observer(reg_management_deal_radio_rx_events);console_register_observer(deal_console_rx);radio_rx_start(2400, 14);uint8_t arr[28] = {0};while (1){radio_rx_run();console_run();}}


原创粉丝点击