这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» MCU» 瑞萨RA0单片机连载之四移植面向对象之UART驱动

共1条 1/1 1 跳转至

瑞萨RA0单片机连载之四移植面向对象之UART驱动

助工
2024-05-16 22:08:41 打赏

串口是单片机最常用的外设之一。本次创建面向对象来移植UART的驱动。

【学习例程】百问网的面向对象的这UART驱动,源代码为百问网的RA6M5的驱动,我这里做了细小的改动而实现快速的驱动。

【创建工程】

在上一篇瑞萨RA0单片机连载之三基于面向对象的LED灯-电子产品世界论坛 (eepw.com.cn)的基础上添加串口的驱动。

1、本次驱动选用的驱动的串口为r_sau_uart0,配置的IO为P100,P101为TX与RX。打开RASC,添加uart0

image.png

添回串口回调函数为sau_uart_callback。并生成工程。

2、移植dev_uart.c/h、drv_uart.c/h到工程中:

image.png

3、其代码dev_uart.c如下:

#include "dev_uart.h" #include  #include  #include  #include  static struct UartDev *gHeadUartDev; void UartDevicesRegister(void) { UartDevicesCreate(); UartDeviceList(); } void UartDeviceInsert(struct UartDev *ptdev) { if(NULL == gHeadUartDev) gHeadUartDev = ptdev; else { ptdev->next = gHeadUartDev; gHeadUartDev = ptdev; } } struct UartDev *UartDeviceFind(const char *name) { struct UartDev *ptdev = gHeadUartDev; while(ptdev) { if(strstr(ptdev->name, name)) { return ptdev; } ptdev = ptdev->next; } return NULL; } void UartDeviceList(void) { struct UartDev *ptdev = gHeadUartDev; printf("\r\nUart Device List:\r\n"); while(ptdev) { printf("\t%s\r\n", ptdev->name); ptdev = ptdev->next; } printf("\r\n"); }

其代码dev_uart.h如下:

/* * dev_uart.h * * Created on: 2023?4?13? * Author: slhuan */ #ifndef __DEV_UART_H #define __DEV_UART_H typedef struct UartDev{ char *name; unsigned char channel; int (*Init)(struct UartDev *ptdev); int (*Write)(struct UartDev *ptdev, unsigned char * const buf, unsigned int length); int (*Read)(struct UartDev *ptdev, unsigned char *buf, unsigned int length); struct UartDev *next; }UartDevice; void UartDevicesRegister(void); void UartDeviceInsert(struct UartDev *ptdev); struct UartDev *UartDeviceFind(const char *name); void UartDeviceList(void); #endif /* __DEV_UART_H */

drv_uart.c代码如下:


/* * drv_uart.c * * Created on: 2023年3月30日 * Author: slhuan */ #include "drv_uart.h" #include  #include "hal_data.h" #include  static void UART0WaitTxCplt(void); static void UART0WaitRxCplt(void); static int UARTDrvInit(struct UartDev *ptdev); static int UARTDrvRead(struct UartDev *ptdev, unsigned char *buf, unsigned int length); static int UARTDrvWrite(struct UartDev *ptdev, unsigned char * const buf, unsigned int length); static volatile bool gUart0TxCplt = false; static volatile bool gUart0RxCplt = false; static struct UartDev gLogDevice = { .name = "Log", .channel = 0, .Init = UARTDrvInit, .Read = UARTDrvRead, .Write = UARTDrvWrite, .next = NULL }; void UartDevicesCreate(void) { UartDeviceInsert(&gLogDevice); gLogDevice.Init(&gLogDevice); } static int UARTDrvInit(struct UartDev *ptdev) { if(NULL == ptdev) return -EINVAL; switch(ptdev->channel) { case 0: { fsp_err_t err = g_uart0.p_api->open(g_uart0.p_ctrl, g_uart0.p_cfg); assert(FSP_SUCCESS == err); break; } case 1:case 2: case 3:case 4:case 5: case 6: { break; } case 7: case 8:case 9: break; default:break; } return ESUCCESS; } static int UARTDrvWrite(struct UartDev *ptdev, unsigned char * const buf, unsigned int length) { if(NULL == ptdev) return -EINVAL; if(NULL == buf) return -EINVAL; if(0 == length) return -EINVAL; switch(ptdev->channel) { case 0: { fsp_err_t err = g_uart0.p_api->write(g_uart0.p_ctrl, buf, length); assert(FSP_SUCCESS == err); UART0WaitTxCplt(); break; } case 1:case 2: case 3:case 4:case 5: case 6: { break; } case 7: case 8:case 9: break; default:break; } return ESUCCESS; } static int UARTDrvRead(struct UartDev *ptdev, unsigned char *buf, unsigned int length) { if(NULL == ptdev) return -EINVAL; if(NULL == buf) return -EINVAL; if(0 == length) return -EINVAL; switch(ptdev->channel) { case 0: { fsp_err_t err = g_uart0.p_api->read(g_uart0.p_ctrl, buf, length); assert(FSP_SUCCESS == err); UART0WaitRxCplt(); break; } case 1:case 2: case 3:case 4:case 5: case 6: { break; } case 7: case 8:case 9: break; default:break; } return (int)length; } void sau_uart_callback(uart_callback_args_t * p_args) { switch(p_args->event) { case UART_EVENT_RX_COMPLETE: { gUart0RxCplt = true; break; } case UART_EVENT_TX_COMPLETE: { gUart0TxCplt = true; break; } case UART_EVENT_RX_CHAR: { break; } case UART_EVENT_ERR_PARITY:case UART_EVENT_ERR_FRAMING: case UART_EVENT_ERR_OVERFLOW:case UART_EVENT_BREAK_DETECT: case UART_EVENT_TX_DATA_EMPTY: break; default:break; } } static void UART0WaitTxCplt(void) { while(!gUart0TxCplt); gUart0TxCplt = false; } static void UART0WaitRxCplt(void) { while(!gUart0RxCplt); gUart0RxCplt = false; }

这里我们需要修改的地方就是对源码修改UART0的自几回调函数以及

switch(ptdev->channel)

drv_uart.h

/* * drv_uart.h * * Created on: 2023年4月13日 * Author: slhuan */ #ifndef __DRV_UART_H #define __DRV_UART_H #define UART_DEVICE_NAME_MAX_LENGTH (16) #define UART_TOTAL_CHANNELS (10) #define UART_RECEIVE_BUFFER_SIZE (1024) void UartDevicesCreate(void); #endif /* __DRV_UART_H */

到此为止,我们的驱动就移植完毕了。

测试代码:

image.png

实验效果,编译下载程序到开发板后,开机打印出初始化的LOG

image.png

【总结】

我们实现了面向对象的UART的移植,从RA6M5的工程中移植过来,只需要修改少量的代码就可以实现面向对象的移植。




关键词: 刘工爱评测之瑞萨RA0单片机 瑞萨RA0 单片机

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]