k210开发板 K210_Kendryte 串口中断

通过Kendryte开发平台,实现k210开发板的串口中断,串口助手发送55 AA 55 55 55 55 led灯亮,发送55 AA AA AA AA AAled灯灭,我使用的是01Studio的开发板,配置了三色灯的蓝灯IO12.

#include <stdio.h>

#include <string.h>

 

#include "fpioa.h"

#include "gpiohs.h"

#include "sysctl.h"

#include "uart.h"

#define CMD_LENTH 4

#define CLOSLIGHT 0x55555555  

#define OPENLIGHT 0xAAAAAAAA

#define UART_NUM UART_DEVICE_3

 

int release_cmd(char *cmd) { //串口命令执行函数

switch (*((int *)cmd)) {

case CLOSLIGHT:

gpiohs_set_pin(3, GPIO_PV_LOW);

break;

case OPENLIGHT:

gpiohs_set_pin(3, GPIO_PV_HIGH);

break;

}

return 0;

}

 

///发送函数

int on_uart_send(void *ctx) {

uint8_t v_uart = *((uint32_t *)ctx) + 1 + 0x30;  //2+1为串口3,0x30转为ASCII

uart_irq_unregister(UART_NUM, UART_SEND);

char *v_send_ok = "Send ok Uart";

uart_send_data(UART_NUM, v_send_ok, strlen(v_send_ok));

uart_send_data(UART_NUM, (char *)&v_uart, 1); //发送串口号

return 0;

}

 

volatile uint32_t recv_flag = 0;

char g_cmd[4];

volatile uint8_t g_cmd_cnt = 0;

//接受函数中断

int on_uart_recv(void *ctx) {

char v_buf[8];

int ret = uart_receive_data(UART_NUM, v_buf, 8);

for (uint32_t i = 0; i < ret; i++) {

if (v_buf[i] == 0x55 && (recv_flag == 0 || recv_flag == 1)) {  //第一个字节匹配

recv_flag = 1;

continue;

} else if (v_buf[i] == 0xAA && recv_flag == 1) {//第二个字节匹配

recv_flag = 2;

g_cmd_cnt = 0;

continue;

} else if (recv_flag == 2 && g_cmd_cnt < CMD_LENTH) {//获取控制命令四个字节

g_cmd[g_cmd_cnt++] = v_buf[i];

if (g_cmd_cnt >= CMD_LENTH) {

release_cmd(g_cmd);

recv_flag = 0;

}

continue;

} else {

recv_flag = 0;

}

}

return 0;

}

 

void io_mux_init(void) {

fpioa_set_function(4, FUNC_UART1_RX + UART_NUM * 2); //串口接收

fpioa_set_function(5, FUNC_UART1_TX + UART_NUM * 2); //串口发送

fpioa_set_function(12, FUNC_GPIOHS3); // led

}

 

int main() {

io_mux_init(); //串口引脚配置

plic_init(); //中断初始化

sysctl_enable_irq(); //使能中断

 

gpiohs_set_drive_mode(3, GPIO_DM_OUTPUT); // led初始化

gpio_pin_value_t value = GPIO_PV_HIGH;

gpiohs_set_pin(3, value);

 

uart_init(UART_NUM); //串口初始化

uart_configure(UART_NUM, 115200, 8, UART_STOP_1, UART_PARITY_NONE);

 

uart_set_receive_trigger(UART_NUM, UART_RECEIVE_FIFO_8); //接收中断

uart_irq_register(UART_NUM, UART_RECEIVE, on_uart_recv, NULL, 2);

 

uart_set_send_trigger(UART_NUM, UART_SEND_FIFO_0); //发送中断

uint32_t v_uart_num = UART_NUM;

uart_irq_register(UART_NUM, UART_SEND, on_uart_send, &v_uart_num, 2);

 

char *hel = {"hello world!\n"};

uart_send_data(UART_NUM, hel, strlen(hel));

 

while (1)

;

}

 

/// ///uart dma发送接收

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

 

#include "fpioa.h"

#include "gpiohs.h"

#include "sysctl.h"

#include "uart.h"

 

#define CMD_LENTH 4

 

#define CLOSLIGHT 0x55555555

 

#define OPENLIGHT 0xAAAAAAAA

 

#define UART_NUM UART_DEVICE_1

 

uint32_t recv_buf[48];

 

#define RECV_DMA_LENTH 6

 

volatile uint32_t recv_flag = 0;

 

char g_cmd[4];

 

volatile uint8_t g_cmd_cnt = 0;

 

int release_cmd(char *cmd)

 

{

switch (*((int *)cmd)) {

case CLOSLIGHT:

 

gpiohs_set_pin(3, GPIO_PV_LOW);

 

break;

 

case OPENLIGHT:

 

gpiohs_set_pin(3, GPIO_PV_HIGH);

 

break;

}

 

return 0;

}

 

volatile uint32_t g_uart_send_flag = 0;

 

int uart_send_done(void *ctx) //发送完成

{

g_uart_send_flag = 1;

return 0;

}

 

int uart_recv_done(void *ctx) //接受完成

{

uint32_t *v_dest = ((uint32_t *)ctx) + RECV_DMA_LENTH;

if (v_dest >= recv_buf + 48) v_dest = recv_buf;

uart_data_t data = (uart_data_t) //重新初始化dma接收中断

{

.rx_channel = DMAC_CHANNEL1,

.rx_buf = v_dest,

.rx_len = RECV_DMA_LENTH,

.transfer_mode = UART_RECEIVE,

};

 

plic_interrupt_t irq = (plic_interrupt_t){

.callback = uart_recv_done,

.ctx = v_dest,

.priority = 2,

};

 

uart_handle_data_dma(UART_NUM, data, &irq);

uint32_t *v_buf = (uint32_t *)ctx;

 

for (uint32_t i = 0; i < RECV_DMA_LENTH; i++) {

if (v_buf[i] == 0x55 && (recv_flag == 0 || recv_flag == 1)) {

recv_flag = 1;

continue;

} else if (v_buf[i] == 0xAA && recv_flag == 1) {

recv_flag = 2;

g_cmd_cnt = 0;

continue;

}

 

else if (recv_flag == 2 && g_cmd_cnt < CMD_LENTH) {

g_cmd[g_cmd_cnt++] = v_buf[i];

if (g_cmd_cnt >= CMD_LENTH) {

release_cmd(g_cmd);

recv_flag = 0;

}

continue;

}

 

else {

recv_flag = 0;

}

}

 

return 0;

}

 

void io_mux_init(void) //串口引脚配置

{

fpioa_set_function(4, FUNC_UART1_RX + UART_NUM * 2);

fpioa_set_function(5, FUNC_UART1_TX + UART_NUM * 2);

fpioa_set_function(12, FUNC_GPIOHS3); // led

}

 

int main(void) {

io_mux_init(); //串口引脚配置

dmac_init(); //直接内存访问

plic_init(); //中断

sysctl_enable_irq(); //中断使能

gpiohs_set_drive_mode(3, GPIO_DM_OUTPUT); // led初始化为高电平

gpiohs_set_pin(3, GPIO_PV_HIGH);

 

uart_init(UART_NUM); //串口初始化

uart_configure(UART_NUM, 115200, 8, UART_STOP_1,

UART_PARITY_NONE); //设置波特率,数据位,停止位,奇偶校验

 

uint8_t *hel = {"hello!\n"};

uint32_t *v_tx_buf = malloc(sizeof(hel) * sizeof(uint32_t)); //申请内存

 

for (uint32_t i = 0; i < strlen(hel); i++) //存放字符串

{

v_tx_buf[i] = hel[i];

}

 

uart_data_t data = (uart_data_t) //创建结构体发送dma

{

.tx_channel = DMAC_CHANNEL0, //通道

.tx_buf = v_tx_buf, //发送的数据

.tx_len = strlen(hel), //长度

.transfer_mode = UART_SEND, //模式

};

 

plic_interrupt_t irq = (plic_interrupt_t){

.callback = uart_send_done, //回调函数

.ctx = NULL,

.priority = 1, //优先级

};

 

uart_handle_data_dma(UART_NUM, data, &irq); //串口dma 发送初始化

 

uart_data_t v_rx_data = (uart_data_t) //接受dma结构体

{

.rx_channel = DMAC_CHANNEL1, //通道

.rx_buf = recv_buf, //收到数据

.rx_len = RECV_DMA_LENTH, //接受长度

.transfer_mode = UART_RECEIVE, //模式

};

 

plic_interrupt_t v_rx_irq = (plic_interrupt_t){

.callback = uart_recv_done, //接受数据回调函数

.ctx = recv_buf,

.priority = 2,

};

 

uart_handle_data_dma(UART_NUM, v_rx_data,

&v_rx_irq); //串口dma 接收中断初始化

 

while (1) {

sleep(1);

uart_handle_data_dma(UART_NUM, data, &irq); //不停的发送hello

g_uart_send_flag = 1;

}

}

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chilian12321

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值