基于亚博K210开发板——串口中断以及开启双核任务

news2024/11/26 12:35:45

文章目录

  • 开发板
  • 实验目的
  • 实验准备
    • 硬件原理图
    • 软件对应SDK
      • 对应的头文件 uart.h
      • uart.h接口函数
      • 高速通用异步收发传输器(UARTHS)对应的头文件 uarths.h
      • uarths.h接口函数
      • 板级对应的头文件 bsp.h
      • bsp.h接口函数
  • 实验代码
  • 实验结果
    • 效果

开发板

亚博K210开发板
在这里插入图片描述

实验目的

本实验配置串口通信,并开启接收中断,主程序开启双核,核心0任务实现LED灯交替亮灭并打印数据,核心1任务实现实时读取串口数据,当达到一定条件开启或RGB交替亮灭并打印对应数据

实验准备

硬件原理图

Tpye-C 接口连接 K210 的 IO4 和 IO5 接口,其中 IO4 为 K210 芯片的接收引脚,IO5
为 K210 芯片的发送引脚。
在这里插入图片描述

软件对应SDK

对应的头文件 uart.h

通用 UART 为 UART1、UART2 和 UART3,支持异步通信(RS232 和 RS485 和IRDA,通信速率可达到 5Mbps。UART 支持 CTS 和 RTS 信号的硬件管理以及软件流控(XON 和 XOFF)。3 个接口均可被 DMA 访问或者 CPU 直接访问。每次传输数据为 8 字节,支持异步时钟,可单独配置数据时钟,实现全双工模式,保证两个时钟域中数据同步。

uart 默认为 RS232 模式,也可以配置为软件可编程式 RS485 模式。

用 THRE 中断模式来提升串口性能。当 THRE 模式和 FIFO 模式被选择之后,如果 FIFO 中少于阈值便触发 THRE 中断。

uart.h接口函数

• uart_init:初始化 uart
• uart_config (0.6.0 后不再支持,请使用 uart_configure)
• uart_configure:配置串口的波特率等
• uart_send_data:通过串口发送数据
• uart_send_data_dma:通过 dma 通道发送数据
• uart_send_data_dma_irq:UART 通过 DMA 发送数据,并注册 DMA 接收完成中断函数,仅单次中断
• uart_receive_data:读取串口数据
• uart_receive_data_dma:串口通过 dma 接收数据
• uart_receive_data_dma_irq:UART 通过 DMA 接收数据,并注册 DMA 接收完成中断函数,仅单次中断
• uart_irq_register:注册串口中断函数
• uart_irq_deregister:注销串口中断
• uart_set_work_mode:设置 uart 工作模式。有四种模式:普通 uart、红外、RS485 全双工、RS485 半双工。
• uart_set_rede_polarity:设置 RS485 re de 管脚有效时的极性。
• uart_set_rede_enable:使能 re de 管脚,主要用在 rs485 全双工模式,re 和 de 必须手动控制。单双工模式不用调用该函数,单双工时硬件会自动设置 re de。
• uart_set_tat:配置 re de 互相的时间间隔,这个与外部的 485 模块有关。
• uart_set_det:设置 de 有效无效转换时数据的时间延时。
• uart_debug_init:配置调试串口。系统默认使用 UART3 做为调试串口,调用该函数用户可以自定义使用哪个 uart 做为调试串口,如果使用 UART1 或 UART2 需要使用 fpioa 设置管脚。因此调试脚不局限于 fpioa4、5
• uart_handle_data_dma:UART 通过 DMA 传输数据

高速通用异步收发传输器(UARTHS)对应的头文件 uarths.h

高速 UART 为 UARTHS(UART0),通讯速率可达到 5Mbps,8 字节发送和接收FIFO,可编程式 THRE 中断,不支持硬件流控制或者其他调制解调器控制信号,或同步串行数据转换器。系统的 printf 调试函数默认就是调用 UARTHS 串口来实现发送数据的。

uarths.h接口函数

• uarths_init:初始化 UARTHS,系统默认波特率为 115200 8bit 1 位停止位无检验位。因为uarths 时钟源为 PLL0,在设置 PLL0 后需要重新调用该函数设置波特率,否则会打印乱码。
• uarths_config:设置 UARTHS 的参数。默认 8bit 数据,无校验位。
• uarths_receive_data:通过 UARTHS 读取数据。
• uarths_send_data:通过 UART 发送数据。
• uarths_set_irq:设置 UARTHS 中断回调函数。
• uarths_get_interrupt_mode:获取 UARTHS 的中断类型。接收、发送或接收发送同时中断。
• uarths_set_interrupt_cnt : 设 置 UARTHS 中断时的 FIFO 深度。 当中断类UARTHS_SEND_RECEIVE,发送接收 FIFO 中断深度均为 cnt;

板级对应的头文件 bsp.h

bsp.h 头文件是与平台相关的通用函数,核之间锁的相关操作。提供获取当前运行程序的 CPU 核编号的接口以及启动第二个核的入口。
K210 是双核 CPU,那么什么是双核 CPU 呢?双核 CPU 是在一个 CPU 中拥有两个一样功能的处理器芯片,从而提高计算能力。K210 的核心 0 和核心 1 都可以单独工作,系统默认使用核心 0,如果需要使用核心 1 需要手动开启核心 1 的服务。

bsp.h接口函数

• register_core1:向核心 1 注册函数,并启动核心 1
• current_coreid:获取当前 CPU 的核心编号(0/1)
• read_cycle:获取 CPU 开机至今的时钟数。可以用使用这个函数精准的确定程序运行时钟。可以配合 sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)计算运行的时间。
• spinlock_lock:自旋锁,不可嵌套,不建议在中断使用,中断中可以使用 spinlock_trylock。
• spinlock_unlock:自旋锁解锁。
• spinlock_trylock:获取自旋锁,成功获取锁会返回 0,失败返回-1。
• corelock_lock:获取核间锁,核之间互斥的锁,同核内该锁会嵌套,只有异核之间会阻塞。不建议在中断使用该函数,中断中可以使用 corelock_trylock。
• corelock_trylock:获取核间锁,同核时锁会嵌套,异核时非阻塞。成功获取锁会返回 0,失败返回-1。
• corelock_unlock:核间锁解锁。
• sys_register_putchar:注册系统输出回调函数,printf 时会调用该函数。系统默认使用UART3,如果需要修改 UART 则调用 uart_debug_init 函数。
• sys_register_getchar:注册系统输入回调函数,scanf 时会调用该函数。系统默认使用UART3,如果需要修改 UART 则调用 uart_debug_init 函数。
• sys_stdin_flush:清理 stdin 缓存。
• get_free_heap_size:获取空闲内存大小。
• printk:打印核心调试信息,用户不必理会。

实验代码

bsp_led_rgb.h

#ifndef __BSP_LED_RGB_H_
#define __BSP_LED_RGB_H_
/*****************************HEAR-FILE************************************/
#include "fpioa.h"
#include "gpiohs.h"
#include "gpio.h"
#include "fpioa.h"
#include "sleep.h"

/*****************************HARDWARE-PIN*********************************/

#define IS_HIGH_GPIO  1


// 硬件IO口,与原理图对应

//led
#define PIN_LED_0             (0)
#define PIN_LED_1             (17)

//rgb
#define PIN_RGB_R                 (6)
#define PIN_RGB_G                 (7)
#define PIN_RGB_B                 (8)

/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应

//led
#define LED0_GPIONUM          (3)
#define LED1_GPIONUM          (4)

//rgb
#define RGB_R_GPIONUM          (0)
#define RGB_G_GPIONUM          (1)
#define RGB_B_GPIONUM          (2)

/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口

//led
#define FUNC_LED0             (FUNC_GPIO0 + LED0_GPIONUM)
#define FUNC_LED1             (FUNC_GPIO0 + LED1_GPIONUM)

//rgb
#if  IS_HIGH_GPIO
#define FUNC_RGB_R             (FUNC_GPIOHS0 + RGB_R_GPIONUM)
#define FUNC_RGB_G             (FUNC_GPIOHS0 + RGB_G_GPIONUM)
#define FUNC_RGB_B             (FUNC_GPIOHS0 + RGB_B_GPIONUM)
#else
#define FUNC_RGB_R             (FUNC_GPIO0 + RGB_R_GPIONUM)
#define FUNC_RGB_G             (FUNC_GPIO0 + RGB_G_GPIONUM)
#define FUNC_RGB_B             (FUNC_GPIO0 + RGB_B_GPIONUM)
#endif

void rgbInit(void);
void ledInit(void);
void rgbClose(void);
void ledClose(void);
void ledFlash(int ms);
void rgbFlash(int ms);


#endif /* __BSP_LED_RGB_H_ */

bsp_led_rgb.c

#include "bsp_led_rgb.h"

void hardware_init(void)
{

    fpioa_set_function(PIN_LED_0, FUNC_LED0);
    fpioa_set_function(PIN_LED_1, FUNC_LED1);

    fpioa_set_function(PIN_RGB_R, FUNC_RGB_R);
    fpioa_set_function(PIN_RGB_G, FUNC_RGB_G);
    fpioa_set_function(PIN_RGB_B, FUNC_RGB_B);
}

void rgbInit()
{
    gpio_init();
    //硬件初始化,绑定GPIO口
    fpioa_set_function(PIN_RGB_R, FUNC_RGB_R);
    fpioa_set_function(PIN_RGB_G, FUNC_RGB_G);
    fpioa_set_function(PIN_RGB_B, FUNC_RGB_B);

    //设置模式为输出
#if  IS_HIGH_GPIO     
    gpiohs_set_drive_mode(RGB_R_GPIONUM, GPIO_DM_OUTPUT);
    gpiohs_set_drive_mode(RGB_G_GPIONUM, GPIO_DM_OUTPUT);
    gpiohs_set_drive_mode(RGB_B_GPIONUM, GPIO_DM_OUTPUT);
#else
    gpio_set_drive_mode(RGB_R_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(RGB_G_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(RGB_B_GPIONUM, GPIO_DM_OUTPUT);
 #endif 
}


void ledInit()
{
    gpio_init();
    //硬件初始化,绑定GPIO口
    fpioa_set_function(PIN_LED_0, FUNC_LED0);
    fpioa_set_function(PIN_LED_1, FUNC_LED1);
    //设置LED0和LED1的GPIO模式为输出
    gpio_set_drive_mode(LED0_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(LED1_GPIONUM, GPIO_DM_OUTPUT);

}

void rgbClose()
{
#if  IS_HIGH_GPIO    
    gpiohs_set_pin(RGB_R_GPIONUM, GPIO_PV_HIGH);
    gpiohs_set_pin(RGB_G_GPIONUM, GPIO_PV_HIGH);
    gpiohs_set_pin(RGB_B_GPIONUM, GPIO_PV_HIGH);
#else
    gpio_set_pin(RGB_R_GPIONUM, GPIO_PV_HIGH);
    gpio_set_pin(RGB_G_GPIONUM, GPIO_PV_HIGH);
    gpio_set_pin(RGB_B_GPIONUM, GPIO_PV_HIGH);
#endif    
}


void ledClose()
{
    // 先关闭LED0和LED1
    gpio_pin_value_t value = GPIO_PV_HIGH;
    gpio_set_pin(LED0_GPIONUM, value);
    gpio_set_pin(LED1_GPIONUM, value);

}

void ledFlash(int ms)
{
    static gpio_pin_value_t value = GPIO_PV_HIGH;
    msleep(ms);
    gpio_set_pin(LED0_GPIONUM, value);
    gpio_set_pin(LED1_GPIONUM, value = !value);
}

void rgbFlash(int ms)
{
    static uint8_t rgbIndex = 0;
    rgbIndex %= 3; 
    rgbClose();
    gpiohs_set_pin(rgbIndex, GPIO_PV_LOW);
    rgbIndex++;
    msleep(ms);
}
bsp_usart.h

```c
#ifndef __BSP_USART_H
#define __BSP_USART_H
/*****************************HEAR-FILE************************************/
#include "fpioa.h"
#include "uart.h"
#include "sysctl.h"

/*****************************HARDWARE-PIN*********************************/
// 硬件IO口,与原理图对应
#define PIN_UART_USB_RX       (4)
#define PIN_UART_USB_TX       (5)

/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
#define UART_USB_NUM           UART_DEVICE_3

/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
#define FUNC_UART_USB_RX       (FUNC_UART1_RX + UART_USB_NUM * 2)
#define FUNC_UART_USB_TX       (FUNC_UART1_TX + UART_USB_NUM * 2)



typedef struct UsartRecData
{
    uint8_t reclen;
    char recData;
    /* data */
}UsartRecData;
 



void usartInit(int uartNum,int baudRrate);
void uartSendData(int uartNum,char *data,int size);
bool waitForMessage(int uartNum);

extern UsartRecData usartData;

#endif /* _PIN_CONFIG_H_ */

bsa_usart.c

#include "bsp_usart.h"
#include "string.h"

UsartRecData usartData;


void uart_hardware_init(void)
{

    fpioa_set_function(PIN_UART_USB_RX, FUNC_UART_USB_RX);
    fpioa_set_function(PIN_UART_USB_TX, FUNC_UART_USB_TX);

}

int uartCallBack(void *ctx)
{       
    char temp;
    while(uart_receive_data(UART_USB_NUM,&usartData.recData,1)){
       
    }
    
    return 0;
}

void usartInit(int uartNum,int baudRrate)
{

    uart_hardware_init();
     // 初始化串口,设置波特率为115200
    uart_init(uartNum);
    // 设置 uart 工作模式
    uart_set_work_mode (UART_USB_NUM , UART_NORMAL);
    // 初始化串口
    uart_configure(UART_USB_NUM,baudRrate,UART_BITWIDTH_8BIT, UART_STOP_1, UART_PARITY_NONE);
     // 初始化外部中断 
    uart_irq_register(UART_USB_NUM, UART_RECEIVE, uartCallBack,NULL,2);
    // 设置接收中断 触发 FIFO 深度
    uart_set_receive_trigger(UART_USB_NUM, UART_RECEIVE_FIFO_1);
    

}

void uartSendData(int uartNum,char *data,int size)
{

    uart_send_data(UART_USB_NUM, data, size);
  
}

bool waitForMessage(int uartNum)
{
    char rec = 0;
    while(uart_receive_data(uartNum,&rec,1)){
        if(1 == rec){
            return true;
        }else{
            return false;
        }
    }
}
    

mian.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "bsp.h"
#include "bsp_led_rgb.h"
#include "bsp_usart.h"


int core1TaskRun(void *ctx)
{
    char core1Log1[40] = "rgb state is opened\r\n";
    char core1Log2[40] = "wait for open rgb\r\n";

     while(1){
        if(usartData.recData == 1){
            rgbFlash(300);
            uartSendData(UART_USB_NUM,core1Log1,sizeof(core1Log1));
        }else{
           sleep(1);
           uartSendData(UART_USB_NUM,core1Log2,sizeof(core1Log2));
        }
        
    }
}

void core1Init()
{
    register_core1(core1TaskRun,NULL);
}


int main(void)
{

    char core0Log[50] = "this is core0 task!\r\n";
    
    plic_init();
    sysctl_enable_irq();
    ledInit();
    rgbInit();

    usartInit(UART_USB_NUM,115200);

    core1Init();

    while (1){
       
        ledFlash(1000);
        uartSendData(UART_USB_NUM,core0Log,sizeof(core0Log));       
    }
    
        
    
    return 0;
}

实验结果

编译烧录之后LED0和LED1会依次交替亮灭,串口助手上会打印任务0信息,当在串口助手上发送字符1时,任务1会开启RGB灯的交替亮灭并打印信息,若发送字符0后,任务1会关闭rgb的交替亮灭。

效果

发送 0 后(rgb停止闪烁)
发送字符0后
发送 1 后(rgb开始闪烁)
发送字符1后

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/750185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3中的excel表导出功能(选中导出或导出所有,也可支持vue2)

1.安装模块 npm install xlsx file-saver -S 2.文件导入 import * as XLSX from "xlsx"; import FileSaver from "file-saver" 3.整体代码(可选中导出或导出所有) <template><div><el-button type"warning" click"down&quo…

apt-get install命令

在Linux系统中&#xff0c;apt-get命令默认安装包的位置是在/usr目录下。具体来说&#xff0c;安装的可执行文件会存储在/usr/bin目录下&#xff0c;而库文件会存储在/usr/lib目录下。同时&#xff0c;相应的配置文件和文档等也会存储在/usr/share目录下。 举例&#xff0c;ap…

【计算机系统概论Yale.patt】第三章

文章目录 3.数字逻辑3.1 MOS管3.1.1 p型MOS晶体管3.1.2 n型MOS晶体管 3.2 逻辑门3.2.1 非门——反相器3.2.2 或非门、或门或非门或门 3.2.3 与非门、与门3.2.4 逻辑门符号表示逻辑门的数电表达式摩根定律 3.3 逻辑结构3.3.1 组合逻辑译码器多路复用器全加器可编程逻辑阵列 3.3.…

20230713-------通过platform实现阻塞IO来驱动按键控制LED灯的亮灭

需添加的设备树节点 myplatform{ compatible "hqyj,myplatform"; reg<0X12345678 0X400>; interrupt-parent<&gpiof>; interrupts<9 0>; //9表示引用中断父节点时的索引信息 0表示默认设置 led1<&gpioe 10 0>;pdev.c #include …

linux 安装pytorch3d的坑

事实上&#xff0c;只要按照官方文档的说明就可以完美安装。其中坑的地方在于conda的管理可能会导致下载的版本不符合你的要求&#xff08;例如下载成了cpu版本、下载的cuda版本&#xff09;而同样尝试使用源码编译以及其他方式下载库都会导致同样的问题&#xff0c;这里主要的…

【动手学深度学习】层和块

层和块 简单介绍 块&#xff1a;描述单个层&#xff0c;由多个层组成的组件或整个模型本身。使用块进行抽象的一个好处是可以将一些块组合成更大的组件&#xff0c;这一过程通常是递归的 简单入门 import torch from torch import nn from torch.nn import functional as F# …

【分布式系统案例课】计数服务之需求收集和总架构设计

面试题 对B站视频观看量进行实时的计数 技术问题是一个比较普遍的问题&#xff0c;比如对头条作者的粉丝或者是对获赞进行计数。或者是对企业的业务指标进行计数&#xff0c;例如注册登录下单数这些等。 需求澄清 问题一&#xff1a;用户点击观察视频之后&#xff0c;这个数量…

Gateway网关组件(在Spring Cloud整合Gateway(idea19版本))

Spring Cloud Gateway官网:Spring Cloud Gateway 局域网中就有网关这个概念&#xff0c;局域网接收数据或发送数据都要通过网关&#xff0c;比如使用VMware虚拟机软件搭建虚拟机集群的时候&#xff0c;往往我们需要选择IP段中的⼀个IP作为网关地址,网关可以对请求进行控制,提升…

Shell第三章——循环语句与函数

循环&#xff1a;重复执行一段代码的结构&#xff0c;通过循环可以在满足一定的条件之下多次执行相同的代码。 循环语句&#xff1a;包换循环体&#xff0c;代码的总结构&#xff0c;循环条件&#xff0c;当循环条件满足时&#xff0c;循环体的代码才会执行&#xff0c;条件不…

RabbitMQ-同步和异步通讯、安装和入门案例、SpringAMQP(5个消息发送接收Demo,jackson消息转换器)

文章目录 1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯 1.2.技术对比&#xff1a; 2.快速入门2.1.安装RabbitMQ2.2.RabbitMQ消息模型2.3.导入Demo工程2.4.入门案例2.4.1.publisher实现2.4.2.consumer实现 2.5.总结 3.SpringAMQP3.1.Basic Queue 简单队列模型3.1.1.…

【设计模式】23种设计模式——工厂模式(原理讲解+应用场景介绍+案例介绍+Java代码实现)

工厂模式 需求了解 看一个披萨的项目&#xff1a;要便于披萨种类的扩展&#xff0c;要便于维护 披萨的种类很多(比如 GreekPizz、CheesePizz 等)披萨的制作有 prepare&#xff08;准备材料&#xff09;,bake&#xff08;烘焙&#xff09;,cut&#xff08;切割&#xff09;,b…

Hive SQL 迁移 Flink SQL 在快手的实践

摘要&#xff1a;本文整理自快手数据架构工程师张芒&#xff0c;阿里云工程师刘大龙&#xff0c;在 Flink Forward Asia 2022 生产实践专场的分享。本篇内容主要分为四个部分&#xff1a; Flink 流批一体引擎 Flink Batch 生产实践 核心优化解读 未来规划 点击查看原文视频…

切换.net Framework 版本后,出现NuGet 包是使用不同于当前目标框架的目标框架安装的,可能需要重新安装

问题现象&#xff1a; 由于添加新的dll文件&#xff0c;依赖的.NET Framework版本与当前的不一致&#xff0c;在vs 中切换了目标框架版本后&#xff0c;运行程序&#xff0c;出现以下的warnning信息&#xff1a; 一些 NuGet 包是使用不同于当前目标框架的目标框架安装的&#…

springboot社区疫情防控平台

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

剑指offer68-I.二叉搜索树的最近公共祖先

把p的所有祖先找出来&#xff0c;把q的所有祖先找出来&#xff0c;因为是是搜索树&#xff0c;找出来的祖先都是排好序的&#xff0c;所以可以把找出来的祖先从后面往前面遍历&#xff0c;第一个相同的值的数就是最近的公共祖先&#xff0c;这是我一开始的想法,但是它最后报错了…

(六)人工智能应用--深度学习原理与实战--理解张量与运算图

Tensorflow名称中的Tensor即张量&#xff0c;不仅仅是Tensorflow&#xff0c;几乎所有的深度学习平台都以张量为基本的数据结构。简单来说&#xff0c;张量就是多维数组&#xff0c;本质上是一种数据容器&#xff0c;它可以有任意维度&#xff0c;比如矩阵就是二维张量(二维数组…

数字图像处理【11】OpenCV-Canny边缘提取到FindContours轮廓发现

本章主要介绍图像处理中一个比较基础的操作&#xff1a;Canny边缘发现、轮廓发现 和 绘制轮廓。概念不难&#xff0c;主要是结合OpenCV 4.5的API相关操作&#xff0c;为往下 "基于距离变换的分水岭图像分割" 做知识储备。 Canny边缘检测 在讲述轮廓之前&#xff0c;…

数字孪生,建设智慧城市的新型“加速器”

城市是什么&#xff1f; 是现代文明与生态的联结&#xff0c;是自然与人友好栖息的空间&#xff0c;是运转复杂庞大的系统。 今天&#xff0c;中国的城市在历经十余年的“智慧城市”建设后已经被赋予了数智融合的全新解读。随着近年来5G、云计算、人工智能爆发式能量增长&#…

常见的bug---4、在DataGrip上跑本地模式报return 2异常

文章目录 问题描述原因分析&#xff1a;解决方案&#xff1a; 问题描述 FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask 在DataGrip上设置了Hive的本地模式。虽然可以建表、但是无法对表进行插入数据 原因分析&#xff1a; 在插…