原理
STM32ADC采样,我选用PA5作为ADC接口,并做了UI设计。
KEY配置
key.c
#include "key.h"
#include "SysTick.h"
//按键初始化函数
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOA,ENABLE); //使能端口时钟
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_Pin=KEY_LEFT_Pin|KEY_DOWN_Pin|KEY_RIGHT_Pin;//管脚设置
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
GPIO_Init(KEY_Port,&GPIO_InitStructure); //初始化结构体
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_Pin=KEY_UP_Pin;//管脚设置
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;//下拉
GPIO_Init(KEY_UP_Port,&GPIO_InitStructure); //初始化结构体
}
//mode=0:单次按下按键
//mode=1:连续按下按键
//返回值:0表示未有按键按下
u8 KEY_Scan(u8 mode)
{
static u8 key=1;
if(key==1&&(K_UP==1||K_DOWN==0||K_LEFT==0||K_RIGHT==0)) //任意一个按键按下
{
delay_ms(10); //消抖
key=0;
if(K_UP==1)
{
return KEY_UP;
}
else if(K_DOWN==0)
{
return KEY_DOWN;
}
else if(K_LEFT==0)
{
return KEY_LEFT;
}
else
{
return KEY_RIGHT;
}
}
else if(K_UP==0&&K_DOWN==1&&K_LEFT==1&&K_RIGHT==1) //无按键按下
{
key=1;
}
if(mode==1) //连续按键按下
{
key=1;
}
return 0;
}
key.h
#ifndef _key_H
#define _key_H
#include "system.h"
#define KEY_LEFT_Pin GPIO_Pin_4 //定义K_LEFT管脚
#define KEY_DOWN_Pin GPIO_Pin_3 //定义K_DOWN管脚
#define KEY_RIGHT_Pin GPIO_Pin_2 //定义K_RIGHT管脚
#define KEY_UP_Pin GPIO_Pin_0 //定义KEY_UP管脚
#define KEY_Port (GPIOE) //定义端口
#define KEY_UP_Port (GPIOA) //定义端口
//使用位操作定义
#define K_UP PAin(0)
#define K_DOWN PEin(3)
#define K_LEFT PEin(4)
#define K_RIGHT PEin(2)
//使用读取管脚状态库函数定义
//#define K_UP GPIO_ReadInputDataBit(KEY_UP_Port,KEY_UP_Pin)
//#define K_DOWN GPIO_ReadInputDataBit(KEY_Port,KEY_DOWN_Pin)
//#define K_LEFT GPIO_ReadInputDataBit(KEY_Port,KEY_LEFT_Pin)
//#define K_RIGHT GPIO_ReadInputDataBit(KEY_Port,KEY_RIGHT_Pin)
//定义各个按键值
#define KEY_UP 1
#define KEY_DOWN 2
#define KEY_LEFT 3
#define KEY_RIGHT 4
void KEY_Init(void);
u8 KEY_Scan(u8 mode);
#endif
ADC配置
adc.h
#ifndef _adc_H
#define _adc_H
#include "system.h"
void ADCx_Init(void);
u16 Get_ADC_Value(u8 ch,u8 times);
int Get_temp(void);
#endif
adc.c
#include "adc.h"
#include "SysTick.h"
//初始化ADC
void ADCx_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN; //模拟输入模式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//管脚设置
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;//浮空
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化结构体
//RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1复位
//RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
ADC_Cmd(ADC1, ENABLE);//开启AD转换器
}
//获取通道ch的转换值,取times次,然后平均
//ch:通道编号
//times:获取次数
//返回值:通道ch的times次转换结果平均值
u16 Get_ADC_Value(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles); //ADC1,ADC通道,480个周期,提高采样时间可以提高精确度
for(t=0;t<times;t++)
{
ADC_SoftwareStartConv(ADC1); //使能指定的ADC1的软件转换启动功能
while