adc键盘

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:10   880   0

本程序对应的开发板为蓝桥杯嵌入式开发板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的值,与按键的值,同时将按键的值通过数码管显示。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP