【瑞萨RA-eco-RA6M4评测】实现串口发送接收shell
今天学习RA6M4的串口发送接收功能。实现shell命令测试。开发板上有个USB转串口接口,这次就用这个测试串口发送接收数据。!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/233414shyuuyyouzuctzyh.png)
根据电路图,我们知道了串口使用引脚为P109和P110。下面打开RASC软件配置串口功能。利用上次的例子工程,我们继续添加串口外设。
先配置P109和P110为SCI9的串口。
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/233928ny1x8778tutrhn7e.png)
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/234018sqxg6zx6m22cd2xm.png)
然后添加串口通信功能配置。这里配置串口为SCI的第9通道,115200波特率。
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/233821ap5mq5ia6ua55555.png)
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/234125pdnrqilpq3tzikz9.png)
在组件里面添加串口外设驱动。
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/234326gwtx7tx17y4vbfwb.png)
最后生成keil代码工程。
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/234415pvmdwm9nwyztnakd.png)
添加串口发送接收函数驱动。
```
/******************************************************************************
* Include files
******************************************************************************/
#include "main.h"
#include "shell_uart.h"
#include "hal_data.h"
#include<RTE_Components.h>
#undef __USE_EVENT_RECORDER__
#if defined(RTE_Compiler_EventRecorder) || defined(RTE_CMSIS_View_EventRecorder)
# define __USE_EVENT_RECORDER__1
#endif
#if __USE_EVENT_RECORDER__
# include <EventRecorder.h>
# include "EventRecorderConf.h"
#endif
typedef struct ra6m4_uart_para_t
{
sci_uart_instance_ctrl_t *_uart;
uint32_t channel;
uint8_t uart_recv_buff;
uint8_t uart_send_buff;
}ra6m4_uart_para_t;
ra6m4_uart_para_t ra6m4_uart_p;
shell_uart_buffer_tg_shell_uart;
//RS485 CTRL GPIO
#define RS485_DISABLE_UART_SEND(i) //recv start status //TE485 =0;RE485=1; //RS485,L发送关闭,H接收使能
#define RS485_ENABLE_UART_SEND(i) //send start status //TE485 =1;RE485=0; //RS485,H发送使能,L接收使能
static void uart_get_data_send(uint8_t index)
{
uint32_t i;
//
for(i=0;i<128;i++)
{
if(g_shell_uart.tx.read_i != g_shell_uart.tx.write_i)
{
((ra6m4_uart_para_t *)g_shell_uart.userdata)->uart_send_buff = g_shell_uart.tx.buff.tx.read_i++];
g_shell_uart.tx.read_i &= (UART_FIFO_BUFF_LEN-1); //256Byte
}else break;
}
if(i)
{
RS485_ENABLE_UART_SEND(index);
g_shell_uart.tx_cpl = 1;
//R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
R_SCI_UART_Write(((ra6m4_uart_para_t *)g_shell_uart.userdata)->_uart,
((ra6m4_uart_para_t *)g_shell_uart.userdata)->uart_send_buff,i);
}
}
uint8_t uart_flush_data(uint8_t index)
{
if(g_shell_uart.tx_cpl == 0)
{
uart_get_data_send(index);
}
if(g_shell_uart.tx.read_i != g_shell_uart.tx.write_i) return 1;
else return g_shell_uart.tx_cpl;
}
uint8_t uart_send_char(uint8_t index, uint8_t ch)
{
while(((g_shell_uart.tx.write_i+1) & (UART_FIFO_BUFF_LEN-1)) == g_shell_uart.tx.read_i)
{
//fifo buffer full
if(!(g_shell_uart.tx_cpl))
{
uart_get_data_send(index);
}
}
g_shell_uart.tx.buff.tx.write_i++] = ch;
g_shell_uart.tx.write_i &= (UART_FIFO_BUFF_LEN-1);//256Byte
return uart_flush_data(index);
}
uint8_t uart_recv_char(uint8_t index, uint8_t *ch)
{
if(g_shell_uart.rx.read_i != g_shell_uart.rx.write_i)
{
*ch = g_shell_uart.rx.buff.rx.read_i++];
g_shell_uart.rx.read_i &= (UART_FIFO_BUFF_LEN-1); //256Byte
return 0;
}
return 1;
}
int uart_send_str(uint8_t index, const char* str, uint32_t len)
{
char *s= (char*)str;
int sl = (int)len;
while(len --) uart_send_char(index, *s++);
return sl;
}
int uart_recv_str(uint8_t index, const char* str, uint32_t len)
{
uint8_t *s= (uint8_t *)str;
int rlen = 0;
for(uint32_t i=0;i<len;i++)
{
if(0 == uart_recv_char(index, &s))
{
rlen++;
}
}
return rlen;
}
//////////////////////////////////////////////////////////////////////////////
//中断处理
void user_sci_uart9_isr_callback (uart_callback_args_t * p_args)
{
if(p_args->event == UART_EVENT_TX_COMPLETE)
{
for(uint8_t i=0;i<UART_DEV_NUM;i++)
{
if(p_args->channel == ((ra6m4_uart_para_t *)g_shell_uart.userdata)->channel) //shell
{
g_shell_uart.tx_cpl = 0;
uart_get_data_send(i);
}
}
}
if(p_args->event == UART_EVENT_RX_CHAR)
{
for(int i=0;i<UART_DEV_NUM;i++)
{
if(p_args->channel == ((ra6m4_uart_para_t *)g_shell_uart.userdata)->channel) //shell
{
if(((g_shell_uart.rx.write_i+1) & (UART_FIFO_BUFF_LEN-1)) != g_shell_uart.rx.read_i)
{
g_shell_uart.rx.buff.rx.write_i++] = (uint8_t)p_args->data;
g_shell_uart.rx.write_i &= (UART_FIFO_BUFF_LEN-1);//256Byte
}
RS485_DISABLE_UART_SEND(i); //recv start status
}
}
}
}
extern int stdout_putchar (int ch);
#if __USE_EVENT_RECORDER__ == 0
int stdout_putchar (int ch)
{
uart_send_char(UART_SHELL_DEV_INDEX, ch & 0xff);
return ch;
}
int fputc(int ch,FILE *f)
{
uart_send_char(UART_SHELL_DEV_INDEX, ch & 0xff);
return ch;
}
#endif
uint8_t USART_PutChar(uint8_t ch)
{
uart_send_char(UART_SHELL_DEV_INDEX, ch);
return 0;
}
uint8_t USART_GetChar(uint8_t *ch)
{
return uart_recv_char(UART_SHELL_DEV_INDEX, ch);
}
int USART_PutStr(const char* str, uint32_t len)
{
char *s= (char*)str;
int sl = (int)len;
while(len --) uart_send_char(UART_SHELL_DEV_INDEX, *s++);
return sl;
}
int USART_GetStr(const char* str, uint32_t len)
{
uint8_t *s= (uint8_t *)str;
int rlen = 0;
for(uint32_t i=0;i<len;i++)
{
if(0 == uart_recv_char(UART_SHELL_DEV_INDEX, &s))
{
rlen++;
}
}
return rlen;
}
void shell_usart_init(void)
{
ra6m4_uart_p._uart = &g_uart0_ctrl;
ra6m4_uart_p.channel = 9;
g_shell_uart.tx.read_i = 0;
g_shell_uart.tx.write_i = 0;
g_shell_uart.rx.read_i = 0;
g_shell_uart.rx.write_i = 0;
g_shell_uart.tx_cpl = 0;
g_shell_uart.userdata = &ra6m4_uart_p;
#if __USE_EVENT_RECORDER__
EventRecorderInitialize(0, 1);
#endif
#ifdef UART_SHELL
#if UART_SHELL == 1
userShellInit(); //LETTER_SHELL
#elif UART_SHELL == 2
shell_init(); //NR_MICRO_SHELL
#elif UART_SHELL == 3
// 配置IO操作
shell_io_ops_t io_ops = {
.send = USART_PutStr,
};
lsy_shell_init(&io_ops); //LSY_SHELL
#else
#endif
#endif
/* 启动非阻塞式读取接收数据 */
for(int i=0;i<UART_DEV_NUM;i++)
{
RS485_DISABLE_UART_SEND(i); //recv start status
}
}
void shell_usart_loop(void)
{
uint8_t ch;
if(0 == uart_recv_char(UART_SHELL_DEV_INDEX, &ch))
{
#ifdef UART_SHELL
#if UART_SHELL == 1
shellHandler(&shell, ch); //letter shell
#elif UART_SHELL == 2
shell(ch);
#elif UART_SHELL == 3
lsy_shell_input(ch);
#else
USART_PutChar(ch);
#endif
#endif
}
//将串口FIFO内数据继续发送
for(uint8_t i=0;i<UART_DEV_NUM;i++)
{
uart_flush_data(i);
}
}
```
将串口输出重定向到printf输出。
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/234608gqag7mzgg07b3w7m.png)
继续添加nr_micro_shell代码,实现shell命令功能。
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/234751poo4vk9qukpe3zss.png)
最终编译下载就可以看到串口输出了。
!(https://www.eefocus.com/forum/data/attachment/forum/202608/05/234840iqacxwgikxc5viav.png)
页:
[1]