📄 hw_adc.c
字号:
/*********************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* All Rights Reserved
* V1.00
* FileName : Hw_adc.c
* Author : lzy
* Description:
* History :
* <author> <time> <version> <desc>
* lzy 07/7/9 1.0 ORG
* lzy 07/7/29 1.1 modify ADC_start and ADC_isr
$Log: Hw_adc.c,v $
Revision 1.5 2008/06/25 06:23:18 HSL
把 AD按键检测和 ADC检测分离.
Revision 1.4 2008/06/23 09:53:13 HSL
增加注释.
Revision 1.3 2008/06/23 09:51:19 HSL
增加 AD按键的支持.
Revision 1.2 2008/06/19 04:43:29 Administrator
代码整理!
Revision 1.1.1.1 2008/05/07 04:15:08 Administrator
no message
Revision 1.2 2008/03/10 01:58:07 Hanjiang
no message
Revision 1.1.1.1 2008/03/06 13:29:04 Lingzhaojun
no message
Revision 1.5 2007/11/20 08:31:07 Linzhengyuan
代码调整
Revision 1.4 2007/11/10 04:19:44 Huangxinyu
调试修改
Revision 1.3 2007/10/15 09:00:38 Huangxinyu
根据RK27提交修改driver
Revision 1.2 2007/10/08 02:38:37 Lingzhaojun
添加版本自动注释脚本
*********************************************************************************/
#include "Hw_include.h"
#include "hw_adc.h"
#include "hw_scu.h"
static ADC_channel_t ADC_Channel;
static pADC_Callback_t pADC_Callback = NULL;
static unsigned char AdcCurrChn = 0;
unsigned short AdcValue[4] = {0x1FF, 0x1FF, 0x1FF, 0x1FF};
#define pADCReg ((pADCReg_t)APB0_ADC_BASE)
/**************************************************************************
* 函数描述: ADC 初始化
* 入口参数: 无
* 出口参数: 无
* 返回值: 无
* 注释: ADC 开启
***************************************************************************/
void ADC_PowerOnInit(void)
{
unsigned int apdfreq;
pADC_Callback = NULL;
apdfreq = Pll_get_apb_freq();
ADC_SetFreq(apdfreq);
delay_nops(100);
Scu_ClockEnable(LSADC_CLOCK);
Scu_ClockEnable(LSADC_PCLOCK);
delay_nops(100);
WriteReg32(&pADCReg->ADC_CTRL, ADC_EN);
}
/**************************************************************************
* 函数描述: ADC 反初始化
* 入口参数: 无
* 出口参数: 无
* 返回值: 无
* 注释: ADC 关闭,powerdown
***************************************************************************/
void ADC_Deinit(void)
{
pADC_Callback = NULL;
WriteReg32(&pADCReg->ADC_CTRL, 0x00);
Scu_ClockDisable(LSADC_CLOCK);
Scu_ClockDisable(LSADC_PCLOCK);
}
/**************************************************************************
* 函数描述: ADC 中断服务程序
* 入口参数: 无
* 出口参数: 无
* 返回值: 无
* 注释: 当注册ADC回调函数时,会调用此回调函数
***************************************************************************/
void ADC_Isr(void)
{
UINT32 Result;
Intr_Disable(INTC_ADC);
Result = ReadReg32(&pADCReg->ADC_DATA);
ClrRegBits32(&pADCReg->ADC_CTRL, ADC_INT | ADC_INT_EN);
if (pADC_Callback)
pADC_Callback(Result);
}
/**************************************************************************
* 函数描述: 启动ADC 转化
* 入口参数: ADC 通道号,回调函数 (回调函数可以为空)
* 出口参数: 无
* 返回值: 无
* 注释: 当回调函数为空时,中断功能不打开
* 注意当上次adc 未完成转换,会等待
***************************************************************************/
void ADC_Start(ADC_channel_t channel, pADC_Callback_t pCallback)
{
UINT32 i;
// wait for last ADC convert finished,
//
for (i = 100;i > 0;i--)
{
if (ReadReg32(&pADCReg->ADC_STATUS))
delay_nops(100);
else
break;
}
// if convert time out, reset ADC
if (0 == i)
{
Scu_ModuleReset(LSADC_RESET , TRUE);
delay_nops(400);
Scu_ModuleReset(LSADC_RESET , FALSE);
}
ADC_Channel = channel;
if (pCallback)
{
WriteReg32(&pADCReg->ADC_CTRL, ADC_INT_EN | ADC_SOC | ADC_EN | channel);
pADC_Callback = pCallback;
Intr_RegISR(INTC_ADC, ADC_Isr);
Intr_Enable(INTC_ADC);
}
else
WriteReg32(&pADCReg->ADC_CTRL, ADC_SOC | ADC_EN | channel);
}
/**************************************************************************
* 函数描述: 读ADC 转换后的数据
* 入口参数: ADC 通道号
* 出口参数: 无
* 返回值: ture: 转换完成
false: 转换未完成完成
* 注释:
***************************************************************************/
UINT32 ADC_ReadData(UINT16 *padcdata)
{
if (!ReadReg32(&pADCReg->ADC_STATUS))
{
*padcdata = (UINT16)(ReadReg32(&pADCReg->ADC_DATA) & 0x3ff);
return TRUE;
}
else
return FALSE;
}
/**************************************************************************
* 函数描述: 根据apb 频率设置ADC 转换速率
* 入口参数: apb 频率,KHz 单位
* 出口参数: 无
* 返回值: 无
* 注释: 最大12MHz
***************************************************************************/
void ADC_SetFreq(UINT32 APBnKHz)
{
UINT32 tmp;
tmp = APBnKHz / ADC_Frequence - 1;
ClrRegBits32(&pSCUReg->SCU_DIVCON, ADC_CLKDIV_MASK);
SetRegBits32(&pSCUReg->SCU_DIVCON, tmp << ADC_CLKDIV_SHL);
}
/**************************************************************************
* 函数名称: RockAdcScanning
* 函数描述: 系统adc 扫描,对四个通道的adc定时扫描
* 入口参数: 无
* 出口参数: 无
* 返回值: 无
***************************************************************************/
void RockAdcScanning(void)
{
//1注意:
/*
080623,huangsl.打开AD按键的时候,需要修改 systimer.inc中的值,改为
1-2 TICKs 检查一次AD值.按键检测时间是 AD检测时间 的 4*2 = 8倍.原因如下:
4X :检测 4个 AD通道才有一次是 AD按键.
2X :AD按键检测中为了消除AD值波动,会丢弃第一次扫描到的值.
如果AD扫描 为 1个 TICK,按键扫描时间为 8*5 = 40ms,2个TICK对应的时间为 80ms.
所以建议:
1. 没有使用的 AD 通道最好不作检测,比如没有触摸屏的 项目,只需要使用 电池检测和AD按键检测即可,
AD按键的扫描时间就可以成倍的提高,或者检测每检测两次 AD按键 然后才检测一次电池AD值.这样可以提高
AD 按键的反映时间.
2. 所有的按键检测都集中在 RockKeyScanning 函数里面,可以在这个函数里面调用多个其他检测函数,比如
ADKeyScanning.此处只作单纯的 AD 值检测 赋值到 AdcValue 数组里面.
*/
unsigned short adctemp;
INT16U adkCHn = AdcCurrChn;
if (ADC_ReadData(&adctemp))
AdcValue[AdcCurrChn] = adctemp;
AdcCurrChn++;
if (AdcCurrChn >= Adc_channel_max)
AdcCurrChn = Adc_channel0;
ADC_Start(AdcCurrChn, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -