K210学习记录(2)——UART(串口)

发布者:温柔阳光最新更新时间:2022-07-01 来源: csdn关键字:UART  串口 手机看文章 扫描二维码
随时随地手机看文章

0、引言

本系列博客仅作为本人学习K210单片机的学习记录,主要学习其内部资源使用,作为初学者难免有错误之处,如有发现还望指出。


硬件:Sipeed Maix Dock开发板(推荐官方KD233开发板)

软件:Kendryte IDE(基于VS Code 开发)


文档:

Kendryte IDE使用手册

Standalone SDK编程指南


芯片技术规格书

SDK:

Kendryte SDK

MaixPy/drive


1、UART——interrupt

以下代码为官方代码库“kendryte_uart-interrupt-standalone”修改而成,实现的功能为将电脑发送的字符串,在中断回调函数中存入缓存v_buf中,字符串接收完成后,再将v_buf中的数据上传回电脑。管脚配置如下所示

main.c


#include

#include

#include

#include

#include

#include


//UART_NUM位于uart.h中 ,用于定义所使用的串口号

//#define UART_NUM UART_DEVICE_3

uint32_t v_uart_num = UART_NUM;


//打印字符串,通过指针

void uart_print(const char const *str) {

  uart_send_data(UART_NUM, str, strlen(str));

}


//发送中断回调函数(想不到用途)

int on_uart_send(void *ctx) {

  uint8_t v_uart = *((uint32_t *)ctx) + 1 + 0x30;

  //注销中断函数,保证该功能单次使用,否则会陷入局部死循环。

  uart_irq_unregister(UART_NUM, UART_SEND);


  uart_print("Send ok Uartn");                  //测试用

  uart_send_data(UART_NUM, (char *)&v_uart, 1);  //标准发送程序,位于uart.c

  return 0;

}


int main() {

  plic_init();//中断初始化

  sysctl_enable_irq();//开启系统中断

  uart_init(UART_NUM); //初始化配置串口。通道3

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

  //接收中断或 DMA 触发 FIFO 深度,当 FIFO 中的数据大于等于该值时触发中断或 DMA传输。

  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);

  //当发送事件产生,触发中断及回调函数(想不到用途)

  //  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) {

    if (uart_recv_ztj) //当字符串接收完成,uart_recv_ztj置高

    {

      uart_send_data(UART_NUM, v_buf, uart_recv_len);//将收到的数据发送回去

      uart_recv_ztj = 0;//清除标志位

    }

  }

}


uart.h(其他部分与官方提供的库一致,后文不再赘述)


#define BUF_LEN 200//定义接收最大长度

#define UART_NUM UART_DEVICE_3//定义使用的通道

extern char v_buf[BUF_LEN];//将缓存配置位全局变量

extern char uart_recv_ztj;  //接收数据状态机

extern int uart_recv_len;   //实际接收到的数据长度


void on_uart_recv(void);//中断函数,需要在uart_irq_register中配置


uart.c(可根据自己实际的报文格式,对代码进行二次修改)


char v_buf[BUF_LEN];     //接收数据缓冲区

char uart_recv_ztj = 0;  //接收状态机

int uart_recv_len = 0;//实际长度


//接收中断回调参数,处理接收数据

void on_uart_recv(void) {

  size_t i = 0;

  for (i = 0; i < BUF_LEN; i++) {

  //以下两行为官方所采用判断是否接收完成的代码,不完全理解其含义

    if (uart[UART_DEVICE_3]->LSR & 1)

      v_buf[i] = (char)(uart[UART_DEVICE_3]->RBR & 0xff);

    else {

      uart_recv_ztj = 1;  //接收完成

      uart_recv_len = i;  //将真实长度传递

      break;//跳出循环

    }

  }

}


测试结果如下所示

详情请参考 《Standalone SDK编程指南》——通用异步收发传输器 (UART)部分


2、UART——DMA

使用串口接收触发中断,后调用DMA收数据,再将数据发出去,其他函数看了很久,没弄得明白,在此不表。


#include

#include

#include

#include

#include

#include


//回调函数

void ztj() {

  uart_receive_data_dma(UART_NUM, DMAC_CHANNEL1, v_buf, 10);//将数据通过DMA方式接收

  uart_send_data_dma(UART_NUM, DMAC_CHANNEL0, v_buf, 10);

}


int main() {

  dmac_init();

  plic_init();          //中断初始化

  sysctl_enable_irq();  //开启系统中断


  gpio_init();                             //初始化GPIO

  gpio_set_drive_mode(0, GPIO_DM_OUTPUT);  //将GPIO 0配置为输出模型

  gpio_set_pin(0, GPIO_PV_HIGH);           // GPIO 0 输出高


  //初始化配置串口。通道3

  uart_init(UART_NUM);

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

  //接收中断或 DMA 触发 FIFO 深度,当 FIFO 中的数据大于等于该值时触发中断或

  // DMA传输。

  // uart_set_receive_trigger(UART_NUM, UART_RECEIVE_FIFO_8);

  //串口中断配置(通道、接收中断、回调函数)

  uart_irq_register(UART_NUM, UART_RECEIVE, ztj, NULL, 1);


  //发送字符串

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

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

  uart_send_data_dma(UART_NUM, DMAC_CHANNEL0, hel, strlen(hel));

  while (1) {

    gpio_set_pin(0, 1);

    msleep(2000);

    gpio_set_pin(0, 0);

    msleep(2000);

  }

}


3、双串口使用

FPIOA很大程度方便了硬件设计,将GPIO 34/35 配置为UART1 RX/TX,GPIO 4/5 配置为UART3 RX/TX。


关于两个串口的配置也相对简单,再库函数中修改为对应的串口信道即可,详情见代码。

程序流程:使用UART3中断来接收PC下发的字符串,接收完成后用UART1再发送回PC。

main.c


#include

#include

#include

#include

#include

#include


int main() {

  plic_init();          //中断初始化

  sysctl_enable_irq();  //开启系统中断


  gpio_init();                             //初始化GPIO

  gpio_set_drive_mode(0, GPIO_DM_OUTPUT);  //将GPIO 0配置为输出模型

  gpio_set_pin(0, GPIO_PV_HIGH);           // GPIO 0 输出高


  uart_init(UART_NUM);  //初始化配置串口。通道3

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


    uart_init(UART_DEVICE_1);  //初始化配置串口。通道1

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

  //接收中断或 DMA 触发 FIFO 深度,当 FIFO 中的数据大于等于该值时触发中断或

  //DMA传输。 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);

  //当发送事件产生,触发中断及回调函数(想不到用途)

  //  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) {

    gpio_set_pin(0, 1);

    msleep(2000);

    gpio_set_pin(0, 0);

    msleep(2000);

  }

}


uart.c


//接收中断回调参数,处理接收数据

void on_uart_recv(void) {

  size_t i = 0;

  for (i = 0; i < BUF_LEN; i++) {

    if (uart[UART_DEVICE_3]->LSR & 1)

      v_buf[i] = (char)(uart[UART_DEVICE_3]->RBR & 0xff);

    else {

      uart_recv_ztj = 1;  //接收完成

      uart_recv_len = i;  //将真实长度传递

      //uart_send_data(UART_NUM, v_buf, uart_recv_len);

      break;

    }

  }


  if (uart_recv_ztj)  //当字符串接收完成,uart_recv_ztj置高

  {

    // uart_send_data(UART_NUM, v_buf, uart_recv_len);  //将收到的数据发送回去

    uart_send_data_dma(UART_DEVICE_1, DMAC_CHANNEL0, v_buf, uart_recv_len);//使用DMA发送数据

    uart_recv_ztj = 0;  //清除标志位

  }

}


测试结果

在这里插入图片描述

参考资料

《Kendryte IDE使用手册》


《Standalone SDK编程指南》


《芯片技术规格书》


关键字:UART  串口 引用地址:K210学习记录(2)——UART(串口)

上一篇:K210学习记录(3)——kmodel生成与使用
下一篇:K210学习记录(1)——GPIO与软件使用

推荐阅读最新更新时间:2024-11-04 17:11

智能灯光控制器研究
中心议题: 智能灯光控制器研究 智能灯光控制器原理 解决方案: 无线数传模块设计 LPC2104采用16位/32位RISC结构 无线模块软件设计 1 引言 随着人们生活质量的提高,灯具已不单纯是室内的基本照明工具,而且是建筑装饰的一种实用艺术品,当家里有各式各样的灯具之后,将它们精心地搭配在一起,达到最适合的气氛效果是高品质生活的需要,目前灯光的控制主要还是手动形式,逐个控制所有的灯具,这样不仅麻烦而且效率低下,也不符合现代舒适生活的标准。 因此,设计一个可以便捷地控制灯光、同时还提供场景组合等功能的智能化灯光系统不仅具有实用价值,而且还具有广阔的市
[电源管理]
智能灯光控制器研究
stm32f407(cortex-M4)USART串口调试程序
上文通过调试TIM1遇到了一些问题,深入了解了stm32F407的复用功能。网上流传的很多资料都是cortex-M3的,现在都M4了,观念自然得跟上,一味照搬没有自己的思考是不行的。记得我最早的调试的程序就是串口USART,刚入手嘛,就网上找了个例程,例程对IO复用是这么写的: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE); //打开复用时钟 GPIO_StructInit(&GPIO_InitStructure); GPIO_Init
[单片机]
51单片机串口通信的原理实例
一、原理简介 51单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。其缺点是传输速度较低。 与之前一样,首先我们来了解单片机串口相关的寄存器。 SBUF 寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。从而控制外部两条独立的收发信号线RXD(P3.0)、TXD(P3.1)
[单片机]
51单片机<font color='red'>串口</font>通信的原理实例
STM32F4之串口(三)
实现STM32开发板向计算机传送数据就需要准备好STM32开发板和上位接收程序。 上位机部分使用QT开发,版本为5.8.0 STM32部分使用STM32F429芯片,开发环境为uVision V5.24.2.0 上位机效果为: 代码如下: mainwindow.h文件: #ifndef MAINWINDOW_H #define MAINWINDOW_H #include QMainWindow #include QDebug #include QtSerialPort/QSerialPort #include QtSerialPort/QSerialPortInfo namespace Ui { cla
[单片机]
STM32F4之<font color='red'>串口</font>(三)
USB虚拟串口通信实现
以一种高度集成的USB总线转接芯片CH341为核心,设计并实现了基于USB接口的PC机与下位机的虚拟串口通信。上位机在Windows环境下利用MSComm控件实现与下位机通信,介绍了USB转虚拟串口的实现方法,并基于该虚拟串口编写了智能家居控制应用软件。实验测试表明,采用虚拟串口实现上位机与单片机通信,具有结构简单、速度快和易于软件开发等特点,能满足于各种串口通信场合。 在嵌入式系统中,异步串行通信接口多作为标准外围设备出现。随着大量支持USB的个人电脑的普及,易于使用的接口。USB接口逐步成为PC机的标准接口,使得对USB接口相关应用软件的开发和外围设备的研究显得越来越重要。 本文中的智能家居控制系统采用基于USB的虚拟串
[嵌入式]
stm8s串口通信(uart
最近开始使用stm8s103k3单片机了。据说很好,确实不错。前几天已经试过了GPIO,Timer2,ADC的功能,都比较容易,唯独串口UART使用,破费周折,写出来,供大家借鉴。 我使用的是stm8s103k3,32脚单片机,这个使用手册上说了UART1,UART2,UART3。但是引脚的功能图上只有UART1,并且你打开stm8s103k.h的头文件,里面也只有UART1寄存器的定义说明。所以我认为只有UART1。既然有这个功能,那就用吧,我以为直接可以连接到电脑的串口(COM1),就可以使用了,其实不可以。单片机即使写着提供UART通讯功能,也要连接MAX232转接芯片,我就在这里耽误了许多时间。 1、使用st
[单片机]
stm8s<font color='red'>串口</font>通信(<font color='red'>uart</font>)
嵌入式系统的USB虚拟串口设计
   引 言:   现代嵌入式系统中,异步串行通信接口往往作为标准外设出现在单片机和嵌入式系统中。但是随着个人计算机通用外围设备越来越少地使用串口,串口正在逐渐从个人计算机特别是便携式电脑上消失。于是嵌入式开发人员常常发现自己新买来的计算机上没有串口,或者出现调试现场用户的计算机没有串口的尴尬局面。相反,现在的个人计算机普遍拥有4个以上的USB接口,能不能使用USB接口代替串口,完成PC机和嵌入式系统的通信呢?   1、 USB虚拟串口代替物理串口的可行性   首先,越来越多带USB接口的器件涌现出来,如带USB接口的单片机,或独立的USB接口器件,而且这些器件的成本已经很接近于使用RS232电平转换芯片所带来的成本。 ?
[嵌入式]
STM32系统学习——USART(串口通信)
串口通信是一种设备间非常常用的串行通行方式,其简单便捷,大部分电子设备都支持。 一、物理层 常用RS-232标准,主要规定了信号的用途、通信接口以及信号的电平标准。 “DB9接口”之间通过串口信号线建立起连接,串口信号线使用”RS-232标准“传输数据信号,这些信号通过记过电平转换芯片转换成控制器能识别的TLL标准的电平信号,才能实现通信。 1.电平标准 可分为TTL标准以及RS-232标准。 常见的电子电路中常见TTL的电平标准,理想状态使用5V表示二进制逻辑1,0V表示逻辑0;而为了增加串口通信的远距离传输以及抗干扰能力,RS-232使用-15V表示逻辑1,+15V表示逻辑0。 因为控制器一般使用TTL电平标准
[单片机]
STM32系统学习——USART(<font color='red'>串口</font>通信)
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved