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();}}
阅读全文
0 0
- NRF52832开发:普通串口驱动
- NRF52832开发:GPIO驱动
- 串口驱动开发学习
- 硬件开发----串口驱动
- nrf52832开发环境安装
- BLE开发 Nordic nRF52832(二) BLE简介与虚拟串口传输实现
- 修改s3c440普通串口驱动为485驱动
- S5PV210开发 -- 串口驱动开发
- linux UART串口驱动开发
- linux驱动开发:串口协议
- nRF52832
- nrf52832
- Linux内核修改:将2440串口UART2(红外端口)更成普通串口驱动
- nrf52832 gpio9和10默认是NFC,非普通GPIO
- linux UART串口驱动开发文档
- linux UART串口驱动开发文档
- nRF52832 — 串口BLE例程逐行解析【转载】
- 蓝牙nrf52832的架构和开发
- 从Java代码到字节码(1)
- vue中的class和style
- LSTM模型简介及Tensorflow实现
- Centos7搭建ganglia
- 汇编第四节-第一个程序
- NRF52832开发:普通串口驱动
- 西瓜书《机器学习》课后答案——chapter11_11.1 Relief特征选择算法
- python模糊图片过滤
- ffsdafdsa
- 数据库优化
- 6.12计算输入的正数和
- Name.GetBuffer()会导致CString::left()不起作用
- SpringMVC+Spring+mybatis+redis项目从零开始--Springmvc配置实现
- 保护模式虚拟机使用qemu的snapshot参数引发的惨案