|
1.分析五向按键的原理图,其中按键部分,可以去参考我的 按键中断那个帖子,目前主要以ADC为主。
proteus图
LM258是一个双运放放大器,根据运放2个原则,虚短和虚断。分析得到ADCP30的电压值。
公式为:
1.在系统初始化中adc还需要加入一些平台上的初始化,在SystemInit函数中,之前的子模块初始化需要改为
//syscon_SetIvrefX32WithMask(QN_SYSCON, SYSCON_MASK_DVDD12_SW_EN, MASK_ENABLE);
//syscon_set_sysclk_src(CLK_XTAL, __XTAL);
// DC-DC
dc_dc_enable(true);
// QN platform initialization
plf_init(NORMAL_MODE, __XTAL, QN_32K_RCO, NULL, 0);
2.设置P30位ADC
syscon_SetPMCR1(QN_SYSCON, P23_GPIO_19_PIN_CTRL
| P24_GPIO_20_PIN_CTRL
| P26_GPIO_22_PIN_CTRL
| P27_GPIO_23_PIN_CTRL
| P30_AIN0_PIN_CTRL
| P31_GPIO_25_PIN_CTRL);
3.ADC的配置
void USER_ADC_configuration(void)
{
//AIN0模拟输入功能
analog_pin_enable(AIN0, MASK_ENABLE);
//设置输入模式,时钟,参考电压,分辨率和中断
adc_init(ADC_SINGLE_WITHOUT_BUF_DRV, ADC_CLK_1000000, ADC_INT_REF, ADC_12BIT);
}
4.ADC的值得读取
static void adc_test_cb(void)
{
adc_done = 1;
}
int USER_read_adc(void)
{
int ret;
adc_read_configuration read_cfg;
read_cfg.trig_src = ADC_TRIG_SOFT;
adc_done = 0;
// modify here
read_cfg.mode = BURST_MOD;
read_cfg.start_ch = AIN0;
read_cfg.end_ch = AIN0;
adc_read(&read_cfg, ADC_buf, 512, adc_test_cb);
while (adc_done == 0);
for (int i = 0; i < 512; i++)
{
ADC_RESULT_mV(ADC_buf);
}
int sum = 0;
for (int i = 0; i < 10; i++)
{
sum += ADC_buf[511 - 2*i];
}
sum = sum / 10;
ret =ADC_RESULT_mV(sum);
return ret;
5.在按键中断的回调函数里,根据读取ADC的值,判别是哪个方向。
void cb_gpio(enum gpio_pin pin)
{
int key;
if (pin == GPIO_P12)
{
key = USER_read_adc();
//printf("key_vaule = %d\r\n",key);
if(key>975 && key <990)
{
printf("mid button\r\n");
}
else if(key>815 && key <830)
{
printf("left button\r\n");
}
else if(key>605 && key <620)
{
printf("down button\r\n");
}
else if(key>395 && key <415)
{
printf("right button\r\n");
}
else if(key>190 && key <205)
{
printf("up button\r\n");
}
}
}
6.效果图:
|
|