蓝桥杯嵌入式扩展板学习之ADC按键 您所在的位置:网站首页 adc按键 蓝桥杯嵌入式扩展板学习之ADC按键

蓝桥杯嵌入式扩展板学习之ADC按键

2023-09-29 00:22| 来源: 网络整理| 查看: 265

硬件模块

电路图 在这里插入图片描述 在这里插入图片描述 工作原理:根据ADC采集到不同的值判断对应的按键是否按下 K1按下:ADC读取R1对地的电压 K2按下:ADC读取R1和R2对地的电压 K3按下:ADC读取R1和R2和R3对地的电压 依次累加到K8 程序 ADC配置和之前没什么区别,唯一改变的就是采集的通道号变成ADC_Channel_5 void ADC_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //ADC GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); // ADC1 工作模式配置 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换 两者的区别在于连续转换直到所有的数据转换完成后才停止转换,而单次转换则只转换一次数据就停止,要再次触发转换才可以 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); } /***********************ADC值读取函数******************************/ //返回类型是u16 u16 btn_buff[BTN_BUFF_LEN]; //数组的类型必须是u16,才能装满一个16进制数字 u16 Get_ADC(void) { u16 temp; ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_1Cycles5); //ADC_KEY对应的是通道5 ADC_SoftwareStartConvCmd(ADC1,ENABLE); while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); temp = ADC_GetConversionValue(ADC1); ADC_SoftwareStartConvCmd(ADC1,DISABLE); return temp; }

在这里插入图片描述 官方给的这个算法:目的想的是提高AD采集的稳定性和精度,其实经过测试之后,发现完全可以不需要这个算法,我们直接读取Get_ADC()函数的返回数值即可。就当平时训练的时候扩展了一下算法的知识吧,只是比赛的时候时间比较紧张的话,可以完全不用这个算法,影响不大。

/***********************按键读取函数******************************/ //返回类型是u16 u16 Read_Btn(void) { u16 temp; //中间变量 大小应为u16 u8 i =0,j=0; //循环变量 for(i=0;i for(j=0;j temp = btn_buff[j+1]; btn_buff[j+1] = btn_buff[j]; btn_buff[j] = temp; } } } if(BTN_BUFF_LEN % 2 == 0) //判断循环次数是否偶数 { return(btn_buff[BTN_BUFF_LEN/2 -1] + btn_buff[BTN_BUFF_LEN/2]) / 2;//偶数返回中间俩个值的平均值 } else { return(btn_buff[BTN_BUFF_LEN/2]); //奇数返回中间一个数值 } } /***********************按键显示函数******************************/ //取值范围自己根据按键按下的数值设定一个范围,可能每个人板子的情况不同需要自己需要 u8 Scan_Btn(void) { u16 btn_tmp = 0; btn_tmp = Read_Btn(); //根据自己读取的adc数值设置边界范围 if(btn_tmp return 2; } else if((btn_tmp >= 0x0240) && (btn_tmp return 4; } else if((btn_tmp >= 0x0710) && (btn_tmp return 6; } else if((btn_tmp >= 0x0B60) && (btn_tmp return 8; } else { return 0; //error status & no key } } 方法1:用十六进制表示

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

while(1) { snprintf((char*)str,sizeof(str)," Button ADC:%04X ",Read_Btn()); //%04X表示显示4位16进制 LCD_DisplayStringLine(Line6,str); key_val = Scan_Btn(); if(key_val != 0) { SEG_DisplayValue(16, 16, key_val); sprintf((char*)str," Button Value:%d ",key_val); LCD_DisplayStringLine(Line7,str); } }

方法2:用十进制表示,可以更方便显示和取范围

sprintf((char*)str," Button ADC:%d ",Read_Btn()); if(btn_tmp return 2; } else if((btn_tmp >= 750) && (btn_tmp return 4; } else if((btn_tmp >= 2050) && (btn_tmp return 6; } else if((btn_tmp >= 3050) && (btn_tmp return 8; } else { return 0; //error status & no key }

注意 u16 btn_buff[BTN_BUFF_LEN]; //数组的类型必须是u16,才能装满一个16进制数字,最开始我定义为u8类型,只能最多存储到0X00FF,这样和ADC精度12位读取最大值为0x0FFF不相符



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有