4342|0

473

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

利用coldfire的ADC模块实现按键检测 [复制链接]

http://blog.ednchina.com/bluehacker/237139/message.aspx

现在很多的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
//#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;
     }
}
}

类别:freescale | 编辑 | 删除 | 评论(0) | 阅读(129)

此帖出自NXP MCU论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表