📄 adc.c
字号:
/***********************************************Copyright (c)*********************************************
** Guangzou ZLG-MCU Development Co.,LTD.
**
** http://www.zlgmcu.com
**
**--------------File Info---------------------------------------------------------------------------------
** File name: ADC.c
** Last modified Date: 2007-11-13
** Last Version: 2.0
** Descriptions: 模数转换模块 函数实现,采用设备描述符来操作
**
**--------------------------------------------------------------------------------------------------------
** Created by: WangGuoguang
** Created date: 2007-11-08
** Version: 1.0
** Descriptions: 此头文件可在config.h中包含.
**
**--------------------------------------------------------------------------------------------------------
** Modified by: WangGuoguang
** Modified Date: 2007-11-13
** Version: 2.2
** Descriptions: 完善数据缓存处理.
**
*********************************************************************************************************/
#include "config.h" /* 系统头文件 */
#include "ADCPrivate.h" /* 软件包内部私有头文件 */
#include "ADC.h" /* 软件包内部模块头文件 */
/********************************************************************************************************
裁剪是否使用此软件包,当 ADC_FUN_LIB =0,从而不编译.
*********************************************************************************************************/
#if ADC_FUN_LIB > 0
/*********************************************************************************************************
定义操作 ADC 器件的结构体,有多个器件就需要声明多个结构体
**********************************************************************************************************/
static __ADC_INFO __ADC0_Data;
/*********************************************************************************************************
下面使用指针数组(结构体指针数组)来保存指向各个模数转换器(ADC0 ,ADC1 ...)信息结构体的指针,方便对该驱动的扩展
**********************************************************************************************************/
const __PADC_INFO __GpADCInfoData[__ADC_MAX_NUM] = {&__ADC0_Data};
/*********************************************************************************************************
下面定义了模数转换器基地址值,如果有多个ADC(ADC0 ,ADC1 ...),器件可以在该位置添加相应的基地址即可
**********************************************************************************************************/
const uint32 __GuiADCBaseAddrTab[__ADC_MAX_NUM] = {AD0_BASE_ADDR };
/*********************************************************************************************************
定义 数据缓冲区数组,以保存 ADC 器件的通道转换数值结果.
**********************************************************************************************************/
static uint8 __ADC_Data[__ADC_MAX_NUM][ADC_DATA_QUEUE_NUM];
/*********************************************************************************************************
** Function name: __adcInit
**
** Descriptions: 初始化模数转换器设备结构体,该函数被个初始化功能函数调用
** Input parameters: uiID --模数转换器ID编号
** puiParam--参数指针
** pRsv --保留指针参数,可输入NULL.
** Output parameters: OPERATE_FAIL -- 操作失败
** Returned value: OPERATE_SUCCESS -- 操作成功
** PIN_ERR -- 管脚配置错误
**
** Notice: 在每次功能配置部分,必须先调用此函数来初始化器件结构体,从而得到物理地址等信息.
*********************************************************************************************************/
static uint32 __adcInit (uint32 uiID,
uint32 *puiParam,
void *pRsv)
{
uint32 i;
volatile uint32 uiOffsetBase;
volatile uint32 *puiBaseAddr;
uint32 uiChnNum;
if ((uiID >= __ADC_MAX_NUM) || (puiParam == NULL)) { /* 检查参数有效性 */
return (uint32)(OPERATE_FAIL);
}
pRsv = pRsv ; /* 为了防止编译器警告 */
/*
* 模拟输入通道管脚设置判断
*/
for (i = 0; i < __ADC_CHN_NUM; i++) {
if (((puiParam[Chn] >> i) & 0x01) != 0 ) {
switch (i) { /* 获取通道号 */
case 0:
if (((PINSEL1 >> 12) & 0x03) != P0_22_AIN0) { /* AIN0 */
return PIN_ERR;
}
break;
case 1: /* AIN1 */
if (((PINSEL1 >> 14) & 0x03) != P0_23_AIN1) {
return PIN_ERR;
}
break;
case 2: /* AIN2 */
if (((PINSEL1 >> 16) & 0x03) != P0_24_AIN2) {
return PIN_ERR;
}
break;
case 3: /* AIN3 */
if (((PINSEL0 >> 20) & 0x03) != P0_10_AIN3) {
return PIN_ERR;
}
break;
case 4: /* AIN4 */
if (((PINSEL0 >> 22) & 0x03) != P0_11_AIN4) {
return PIN_ERR;
}
break;
case 5: /* AIN5 */
if (((PINSEL0 >> 24) & 0x03) != P0_12_AIN5) {
return PIN_ERR;
}
break;
case 6: /* AIN6 */
if (((PINSEL1 >> 18) & 0x03) != P0_25_AIN6) {
return PIN_ERR;
}
break;
case 7: /* AIN7 */
if (((PINSEL1 >> 20) & 0x03) != P0_26_AIN7) {
return PIN_ERR;
}
break;
default:
break;
}
}
}
IRQDisable(); /* 关IRQ中断 */
/*
* 初始化器件结构体信息
*/
__GpADCInfoData[uiID]->uiADCID = uiID;
__GpADCInfoData[uiID]->uiAdcState = ADC_IDLE;
/*
* 获取ADC部件的物理地址
*/
__GpADCInfoData[uiID]->uiOffsetBase = __ADC_OFFSET_BASE;
__GpADCInfoData[uiID]->puiAddrBase = (uint32*)__GuiADCBaseAddrTab[uiID];
__GpADCInfoData[uiID]->AdcQueAddr = (__PDATA_QUEUE)__ADC_Data[uiID];
/*
* 地址参数处理
*/
uiOffsetBase = __GpADCInfoData[uiID]->uiOffsetBase;
puiBaseAddr = __GpADCInfoData[uiID]->puiAddrBase;
/*
* 设置状态处理
*/
__GpADCInfoData[uiID]->uiBurst = puiParam[Burst]; /* 暂存BURST的状态. */
__GpADCInfoData[uiID]->uiStart = puiParam[Start]; /* 暂存Start的状态. */
if(puiParam[Burst] == 1) { /* 硬件控制方式,此时Burst = 1 */
puiParam[Burst] = 0; /* 先设Burst=0,启动函数中再开启 */
puiParam[Start] = 0x00; /* 再Start=0,会立即启动连续转换 */
}
if(puiParam[Burst] == 0) {
puiParam[Precision] = 10; /* 当为软件控制时,精度为10位 */
puiParam[Start] = 0x00; /* 若Start=1,会立即启动一次转换 */
}
/*
* 记录使用通道信息
*/
uiChnNum = 0;
for (i = 0; i < __ADC_CHN_NUM; i++ ) {
__GpADCInfoData[uiID]->ucDoneFlg[i] =0;
__GpADCInfoData[uiID]->ucUseChn[i] = (uint8)((puiParam[Chn] >> i) & 0x01);
uiChnNum += (__GpADCInfoData[uiID]->ucUseChn[i] == 0) ? (0) : (1);
/* 记录通道号个数值,保存在结构体*/
}
__GpADCInfoData[uiID]->uiChnNum = uiChnNum;
IRQEnable(); /* 开IRQ中断 */
/*
* 设置ADCR寄存器,不影响保留位的值.
*/
puiBaseAddr[__B_ADC_ADCR << uiOffsetBase] |= ((puiParam[Chn] << 0 ) |
((Fpclk / puiParam[ADCClk] - 1) << 8 ) |
(puiParam[Burst] << 16) |
((10 - puiParam[Precision]) << 17) |
(puiParam[PowerDown] << 21) |
(puiParam[Start] << 24) |
(puiParam[Edge] << 27));
puiBaseAddr[__B_ADC_ADCR << uiOffsetBase] &= (~(0x03 << 22)); /* 默认设置为正常模式 */
/*
* 创建AD转换结果数据队列
*/
if (QueueCreate(__ADC_Data[uiID],sizeof(__ADC_Data[uiID]),NULL,NULL) == QUEUE_OK) {
return (uint32)(OPERATE_SUCCESS);
} else {
return (uint32)(OPERATE_FAIL);
}
}
/*********************************************************************************************************
** Function name: adcInit
**
** Descriptions: 用户初始化接口函数,解释用户的字符串命令,并对ADC初始化及设置中断
** Input parameters: uiID --部件设备号 :0-ADC0;1-ADC1
** pcArg --字符串输入指针参数,输入参数格式为:关键字0=值0[空格]关键字1=值1[空格]......
** 关键字 : Chn: 可选择范围从 1~FF,务必遵从手册说明;
** ADCClk: <= 4.5MHZ,输入范围:0~4500000;
** Burst : 0 -软件控制模式,1 -硬件控制模式
** Precision:可输入范围:3~10
** PowerDown:可选择:0 -掉电模式, 1 -ADC处于正常工作模式
** Start: 启动控制选择. 根据手册数据,可选择范围:0~7
** Edge: 启动触发信号的边沿选择. 0 -下降沿, 1 -上升沿转换.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -