N32G45之串口+DMA数据收发

news2024/9/21 14:32:42

N32G45之串口+DMA数据收发

1.串口简介
  通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。 USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。
  串口是计算机上一种非常通用设备通信的协议。大多数计算机包含两个基于RS232的串口。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。同时,串口通信协议也可以用于获取远程采集设备的数据。本次所所使用开发板为mini USB串口,有3个分别为USART1、USART2和USART3。我们将以串口1为例完成开发板与上位机之间通讯。

2.串口特性

  • 任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。
      RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。
      TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,
      TX引脚处于高电平。在单线和智能卡模式里,此I/O口被同时用于数据的发送和接收。总线在发送或接收前应处于空闲状态。
      一个起始位。
      一个数据字(8或9位),最低有效位在前。
      0.5, 1.5, 2个的停止位,由此表明数据帧的结束。
      使用分数波特率发生器 —— 12位整数和4位小数的表示方法。
      一个状态寄存器(USART_STS)。
      一个数据寄存器(USART_DAT)。
      一个波特率寄存器(USART_BRCF), 12位的整数和4位小数。
      在这里插入图片描述

3.串口配置

  1. 置位 USART_CTRL1.UEN 来使能 USART;
  2. 配置波特率、数据长度、校验位、停止位长度、以及根据需要配置相关 DMA;
  3. 使能发送功能 (USART_CTRL1.TXEN);
  4. 通过 CPU 或 DMA 将要发送的数据依次写入数据寄存器 USART_DAT, 当数据写入数据寄存器时将清零 USART_STS.TXDE;
  5. 当所有数据已写入到数据寄存器 USART_DAT 后,等待发送完成标志位 USART_STS.TXC 置 1,数据发送完成;

3.1 串口控制寄存器CTRL1

  串口的基本功能(使能串口、中断功能、发送、接收)均在USART1_CRTL1寄存器中完成配置。
在这里插入图片描述

3.2 串口状态寄存器STS

  状态寄存器主要用于检测各个状态标志是否触发(发送标志、接收标志、空闲帧标志等等)。
在这里插入图片描述

3.3 串口数据寄存器DAT

  串口数据寄存器用包含了发送和接收数据。串口数据收发均使用DAT寄存器装载。
在这里插入图片描述

3.4 串口波特率寄存器

  串口波特率寄存器包含了4位小数位和12位整数位。
在这里插入图片描述

  • 波特率计算方式如下:
    在这里插入图片描述

3.5 串口模式配置

  我们这里以串口1为例,因为串口1为开发板调试端口,方便后面效果展示。配置模式为:1个起始位+8个数据位+1个停止位,无校验位。开始长发送功能和空闲帧接收功能,通过DMA配合串口数据收发,实现不定长数据处理。

void USART_Init(u32 buad)
{
  RCC->APB2PCLKEN|=1<<14;
  RCC->APB2PRST|=1<<14;
  RCC->APB2PRST&=~(1<<14);
  /*配置GPIO*/
  RCC->APB2PCLKEN|=1<<2;//PA
  GPIOA->PH_CFG&=0xFFFFF00F;
  GPIOA->PH_CFG|=0x000008B0;
  /*串口配置*/
  USART1->BRCF=72000000/buad;
  USART1->CTRL1|=1<<2;
  USART1->CTRL1|=1<<3;
  
  USART1->CTRL3|=1<<7;//DMA发送
  USART1->CTRL3|=1<<6;//DMA接收
  USART1->CTRL1|=1<<4;//IDLE(空闲帧中断)
  N32_NVIC_SetPriority(USART1_IRQn,1,1);
  USART1->CTRL1|=1<<13;//使能串口
  DMA_CH5_Init((u32 )&USART1->DAT,(u32 )usart1_rx_buff);//DMA配合串口1接收数据 
 DMA_CH4_Init((u32 )&USART1->DAT);
}

3.6 修改printf底层重定向

  修改printf重定向,方便后续功能调试。
  printf底层实现接口函数为fputc,我们只需要将该函数重定向到串口调试终端即可。

int fputc(int c,FILE *stream) 
{
  USART1->DAT=c;
  while(!(USART1->STS&1<<7));
  return c;
}

4.DMA功能配置

  直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。
  DMA 控制器总共可以访问 8 个 AHB 从机: Flash、 SRAM、 ADC、 SDIO、 QSPI、 ETH、 ABP1 和 APB2。
  DMA 控制器由 CPU 控制以执行从源到目的的快速数据移动。配置完成后,无需 CPU 干预即可传输数据。因此,可以释放 CPU 用于其他计算/控制任务或节省整体系统功耗。
  芯片有两个 DMA( DMA1、 DMA2)控制器,每个 DMA 控制器有 8 个逻辑通道。每个逻辑通道用于服务来自单个或多个外设的内存访问请求。内部仲裁器控制不同 DMA 通道的优先级。

  • DMA特性
  • 16 个可独立配置的 DMA 通道: DMA1 和 DMA2 各有 8 个通道
  • 支持内存到内存、内存到外设和外设到内存三种传输类型
  • 每个 DMA 通道支持硬件请求和软件触发来启动传输,并由软件配置
  • 每个 DMA 通道都有专用的软件优先级( DMA_CHCFGx.PRIOLVL[1:0]位,对应 4 个优先级),可以单 独配置。具有相同软件优先级的通道将进一步比较硬件索引(通道号)以确定最终优先级(索引号越低的通道优先级越高)
  • 可配置的源和目标大小。地址设置应与数据大小相对应
  • 每个通道可配置循环传输模式
  • 每个通道有 3 个独立的事件标志和中断(传输完成、半传输、传输错误)和 1 个全局中断标志(由 3 个事件的逻辑或设置)。
  • 共访问 8 个 AHB 从机: Flash、 SRAM、 ADC、 SDIO、 QSPI、 ETH、 ABP1 和 APB2
  • 可配置数据传输数( 0~65535)
  • DMA功能框图
    在这里插入图片描述
      DMA 控制器和 Cortex™-M4F 内核共享相同的系统数据总线。当 CPU 和 DMA 同时访问同一个目标( RAM或外设)时, DMA 请求会暂停 CPU 访问系统总线几个周期,由总线仲裁器进行循环调度。这允许 CPU 获得至少一半的系统总线(内存或外围设备)带宽。
      DMA 请求可以由硬件外设或软件触发, DMA 控制器根据通道的优先级处理请求。根据配置的传输地址和位宽从源地址读取数据,然后将读取的数据存储在目的地址空间中。一次操作后,控制器计算剩余传输数,并更新下一次传输的源地址和目的地址。
  • 每个 DMA 数据传输包括三个操作:

  数据访问:根据传输方向确定源地址( DMA_PADDRx 或 DMA_MADDRx),从源地址读取数据。
  数据存储:根据传输方向确定目的地址( DMA_PADDRx 或 DMA_MADDRx),将读取的数据存储到目的地址空间。
  计算未完成操作的数量,对 DMA_TXNUMx 寄存器进行减量操作,更新下一个操作的源地址和目的地址。

4.1DMA请求映像

  DMA1 请求映像如下图所示。通过配置对应外设的寄存器,每个外设的 DMA 请求均可以独立的开启或关闭,并根据通道优先级,同一时间只有一个请求有效。
在这里插入图片描述
  根据DMA请求映像可知,USART1_TX在Channel4上,USART1_RX在Channel5上。

4.2 DMA配置流程

  • 配置中断屏蔽位, 1:启用中断, 0:禁用中断。
  • 配置通道外设地址和内存地址以及传输方向。
  • 配置通道优先级, 0:最低, 3:最高。
  • 配置外设和内存地址增量。
  • 配置通道传输块大小。
  • 如有必要,配置循环模式。
  • 如果是存储器到存储器,配置 MEM2MEM 模式。
  • 在通道 1~ 8 上重复第 1~ 8 步。
  • 最后使能相应通道。
     如果使用软件提供中断服务,则软件必须查询中断状态寄存器以检查发生了哪个中断(软件需要向中断标志清除位写 1 来清除相应的中断)。在使能通道之前,应清除该通道对应的所有中断。
     如果中断是传输完成中断,软件可以配置下一次传输,或者向用户报告该通道传输完成。
  • DMA支持三种传输方式:
  • 存储器到存储器
  • 存储器到外设
  • 外设到存储器
      流控制由每个 DMA 通道配置寄存器中的两个寄存器位控制。流控制用于控制 DMA 通道的源/目标和方向。

4.3 DMA相关寄存器介绍

在这里插入图片描述
  DMA通道配置寄存器用于配置DMA传输方向、数据宽度、优先级等功能。
在这里插入图片描述
  DMA传输数量寄存器用于设置DMA传输的数量,范围在0~65535之间。

外设基地址寄存器DMA_PADDR
在这里插入图片描述
在这里插入图片描述

4.5 DMA通道4配置

  DMA1_CH4配置,设置模式为存储器到外设,配合串口1数据发送。

/******DMA配合串口1发送数据************
**形参:u32 cpar -- 外设地址
**
**例:DMA_CH4_Init(&USART1->DR,buff)
**外设地址:USART1->DR的地址
**          buff的地址
**作者:IT_阿水
**************************************/
void DMA_CH4_Init(u32 cpar)
{
  RCC->AHBPCLKEN|=1<<0;//dma1时钟使能
  DMA1_CH4->CHCFG&=~(1<<14);//非存储器到存储器模式
  DMA1_CH4->CHCFG|=0x3<<12;//设置CH4优先级为最高
  DMA1_CH4->CHCFG&=~(0x3<<10);//存储器数据宽度8位
  DMA1_CH4->CHCFG&=~(0x3<<8);//外设数据宽度8位  
  DMA1_CH4->CHCFG|=1<<7;//存储器地址增量
  DMA1_CH4->CHCFG&=~(1<<6);//外设地址不增量
  DMA1_CH4->CHCFG&=~(1<<5);//不执行循环操作
  DMA1_CH4->CHCFG|=1<<4;//从存储器读

  DMA1->CHMAPEN|=1<<0;//使能MAP通道
  DMA1_CH4->CHSEL|=16<<0;//开启USART1_TX

  DMA1_CH4->CHCFG&=~(1<<0);//关闭通道传输
  DMA1_CH4->PADDR=cpar;//外设地址
}
/**********开启DMA1_CH4数据传输*************
***
***形参:u16 data_len -- DMA要传输数目
***********************************************/
void DMA_CH4_Start(u8 *buff,u16 data_len)
{
  DMA1_CH4->CHCFG&=~(1<<0);//关闭通道传输
  DMA1_CH4->MADDR=(u32)buff;//存储器地址
  DMA1_CH4->TXNUM=data_len;//设置传输数量
  DMA1_CH4->CHCFG|=1<<0;//开启通道传输
}

4.6 DMA通道5配置

  DMA1_CH5配置,设置模式为外设到存储器,配合串口1数据接收。

/******DMA配合串口1接收数据************
**形参:u32 cpar -- 外设地址
**      u32 cmar -- 存储器地址
**
**例:DMA_CH5_Init(&USART1->DR,buff)
**外设地址:USART1->DR的地址
**          buff的地址
**作者:IT_阿水
**************************************/
void DMA_CH5_Init(u32 cpar,u32 cmar)
{
	RCC->AHBPCLKEN|=1<<0;//dma1时钟使能
	DMA1_CH5->CHCFG&=~(1<<14);//非存储器到存储器模式
	DMA1_CH5->CHCFG|=0x3<<12;//设置CH4优先级为最高
	DMA1_CH5->CHCFG&=~(0x3<<10);//存储器数据宽度8位
	DMA1_CH5->CHCFG&=~(0x3<<8);//外设数据宽度8位  
	DMA1_CH5->CHCFG|=1<<7;//存储器地址增量
	DMA1_CH5->CHCFG&=~(1<<6);//外设地址不增量
	DMA1_CH5->CHCFG&=~(1<<5);//执行循环操作
	DMA1_CH5->CHCFG&=~(1<<4);//从外设读
	
	DMA1->CHMAPEN|=1<<0;//使能MAP通道
	DMA1_CH5->CHSEL=23;//开启USART1_RX
	
	DMA1_CH5->CHCFG&=~(1<<0);//关闭通道传输
	DMA1_CH5->PADDR=cpar;//外设地址
	DMA1_CH5->MADDR=cmar;//存储器地址
	DMA1_CH5->TXNUM=1024;//设置传输数量
	DMA1_CH5->CHCFG|=1<<0;//开启通道传输
 
}
/**********开启DMA1_CH5数据传输*************
***
***形参:u16 data_len -- DMA要传输数目
***********************************************/
void DMA_CH5_Start(u16 data_len)
{
  DMA1_CH5->CHCFG&=~(1<<0);//关闭通道传输
  DMA1_CH5->TXNUM=data_len;//设置传输数量
  DMA1_CH5->CHCFG|=1<<0;//开启通道传输
}

5.编写串口1中断服务函数

  编写串口以中断服务函数,通过触发空闲帧中断,配置DMA实现串口不定长数据接收处理。
  当一空闲帧被检测到时, USART_STS.IDLEF 置 1。此时如果 USART_CTRL1.IDLEIEN 已置 1,将产生一个中断。 USART_STS.IDLEF 可通过以下软件操作清零:先读 USART_STS 寄存器,再读 USART_DAT 寄存器。

/*************************串口接收数据函数********************/
void Usart1_Receive_Data(void)
{
  DMA1_CH5->CHCFG&=~(1<<0);//关闭通道传输
  usart1_cnt=1024-DMA1_CH5->TXNUM;//获取接收到是字符长度
  if(usart1_cnt>1024)usart1_cnt=0;
  DMA1->INTSTS|=1<<17;//清除标志位
  DMA1_CH5->TXNUM=1024;//从新赋值
  DMA1_CH5->CHCFG|=1<<0;//开启闭通道传输
  usart1_flag=1;
}

/*串口中断服务函数*/
void USART1_IRQHandler(void)
{
  u8 c;
  //清除标志:先读USART_STS,再读USART_DAT;
  c=USART1->STS&1<<4;
  if(c)//空闲帧
  {
    c=USART1->DAT;
    Usart1_Receive_Data();//接收数据处理函数
  }
  USART1->STS=0;//清除标志位
}

6.实现串口终端控制LED亮灭

  通过串口调试终端配合,利用串口数据接收功能,实现串口通讯方式对开发板LED亮灭控制。

#include "n32g45x.h"
#include <stdio.h>
#include <string.h>
#include "led.h"
#include "key.h"
#include "usart.h"
#include "delay.h"
int main()
{
  u8 time=0;
  u8 key_val;
  LED_Init();
  KEY_Init();
  USART_Init(115200);
  printf("串口初始化完成\r\n");
  while(1)
  {
    key_val=Key_Scan();  
    if(key_val)
    {
      printf("串口+DMA数据发送测试示例!\r\n");
    }
    if(usart1_flag)
   {
           usart1_rx_buff[usart1_cnt]='\0';
     printf("%s,%d\r\n",usart1_rx_buff,usart1_cnt);
           if(strcmp((char *)usart1_rx_buff,"LED1_ON")==0)LED_D1=1;
          else if(strcmp((char *)usart1_rx_buff,"LED1_OFF")==0)LED_D1=0;
          else if(strcmp((char *)usart1_rx_buff,"LED2_ON")==0)LED_D2=1;
          else if(strcmp((char *)usart1_rx_buff,"LED2_OFF")==0)LED_D2=0;
          else if(strcmp((char *)usart1_rx_buff,"LED3_ON")==0)LED_D3=1;
          else if(strcmp((char *)usart1_rx_buff,"LED3_OFF")==0)LED_D3=0;
          usart1_flag=0;
  }  
    time++;
    Delay_Ms(10);
    if(time>=50)
    {
      time=0;
      LED_D1=!LED_D1;
    }
  }    
}

在这里插入图片描述在这里插入图片描述

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

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

相关文章

【云原生】nacos权限制认证

鉴权 服务端如何开启鉴权 非Docker环境 按照官方文档配置启动,默认是不需要登录的&#xff0c;这样会导致配置中心对外直接暴露。而启用鉴权之后&#xff0c;需要在使用用户名和密码登录之后&#xff0c;才能正常使用nacos。 开启鉴权之前&#xff0c;application.properti…

0115 查找算法Day4

剑指 Offer 03. 数组中重复的数字 在一个长度为 n 的数组 nums 里的所有数字都在 0&#xff5e;n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字重复了&#xff0c;也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例 1&#xff1a; …

Linux-CPU之平均负载

一般我们觉得系统变慢了&#xff0c;都会执行 top 或者 uptime 命令&#xff0c;来了解系统的负载情况。 uptime11:29:06 up 0 min, 2 users, load average: 1.21, 0.29, 0.10// 当前时间 // 系统运行时间 // 正在登录用户数 //1 分钟、5 分钟、15 分钟的平均负载概念&…

补知识点:Stream API

一、创建Stream 首先创建Stream的话&#xff0c;有四种创建方式&#xff1a; 注&#xff1a; 第一种集合的方式是最常用的 package com.atguigu.gulimall.gateway;import com.atguigu.gulimall.streamapi.Employee; import com.atguigu.gulimall.streamapi.EmployeeData; impo…

【应用】Docker

DockerDocker 的安装基本安装流程配置镜像加速Docker 常用命令镜像相关命令容器相关命令DockerfileDockerfile 常用指令Dockerfile 简单使用案例Dockerfile 构建 java 项目镜像Docker ComposeDocker compose 基本参数services 配置参数Docker 的安装 基本安装流程 使用虚拟机…

Linux JDK8下载安装

JDK安装 整体步骤介绍 操作步骤: 1 查看自己linux版本位 getconf LONG_BIT(64位) 2. 下载jdk的安装包 这里提供三种方法下载: (以jdk-8u171-linux-x64.tar.gz为例) 2.1 官网下载jdk: 官网: https://www.oracle.com/downloads/ jdk最新版本下载: https://www.oracle.com…

带你玩转序列模型之seq2seq模型定向(集束)搜索

目录 一.基础模型 二.选择最可能的句子 三.定向搜索 四.改进定向搜索 五.定向搜索的误差分析 一.基础模型 在这一周&#xff0c;你将会学习seq2seq&#xff08;sequence to sequence&#xff09;模型&#xff0c;从机器翻译到语音识别&#xff0c;它们都能起到很大的作用…

【数据结构1】数据结构的基本概念

数据结构的基本概念 数据&#xff1a;数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 数据元素、数据项&#xff1a;数据元素是数据的基本单位&#xff0c;通常作为一…

以太网 TCP协议(TCP交互过程中出现丢包时的解决机制-列举部分)

2.7.3 以太网 TCP协议&#xff08;TCP交互过程中出现丢包时的解决机制-列举部分&#xff09; 参考&#xff1a;CSDN_TCP的重传机制_博主.Pr Young&#xff0c;对描述进行了整理与结合个人的理解进行编写。 一、超时重传机制 在发送数据时&#xff0c;设定一个定时器&#xff0c…

Ubuntu下cmake使用入门

CMake是一个跨平台的安装&#xff08;编译&#xff09;工具&#xff0c;可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件。其包含自己的语法结构&#xff0c;只要按照其语法编写成CMakeLists.txt&#xff0c;然后camke程序就能对…

MAML:User Diverse Preference Modeling by Multimodal AttentiveMetric Learning

一、摘要 大多数现有的推荐系统用特征向量表示用户的偏好&#xff0c;当预测该用户对不同项目的偏好时&#xff0c;假设该特征向量是固定的。然而&#xff0c;同一个向量不能准确地捕捉用户对所有项目的不同偏好&#xff0c;特别是在考虑各种项目的不同特征时。为了解决这个问…

【应用】Kubernetes

Kubernetesk8s 安装流程安装前配置安装 docker 以及 k8s 组件初始化 k8s 集群测试使用&#xff1a;安装 kubernetes-dashboardk8s 基础概念k8s 核心技术概念k8s 内部组件k8s 中的 IP 地址K8S 服务暴露的三种方式k8s 安装流程 k8s-masterk8s-node01k8s-node02192.168.86.140192…

【编程题】【Scratch四级】2022.09 三个数排序

三个数排序 输入三个数&#xff0c;比较三个数的大小&#xff0c;并将这三个数按照从小到大的顺序说出。 1. 准备工作 &#xff08;1&#xff09;保留小猫角色&#xff0c;默认位置&#xff1b; &#xff08;2&#xff09;白色背景。 2. 功能实现 &#xff08;1&#xff…

Java基于SSM框架的教室预约申请管理系统 毕业设计

本教室管理系统主要包括系统用户管理模块、楼层信息管理模块、校内新闻管理、教室信息管理、登录模块、和退出模块等多个模块。它帮助教室管理实现了信息化、网络化,通过测试,实现了系统设计目标,相比传统的管理模式,本系统合理的利用了教室管理数据资源,有效的减少了教室管理的…

四旋翼无人机学习第13节--Padstack Editor的简单使用

文章目录0 前言1 绘制MP2120 QFN10封装焊盘(初步学习)1.1 数据手册确定焊盘种类1.2 软件设置焊盘11.3 软件设置焊盘22 绘制DM9000A LQFP48L封装焊盘(初步学习)2.1 数据手册确定焊盘种类2.2 软件设置焊盘3 绘制STC89C51 PDIP-40封装通孔焊盘(初步学习)3.1 数据手册确定焊盘种类3…

【Spring源码系列】Bean生命周期-Bean销毁

前言 Spring给我们提供了一种当bean销毁时调用某个方法的方式。那么&#xff0c;Spring底层到底是如何实现的呢&#xff1f;接下来&#xff0c;我们将从源码案例的方式来解析&#xff1a;spring如何实现当bean销毁时调用某个方法的。 一、Bean销毁介绍 bean销毁的时机 当sp…

[附源码]计算机毕业设计springboot智能衣橱APP

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

数据增强 - 当数据有限时如何使用深度学习(一)

本文是对图像的深度学习数据增强技术的全面综述前言我们都遇到过这种情况&#xff1a;您有一个可以使用机器学习模型实现的机会&#xff0c;但当您打开网络浏览器并搜索相关数据&#xff0c;很有可能&#xff0c;您会发现一个只有几百张图像的数据集。您记得最受欢迎的数据集的…

【项目_03】日历的回显、搭建热门精选、下拉加载更多、搜索框搭建 | 基于Vue3全家桶

&#x1f4ad;&#x1f4ad; ✨: 日历的回显、搭建热门精选、下拉加载更多、搜索框搭建 | 旅途拾景   &#x1f49f;&#xff1a;东非不开森的主页   &#x1f49c;: 心若有所向往&#xff0c;何惧道阻且长&#x1f49c;&#x1f49c;   &#x1f338;: 如有错误或不足之处&…

Android入门第38天-使用随鼠标移动的圆点来熟悉onTouchEvent

简介 平时包括之前的例子大量是基于TouchListener如&#xff1a;onClick这种一类的事件。 今天给大家带来的是TouchListener与OnTouchEvent的比较&#xff0c;以及多点触碰的知识点&#xff01; TouchListener是基于监听的&#xff0c;而OnTouchEvent则是基于回调的&#xff…