adc键盘

本程序对应的开发板为蓝桥杯嵌入式开发板stm32f103rbt6,为中型mcu。开发板的矩阵键盘采用adc实现,电路图如下

通过测量adc测量电压从而得出按键位置。这里给出一个各按键对应的电压值和转换值的表[转换值=4095*电压值/(10000+电压值)]

按键                  s1         s2            s3         s4          s5          s6           s7              s8  

电阻值               0          510        1710     3310      5110       8110     12810      22810

转换值               0          198         597      1018      1384      1833       2299         2846

表中的转换值只是理论计算值,扩展板个按键的实际转换值可能与表中不同,具体转换值可通过实际的adc值进行获取。

连接

P4.5(PA5)-P5.5(AKEY)

#include "stm32f10x.h"
#include "lcd.h"
#include "stdio.h"

u32 TimingDelay = 0;

void Delay_Ms(u32 nTime);
void SEG_Init(void);
void SEG_Dis(unsigned char data1,unsigned char data2,unsigned char data3,unsigned char dot);
unsigned int Seg=0;
unsigned char Sec=0,Sec1=0,dot=0,AKEY_Long;
unsigned long Tick_ms=0,AKEY_Time;
u8 string[20];

void ADC1_Init_AKEY(void);
unsigned char AKEY_Read(void);
void Delay_AKEY(unsigned int ms);
void AKEY_Proc(void);
unsigned int ADC1_Conv(void);


int main(void)
{
  
    STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	SysTick_Config(SystemCoreClock/1000);
	SEG_Init();
	SEG_Dis(0x10,0x10,0x10,0);
	ADC1_Init_AKEY();

	
	LCD_DisplayStringLine(Line0,"                    ");	
	LCD_DisplayStringLine(Line1,"                    ");	
	LCD_DisplayStringLine(Line2,"                    ");
	LCD_DisplayStringLine(Line3,"                    ");
	LCD_DisplayStringLine(Line4,"                    ");
	LCD_DisplayStringLine(Line5,"                    ");
	LCD_DisplayStringLine(Line6,"                    ");
	LCD_DisplayStringLine(Line7,"                    ");	
	LCD_DisplayStringLine(Line8,"                    ");
	LCD_DisplayStringLine(Line9,"                    ");	
	

  while (1)
  {
   AKEY_Proc();
   SEG_Dis(16,16,Seg,0);
  }			 
}



void SEG_Init(void)
{
	  GPIO_InitTypeDef GPIO_InitStructure;
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3;
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	  GPIO_Init(GPIOA, &GPIO_InitStructure);



}
void SEG_Dis(unsigned char data1,unsigned char data2,unsigned char data3,unsigned char dot)
{
unsigned char i;
unsigned long data;
unsigned char code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

data=((code[data3]<<16)+(code[data2]<<8)+(code[data1]));

data+=(dot&1)<<23;
data+=(dot&2)<<14;
data+=(dot%4)<<5;

GPIO_ResetBits(GPIOA,GPIO_Pin_2);
for(i=0;i<24;i++)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_3);
if(data&0x800000)
GPIO_SetBits(GPIOA,GPIO_Pin_1);
else
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
data<<=1;
GPIO_SetBits(GPIOA,GPIO_Pin_3);


}

GPIO_SetBits(GPIOA,GPIO_Pin_2);



}






void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

void AKEY_Proc(void)
{
unsigned int AKey_Val;
AKey_Val=AKEY_Read();
sprintf((char*)string, "  Button Value:%d", AKey_Val);
LCD_DisplayStringLine(Line7,string);
if(AKey_Val!=AKEY_Long)
{
AKEY_Long=AKey_Val;
AKEY_Time=Tick_ms;
}
else
AKey_Val=0;
if(AKey_Val)
{
Seg=AKey_Val;


}

}

void ADC1_Init_AKEY(void){
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef  ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

/* ADC1 Configuration ------------------------------------------------------*/
  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);

  /* ADC1 regular channel14 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_13Cycles5);

  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /* Start ADC1 calibration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));

  


}

unsigned int ADC1_Conv(void)
{
/* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
  return  ADC_GetConversionValue(ADC1);
}
unsigned char AKEY_Read(void)
{
unsigned char AKey_Val=0;
unsigned int ADC_Val= ADC1_Conv();
sprintf((char*)string,"  Button ADC:%04X", ADC_Val);
LCD_DisplayStringLine(Line6,string);
if(ADC_Val<3470)
{
Delay_AKEY(100);
ADC_Val=ADC1_Conv();
if(ADC_Val<3470)
{
if(ADC_Val>2572)
AKey_Val=8;
else if(ADC_Val>2066)
AKey_Val=7;
else if(ADC_Val>1608)
AKey_Val=6;
else if(ADC_Val>1201)
AKey_Val=5;
else if(ADC_Val>807)
AKey_Val=4;
else if(ADC_Val>498)
AKey_Val=3;
else if(ADC_Val>99)
AKey_Val=2;
else 
AKey_Val=1;

}

}

return AKey_Val;

}

void Delay_AKEY(unsigned int ms)
{
 unsigned int i,j;
 for(i=0;i<ms;i++)
 for(j=0;j<7992;j++);
}
																										  











该程序在数码管的基础上进行修改的,具体实现功能是,显示adc的值,与按键的值,同时将按键的值通过数码管显示。

发布了61 篇原创文章 · 获赞 145 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qqGHJ/article/details/105304617
ADC