【Telink - 泰凌 TL322X 开发板】+串口发送接收测试
串口是基本的常用外设,本次来试试开发板的串口输入输出功能。首先选择串口工程例子。
!(//m.qjumbo.com/forum/data/attachment/forum/202606/27/234105voxsobdwyomwybhm.png)
例子是是兼容多款开发板的,代码看着比较复杂,我精简了一下,去掉了无用的部分。
关于串口部分的一些API调用可以参口这里:(https://doc.telink-semi.cn/doc/zh/software/res/sdk/driver/driver_sdk_cn/#uart)
!(//m.qjumbo.com/forum/data/attachment/forum/202606/27/235250nwsens3u1m1m6ejs.png)
```
typedef struct fifo_buffer_t
{
volatile uint32_t read_i;
volatile uint32_t write_i;
uint8_t buff;
}fifo_buffer_t;
typedef struct shell_uart_buffer_t
{
fifo_buffer_t tx;
fifo_buffer_t rx;
volatile uint32_t tx_cpl: 1;
}shell_uart_buffer_t;
shell_uart_buffer_tg_shell_uart=
{
.tx.read_i = 0,
.tx.write_i = 0,
.rx.read_i = 0,
.rx.write_i = 0,
.tx_cpl = 0,
};
uint8_tuart_send_buff;
void uart_get_data_send(void)
{
int n,m;
for(n=0;n<128;n++)
{
if(g_shell_uart.tx.read_i != g_shell_uart.tx.write_i)
{
uart_send_buff = g_shell_uart.tx.buff;
g_shell_uart.tx.read_i &= 0x1ff; //256Byte
}else break;
}
if(n)
{
g_shell_uart.tx_cpl = 1;
for (m = 0; m < n; m++)
{
uart_send_byte(UART_MODULE_SEL, uart_send_buff);
}
g_shell_uart.tx_cpl = 0;
}
}
void uart_send_char(uint8_t ch)
{
while(((g_shell_uart.tx.write_i+1)&0x1ff) == g_shell_uart.tx.read_i)
{
//fifo buffer full
if((g_shell_uart.tx_cpl == 0))
{
uart_get_data_send();
}
}
g_shell_uart.tx.buff = ch;
g_shell_uart.tx.write_i &= 0x1ff;//256Byte
if((g_shell_uart.tx_cpl == 0))
{
uart_get_data_send();
}
}
uint8_t USART_Flush(void)
{
if(g_shell_uart.tx_cpl == 0)
{
uart_get_data_send();
return 0;
}
return 1;
}
uint8_t USART_PutChar(uint8_t ch)
{
uart_send_char(ch);
return 0;
}
uint8_t USART_GetChar(uint8_t *ch)
{
if(g_shell_uart.rx.read_i != g_shell_uart.rx.write_i)
{
*ch = g_shell_uart.rx.buff;
g_shell_uart.rx.read_i &= 0x1ff; //256Byte
return 0;
}
return 1;
}
uint32_t USART_Flush_Rxbuff(void)
{
uint32_t len = 0;
while(g_shell_uart.rx.read_i != g_shell_uart.rx.write_i)
{
USART_PutChar(g_shell_uart.rx.buff);
len++;
}
return len;
}
int USART_PutStr(const char* str, uint32_t len)
{
while(len --) uart_send_char(*str++);
return 0;
}
int USART_GetStr(char* str, uint32_t len)
{
uint32_t rlen = 0;
for(uint32_t i=0;i<len;i++)
{
if(g_shell_uart.rx.read_i != g_shell_uart.rx.write_i)
{
str = g_shell_uart.rx.buff;
g_shell_uart.rx.read_i &= 0x1ff;
}
}
return rlen;
}
void user_init(void)
{
unsigned short div= 0;
unsigned charbwpc = 0;
gpio_function_en(LED1);
gpio_output_en(LED1); //enable output
gpio_input_dis(LED1); //disable input
gpio_function_en(LED2);
gpio_output_en(LED2); //enable output
gpio_input_dis(LED2); //disable input
gpio_function_en(LED3);
gpio_output_en(LED3); //enable output
gpio_input_dis(LED3); //disable input
gpio_function_en(LED4);
gpio_output_en(LED4); //enable output
gpio_input_dis(LED4); //disable input
uart_hw_fsm_reset(UART_MODULE_SEL);
uart_set_pin(UART_MODULE_SEL, UART0_TX_PIN, UART0_RX_PIN);
uart_cal_div_and_bwpc(115200, sys_clk.pclk * 1000 * 1000, &div, &bwpc);
uart_init(UART_MODULE_SEL, div, bwpc, UART_PARITY_NONE, UART_STOP_BIT_ONE);
uart_tx_irq_trig_level(UART_MODULE_SEL, 0);
uart_rx_irq_trig_level(UART_MODULE_SEL, 1);
uart_set_irq_mask(UART_MODULE_SEL, UART_RX_IRQ_MASK | UART_ERR_IRQ_MASK);
uart_set_rx_timeout_with_exp(UART_MODULE_SEL, bwpc, 12, UART_BW_MUL2, 0);
uart_set_irq_mask(UART_MODULE_SEL, UART_RXDONE_MASK);
plic_interrupt_enable(IRQ_UART0);
core_interrupt_enable();
}
void main_loop(void)
{
if(g_shell_uart.rx.read_i != g_shell_uart.rx.write_i)
{
uart_send_char(g_shell_uart.rx.buff);
g_shell_uart.rx.read_i &= 0x1ff; //256Byte
}
USART_Flush();
}
_attribute_ram_code_sec_ void uart0_irq_handler(void)
{
if (uart_get_irq_status(UART_MODULE_SEL, UART_RX_ERR)) {
uart_clr_irq_status(UART_MODULE_SEL, UART_RXBUF_IRQ_STATUS); // it will clear rx_fifo,clear hardware pointer and rx_err_irq ,rx_buff_irq,so it won't enter rx_buff_irq interrupt.
}
if (uart_get_irq_status(UART_MODULE_SEL, UART_RXBUF_IRQ_STATUS)) {
gpio_set_high_level(LED3);
unsigned char fifo_cnt = uart_get_rxfifo_num(UART_MODULE_SEL);
for (unsigned char k = 0; k < fifo_cnt; k++)
{
if(((g_shell_uart.rx.write_i+1)&0x1ff) != g_shell_uart.rx.read_i)
{
g_shell_uart.rx.buff = uart_read_byte(UART_MODULE_SEL);
g_shell_uart.rx.write_i &= 0x1ff;//256Byte
}
}
}
if (uart_get_irq_status(UART_MODULE_SEL, UART_RXDONE_IRQ_STATUS)) {
gpio_set_high_level(LED4);
unsigned char fifo_cnt = uart_get_rxfifo_num(UART_MODULE_SEL);
for (unsigned char k = 0; k < fifo_cnt; k++)
{
if(((g_shell_uart.rx.write_i+1)&0x1ff) != g_shell_uart.rx.read_i)
{
g_shell_uart.rx.buff = uart_read_byte(UART_MODULE_SEL);
g_shell_uart.rx.write_i &= 0x1ff;//256Byte
}
}
uart_clr_irq_status(UART_MODULE_SEL, UART_RXDONE_IRQ_STATUS);
}
}
PLIC_ISR_REGISTER(uart0_irq_handler, IRQ_UART0)
```
首先要配置串口引脚。
```
#define UART0_TX_PINGPIO_FC_PD6
#define UART0_RX_PINGPIO_FC_PD7
```
!(//m.qjumbo.com/forum/data/attachment/forum/202606/27/234521duvxubvu8a4899k5.png)
使用NDMA模式通过中断接收串口数据。
!(//m.qjumbo.com/forum/data/attachment/forum/202606/27/234618iepo4sdxinak3ex3.png)
修改之后编译下载。
!(//m.qjumbo.com/forum/data/attachment/forum/202606/27/234725be0ba29ben21iwit.png)
实现的效果就是开发板通过串口收到数据然后转发数据回来。连接USB转串口接口到电脑,可以看到串口号,然后通过串口助手测试串口发送接收效果。
!(//m.qjumbo.com/forum/data/attachment/forum/202606/27/234834qu3j63w7n8jdgjgz.png)
页:
[1]