搜索
bottom↓
回复: 2

【经验分享】 利用coldfire的ADC模块实现按键检测 (转)

[复制链接]

出0入0汤圆

发表于 2014-5-13 11:46:20 | 显示全部楼层 |阅读模式
    现在很多的MCU都集成了片上的KBI,即键盘按键中断,它很类似于8051单片机上的外部中断INT0,INT1,原理是简单的,当按键按下时,会有个下降沿用来触发中断。比如freescale公司的s08系列通常都会集成8路的KBI,用起来非常方便。
    coldfire系列处理器有所谓的EPORT,这个片上模块可以很容易的实现KBI的功能。但常常在项目中,mcu的引脚资源很紧张,EPORT常与其他模块复用引脚,导致EPORT并不能总是用于KBI。在现在我们的这个项目中就是这样,采用mcf52211处理器,但是由于受限pcb板尺寸,我们用的LQFP64的处理器,其EPORT引脚只有3个,而我们的键盘却需要有6个按键,在这种情况下,我们采用mcf52211片上adc模块来实现按键检测。
    coldfire系列的adc模块,其功能远远超出了一般的8位单片机和arm的功能,极其强大,下面贴出的代码思路很简单,就是利用coldfire片上adc的low limit compare功能,也就是当adc转换的结果低于指定的阈值(Low limit)时,将触发low limit compare中断,利用这个中断实现按键检测。


/******************************
** File: adc.h
** MCF52211 ADC module driver header file
*********************************/
#ifndef _LZP_MCF52211_ADC_H_
#define _LZP_MCF52211_ADC_H_
extern volatile uint16 g_adcStatus;
void init_adc(uint16 llimit0,uint16 llimit1);
void start_adc();
void stop_adc();
#endif


/*********************************
** File:adc.c
** MCF52211  ADC module driver
********************************/
#include "support_common.h" /* include peripheral declarations and more */
#include "adc.h"
#include "delay.h"
#define ALL_ADC          0xFF
/* Samples Enable SDIS Register */
#define ALL_ENABLED      0x00
/* Delay in the POWER Reg by reset */
#define DEFAULT_DELAY    0x00D0
volatile uint16 g_adcStatus;
/*******************
* set mcf52211's ADC module to loop sequential mode from SAMPLE0 to SAMPLE7
* set ADC interrupt enable
* set ADC Low Limit compare mode
********************/
void init_adc(uint16 llimit0,uint16 llimit1)
{
uint8 i;

g_adcStatus=0;
MCF_GPIO_PANPAR =ALL_ADC;
//set LOW limit interrupt enable
MCF_ADC_CTRL1   = MCF_ADC_CTRL1_LLMTIE |MCF_ADC_CTRL1_SMODE(2); /* SMODE: This field controls the scan mode of the ADC module.
               For Loop sequential mode it has to be set 010 bin (2).  */
    MCF_ADC_CTRL2   = MCF_ADC_CTRL2_DIV(9);//set adc clock rate to 3MHZ
    /* The sampling order for channels */  /* ADLST1: contains an ordered list of the analog input channels to be
               converted when the next scan is initialized*/
    MCF_ADC_ADLST1 = MCF_ADC_ADLST1_SAMPLE0(0) |
          MCF_ADC_ADLST1_SAMPLE1(1) |
          MCF_ADC_ADLST1_SAMPLE2(2) |
          MCF_ADC_ADLST1_SAMPLE3(3);
    /* The sampling order for channels */
    MCF_ADC_ADLST2 = MCF_ADC_ADLST2_SAMPLE4(4) |
          MCF_ADC_ADLST2_SAMPLE5(5) |
          MCF_ADC_ADLST2_SAMPLE6(6) |
          MCF_ADC_ADLST2_SAMPLE7(7);
   /* set ADC interrupt*/
    MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK51 );
    MCF_INTC0_IMRL &=~( MCF_INTC_IMRL_MASKALL);
    MCF_INTC0_ICR51 =MCF_INTC_ICR_IP(7)+MCF_INTC_ICR_IL(2);
    /*set channel's low limit*/
    MCF_ADC_ADLLMT(0)=MCF_ADC_ADLLMT_LLMT(llimit0);
    MCF_ADC_ADLLMT(1)=MCF_ADC_ADLLMT_LLMT(llimit1);
    for(i=0;i<6;i++)
    {
     MCF_ADC_ADLLMT(i+2)=MCF_ADC_ADLLMT_LLMT(50);
    }
     /* All channels enabled */
    MCF_ADC_ADSDIS  = ALL_ENABLED;    /* ADSDIS: enables only the desired analog channels*/
    /* set the power-up delay in ADC */
    MCF_ADC_POWER   = DEFAULT_DELAY;   /* POWER: controls the power management of the ADC module*/
     /* wait until module is powered-up */
    while(MCF_ADC_POWER & MCF_ADC_POWER_PSTS0)  /* PSTS0 register: 0: ADC converter A is currently powered up,
               1: ADC converter A is currently powered down */
    ;           
    return;
}
/*
* Start the ADC module
*
* Parameters: none
*
* Return : None.
*/
void start_adc()
{
MCF_ADC_CTRL1 &= ~MCF_ADC_CTRL1_STOP0 ;
MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_START0;  /* CTRL1: is used to configure and control the ADC module.
               START0: A scan is started by writing a 1 to this bit.*/
return;
}
//stop adc module
void stop_adc()
{
MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_STOP0 ;  /* CTRL1: is used to configure and control the ADC module.
               STOP0: A scan is stoped by writing a 1 to this bit.*/
return;
}
//the adc isr
__declspec(interrupt:0) void adc_isr(void)
{
uint16 prev_status,cur_status;
if (MCF_ADC_ADSTAT & MCF_ADC_ADSTAT_LLMTI)
{
  prev_status=MCF_ADC_ADLSTAT;
  MCF_ADC_ADLSTAT =0xffff;  //clear interrupt
  MCF_ADC_ADSTAT |= MCF_ADC_ADSTAT_EOSI0;
  MCF_ADC_CTRL1&=~MCF_ADC_CTRL1_LLMTIE;
  stop_adc();
  delay_ms(50);
  start_adc();
  //wait for adc conversion finish
  while((MCF_ADC_ADSTAT&MCF_ADC_ADSTAT_EOSI0)==0);
  MCF_ADC_ADSTAT |= MCF_ADC_ADSTAT_EOSI0;
  cur_status=MCF_ADC_ADLSTAT;
  if(cur_status==prev_status)
  {
   g_adcStatus=cur_status;
  }
  else
  {
   g_adcStatus=0;
  }
  MCF_ADC_ADLSTAT =0xffff;  //clear interrupt
  MCF_ADC_CTRL1|=MCF_ADC_CTRL1_LLMTIE;
  
}
}


/***********************************
** File :test.c
** test code for adc driver
** demo the keyboard break detect
** the keyboard is connect with mcf52211's AN2~AN7
************************************/
#include "support_common.h" /* include peripheral declarations and more */
//#if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT)
/* Standard IO is only possible if Console or UART support is enabled. */
#include <stdio.h>
//#endif
#include "adc.h"
#include "uart0.h"
#define EnableInterrupts asm { move.w SR,D0; andi.l #0xF8FF,D0; move.w D0,SR;  }
int main(void)
{
int counter = 0;
unsigned char buf[30];
#if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT)
printf("Hello World in C from MCF52211 derivative on MCF52211 board\n\r");
fflush(stdout);
#endif
uart0_init(9600);
  init_adc(100,100);
  uart0_putstr((unsigned char*)("MCF52211 ADC test\n"));
  EnableInterrupts;
  start_adc();
for(;;) {   
     counter++;
     if(g_adcStatus>0)
     {
      sprintf((char*)buf,"adc result: %d\n",g_adcStatus);
      uart0_putstr(buf);
      g_adcStatus=0;
     }
}
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2014-5-13 12:39:48 | 显示全部楼层
感谢楼主的资料分享,最好把工程或者文件以附件的形式放出来!

出0入0汤圆

发表于 2014-9-5 16:08:42 | 显示全部楼层
感谢分享。            
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 23:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表