完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
` 本帖最后由 MMCU5721167 于 2017-10-19 16:30 编辑 来源 灵动MM32 前段时间有一个客户需要用到4线电阻触摸屏,为了节省一片触摸屏控制芯片,客户决定使用MCU直接控制4线电阻触摸屏,主要使用到了MM32的ADC外设资源,通过ADC采集触摸屏的X+Y+的电压,算出相对应的坐标轴,并且显示在显示屏上。所以今天将结合该例程和大家一起熟悉、了解MM32的ADC配置流程。 一、触摸屏操作原理 电阻触摸屏利用压力感应进行控制。电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层透明氧化金属(透明的导电电阻)导电层,上面再盖有一层外表面硬化处理、光滑防擦的塑料层,它的内表面也涂有一层涂层,在他们之间有许多细小的(小于1/1000英寸)的透明隔离点把两层导电层隔开绝缘。当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,在X和Y两个方向上产生信号,然后送触摸屏控制器。控制器侦测到这一接触并计算出(X,Y)的位置,再根据模拟鼠标的方式运作。这就是电阻技术触摸屏的最基本的原理。 二、MM32驱动电阻触摸屏的实现 MM32系列MCU的I/O口可以编程配置成带上拉电阻的模式,这个特点可以用来检测有无触摸。MM32的GPIO管脚连接触摸屏的Y+和X- ,连接Y+的管脚配置成内部电阻上拉模式,连接X-的管脚配置成推挽输出低电平。如果Y+为高电平,那么就是没有触摸。如果Y+为低电平,触摸屏被压下。从高到低电平的跳变可以检测触摸,可以用外部中断,在本例程中将使用ADC的单次扫描模式采集X+Y+电压。 图1. 4线电阻触摸屏坐标读取 三、MM32 ADC介绍 12 位ADC 是逐次逼近式的模拟-数字转换器(SAR A/D 转换器),且ADC转换数据分辨率可设置8-12位有效。 高达1Msps转换速率,有很多用户在计算采样频率设置时会觉得很难理解,在这里将为大家讲一下采样频率计算方法,ADC 的时钟ADCLK 由 PCLK2 分频得到ADC 的输入时钟(不得超过15MHz,它是由PCLK2 经分频产生)。分频系数可通过设置 ADCFG 寄存器的ADCPRE 位来确定,即PCLK2/(N+1)/2 分频后作为 ADC 时钟。设置 ADC 分辨率为 n 位(n=8,9,10,11,12),每个通道采样时间为 m, Fsample = FADCLK/(m + n + 1.5)。假设分辨率配置为 12bit,每个通道采样时间为 1.5T,则 Fsample =FADCLK/15。 例如:设置ADC 分辨率为n =12,每个通道采样时间m=1.5个周期,FADCLK=15MHz Fsample = FADCLK/(m + n+ 1.5)=15/(12+1.5+1.5)=1Msps 根据此配置可以得到1Msps转换速率,也就是转换时间为1us,用户可以根据项目的需求配置相对应的转换速率。 A/D转换器支持多种工作模式:单次转换、单周期扫描模式和连续转换模式。 - 单次转换模式: A/D 转换在指定通道完成一次转换。 - 单周期扫描模式: A/D 转换在所有指定通道完成一个周期(从低序号通道到高序号通道)转换。 - 连续扫描模式: A/D 转换连续执行单周期扫描模式直到软件停止 A/D 转换。 支持DMA传输,单周期扫描和连续扫描时通道转换的值存储在各自通道的数据寄存(ADDRn)中,最近一次转换的结果也会保存在 ADDATA 寄存器中。DMA传输时可以选择传输某个特定通道的数据,或者传输所有扫描通道的结果。 A/D转换的启动方式有软件设定(即在配置相关寄存器时,直接开启采样)、外部引脚触发(例如定时器捕获,EXti线)以及各个定时器启动(Timer1/2/3/4 匹配或者 TRGO 信号,在配置电机应用时需要使用定时器触发ADC采样)。 窗口比较器(模拟看门狗)允许应用程序检测输入电压是否超出了用户设定的高/低阀值值,转换结果可和指定的值相比较,当转换值和设定值相匹配时,用户可设定是否产生中断请求。 四、用MM32L373读触摸屏参数 在硬件中使用了MM32L373的ADC单周期扫描功能,使用到的GPIO分别是:PA1PA3PA4PA5,分两步读取X,Y坐标值。 //测量X+电压的GPIO配置 voidXP_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //将X+配置模拟输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); //将X-配置浮空模式 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //将Y+、Y-配置为通用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_4);//Y-输出低电平 GPIO_SetBits(GPIOA,GPIO_Pin_5); //Y+输出高电平 } //测量Y+电压的GPIO配置 voidYP_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //将Y+ 配置模拟输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); //将Y- 配置浮空模式 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //将X+、X-配置为通用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_3);//X-输出低电平 GPIO_SetBits(GPIOA,GPIO_Pin_1); //X+输出高电平 } 第一步,驱动Y+为高电平,Y-为低电平,接X+管脚配置成AD输入模式,检测X+的电压,此电压与驱动电压的比例即Y坐标和整个屏的高度比率。 /*************************************************************************** ** 函数信息:voidXP_ADC1_SingleChannel(uint8_t ADC_Channel_x) **功能描述:测量X+电压,配置ADC单次扫描通道 **输入函数:ADC_Channel_x , x为0~8 **输出函数:无 ***************************************************************************/ voidXP_ADC1_SingleChannel(uint8_t ADC_Channel_x) { ADC_InitTypeDef ADC_InitStructure; XP_GPIO_Configuration(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC1时钟 /* Initialize the ADC_PRESCARE values */ ADC_InitStructure.ADC_PRESCARE = ADC_PCLK2_PRESCARE_16;//16分频 /* Initialize the ADC_Mode member */ ADC_InitStructure.ADC_Mode = ADC_Mode_Single;//配置单通道扫描模式 /* Initialize the ADC_ContinuousConvMode member */ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换模式 /* Initialize the ADC_DataAlign member */ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐 /* Initialize the ADC_ExternalTrigConv member */ ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;//外部触发通道选择 ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_x, 0, ADC_SampleTime_1_5Cycles);//设置换换顺序和采样时间 ADC_Cmd(ADC1, ENABLE); //使能ADC1 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1软件转换启动 if(ADC_Channel_x==ADC_Channel_8) { ADC1->ADCFG|=0x04; } } 第二步,驱动X+为高电平,X-为低电平,接Y+的管脚配置成AD输入模式,检测Y+的电压,此电压与驱动电压的比例即X坐标和整个屏的宽度比率。 /*************************************************************************** ** 函数信息:void YP_ADC1_SingleChannel(uint8_tADC_Channel_x) **功能描述:测量Y+电压,配置ADC单次扫描通道 **输入函数:ADC_Channel_x , x为0~8 **输出函数:无 ***************************************************************************/ voidYP_ADC1_SingleChannel(uint8_t ADC_Channel_x) { ADC_InitTypeDef ADC_InitStructure; YP_GPIO_Configuration(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1时钟 /* Initialize the ADC_PRESCARE values */ ADC_InitStructure.ADC_PRESCARE = ADC_PCLK2_PRESCARE_16; //16分频 /* Initialize the ADC_Mode member */ ADC_InitStructure.ADC_Mode = ADC_Mode_Single; //配置单通道扫描模式 /* Initialize the ADC_ContinuousConvMode member */ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //关闭连续转换模式 /* Initialize the ADC_DataAlign member */ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐 /* Initialize the ADC_ExternalTrigConv member */ ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;//外部触发通道选择 ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1,ADC_Channel_x,0,ADC_SampleTime_1_5Cycles);//设置换换顺序和采样时间 ADC_Cmd(ADC1, ENABLE); //使能ADC1 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1软件转换启动 if(ADC_Channel_x==ADC_Channel_8) { ADC1->ADCFG|=0x04; } } 第三步:根据ADC采集到的数据做校验算法,得到触摸点坐标,并且显示在显示屏对应的区域。 图2 实验效果 ` |
|
相关推荐 |
|
只有小组成员才能发言,加入小组>>
2248个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11676 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5922 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
10953 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4571 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4297 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
964浏览 1评论
792浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 00:22 , Processed in 0.438984 second(s), Total 40, Slave 32 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号