高级会员

- 积分
- 602
- 金钱
- 602
- 注册时间
- 2013-10-18
- 在线时间
- 59 小时
|
基于华大L170和L130的ADC采样HAL库模块化程序,实测可用
支持国产
#include "hal_adc.h"
extern void DelayUs(uint32_t nus);/*引用到的外部接口*/
#define HAL_ADC_SAMPLE_CLK_DIV1 (0u<<2) /*!< PCLK */
#define HAL_ADC_SAMPLE_CLK_DIV2 (1u<<2) /*!< 1/2 PCLK */
#define HAL_ADC_SAMPLE_CLK_DIV4 (2u<<2) /*!< 1/4 PCLK */
#define HAL_ADC_SAMPLE_CLK_DIV8 (3u<<2) /*!< 1/8 PCLK */
#define HAL_ADC_SAMPLE_OP_ENABLE (1u<<11)/*!< 打开放大器BUF */
#define HAL_ADC_SAMPLE_OP_DISABLE (0U) /*!< 关闭放大器BUF */
/*此内部基准不是芯片的基准通道,只是adc特有的内部基准的使能即1.5V和2.5V--华大特有,本次不使用*/
#define HAL_ADC_SAMPLE_IN_REF_ENABLE (1u<<14)/*!< 内部参考电压使能 */
#define HAL_ADC_SAMPLE_IN_REF_DISABLE (0U) /*!< 内部参考电压关闭 */
typedef struct
{
uint32_t adc_conv_mode; /*! ADC转换模式*/
uint32_t adc_clk_div; /*! ADC时钟分频*/
uint32_t adc_sample_cycle; /*! ADC采样周期选择*/
uint32_t adc_ref_sel; /*! ADC参考电压选择*/
uint32_t adc_op_en; /*! ADC输入信号放大器控制使能*/
uint32_t in_ref_en; /*! ADC内部参考电压使能*/
uint32_t adc_data_align; /*! ADC转换结果对齐控制*/
}sHalAdcCfg;
/*
采用通道如果是内部的高阻通道,速率不能超过200Ksps采样率
*/
void HalAdcInit(sHalAdcTypeDef* adc_reg, sHalAdcInitTypeDef* adc_cfg)
{
sHalAdcCfg temp_cfg;
temp_cfg.adc_clk_div = HAL_ADC_SAMPLE_CLK_DIV8;/*8分频,16M主频下是2M*/
temp_cfg.adc_conv_mode = adc_cfg->adc_conv_mode;
temp_cfg.adc_data_align = adc_cfg->adc_data_align;
temp_cfg.adc_op_en = HAL_ADC_SAMPLE_OP_DISABLE;/*关闭放大器BUF*/
temp_cfg.adc_ref_sel = adc_cfg->adc_ref_sel;
temp_cfg.adc_sample_cycle = adc_cfg->adc_sample_cycle;
temp_cfg.in_ref_en = HAL_ADC_SAMPLE_IN_REF_DISABLE;/*不使用内部基准*/
adc_reg->CR0 = 0x1u; /*< ADC 使能*/
DelayUs(20);
M0P_ADC->CR0 |= (uint32_t)temp_cfg.adc_clk_div |\
(uint32_t)temp_cfg.adc_ref_sel |\
(uint32_t)temp_cfg.adc_op_en |\
(uint32_t)temp_cfg.adc_sample_cycle |\
(uint32_t)temp_cfg.in_ref_en;
M0P_ADC->CR1_f.MODE = temp_cfg.adc_conv_mode;
M0P_ADC->CR1_f.ALIGN = temp_cfg.adc_data_align;
}
/*ADC功能使能和禁能*/
void HalAdcCmd(sHalAdcTypeDef* adc_reg, eFunctionalState enable_or_disable)
{
if(DISABLE == enable_or_disable)
{
M0P_ADC->CR0_f.EN = 0u;
}
else
{
M0P_ADC->CR0_f.EN = 1u;
}
}
/*配置单次转换通道*/
void HalAdcChannelCfg(uint32_t ch)
{
if(ch >= 26u)
{
M0P_ADC->CR0_f.BUF = 1U;
}
else
{
M0P_ADC->CR0_f.BUF = 0U;
}
M0P_ADC->CR0_f.SGLMUX = ch;
}
void HalAdcSampleStart(void)
{
M0P_ADC->SGLSTART = 1u;
}
/*ADC 单次转换停止*/
void HalAdcSampleStop(void)
{
M0P_ADC->SGLSTART = 0u;
}
/*0代表采样完成,*/
uint8_t HalAdcIrqStatusGet(HAL_ADC_IRQ_STATE_TYPE_DEF irq_flag)
{
uint8_t ret = 0u;
if(M0P_ADC->IFR & irq_flag)
{
ret = 0u;
}
else
{
ret = 1u;
}
return ret;
}
void HalAdcIrqStatusClear(HAL_ADC_IRQ_STATE_TYPE_DEF irq_flag)
{
M0P_ADC->ICR &= ~(uint32_t)irq_flag;
}
void HalMcuInterVRefEnable(void)
{
M0P_BGR->CR |= 0x1u;
DelayUs(20);
}
void HalMcuInterVRefDisable(void)
{
M0P_BGR->CR &= 0x2u;
}
/*获取采样值*/
uint32_t HalAdcSampleDataGet(void)
{
return M0P_ADC->RESULT;
}
/*单次采样模式值获取*/
static uint16_t HalSampleAdcValueGet(void )
{
uint16_t ans;
uint32_t count=0;
HalMcuInterVRefEnable();/*打开BGR*/
HalAdcSampleStart();/*采样启动*/
do
{
if(HalAdcIrqStatusGet(HAL_ADC_IRQ_SGL) == 0u)
{
break;
}
count++;
}while(count<6000u);
HalAdcIrqStatusClear(HAL_ADC_IRQ_SGL);/*成功失败都清除*/
ans=(uint16_t)HalAdcSampleDataGet();/*数值获取*/
HalAdcSampleStop();/*停止采样*/
HalMcuInterVRefDisable();/*关闭BGR*/
return ans;
}
/*多次采样接口*/
uint16_t HalSampleAdcAverageGet(HAL_ADC_CH_TYPE_DEF ch,uint8_t times)
{
uint8_t i;
uint16_t ans;
uint32_t temp=0;
HalAdcChannelCfg(ch);
for(i=0;i<times;i++)
{
ans=HalSampleAdcValueGet();
temp+=(uint32_t )ans;
}
temp/=(uint32_t )times;
ans=(uint16_t )temp;
return ans;
}
#ifndef HAL_ADC_H
#define HAL_ADC_H
#include "hc32l17x.h"
#include "type.h"
/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
#define HAL_ADC_REG_BASE_ADD M0P_ADC
/*采样模式*/
#define HAL_ADC_SAMPLE_MODE_SIGNAL (0U) /*!< 单输入通道单次转换模式 */
#define HAL_ADC_SAMPLE_MODE_SCAN (1U) /*!< 多输入通道顺序/插队扫描转换模式*/
/*数据对其格式*/
#define HAL_ADC_SAMPLE_DATA_ALIGN_RIGHT (0U)
#define HAL_ADC_SAMPLE_DATA_ALIGN_LEFT (1U)
/*ADC基准源选择*/
#define HAL_ADC_SAMPLE_IN_REF_1V5 (0u<<9)/*!<内部参考电压1.5V(SPS<=200kHz)*/
#define HAL_ADC_SAMPLE_IN_REF_2V5 (1u<<9)/*!<内部参考电压2.5V(avdd>3V,SPS<=200kHz)*/
#define HAL_ADC_SAMPLE_EXTERN (2u<<9)/*!<外部输入(max avdd) PB01*/
#define HAL_ADC_SAMPLE_AVDD (3u<<9)/*!<AVDD*/
/*采样周期*/
#define HAL_ADC_SAMPLE_4CYCLE (0u<<12) /*!<4个采样时钟*/
#define HAL_ADC_SAMPLE_6CYCLE (1u<<12) /*!<4个采样时钟*/
#define HAL_ADC_SAMPLE_8CYCLE (2u<<12) /*!<4个采样时钟*/
#define HAL_ADC_SAMPLE_12CYCLE (3u<<12) /*!<4个采样时钟*/
/*ADC可选通道*/
#define HAL_ADC_EXINPUT_CH0 0U /*!<使用PA00*/
#define HAL_ADC_EXINPUT_CH1 1U
#define HAL_ADC_EXINPUT_CH2 2U
#define HAL_ADC_EXINPUT_CH3 3U
#define HAL_ADC_EXINPUT_CH4 4U
#define HAL_ADC_EXINPUT_CH5 5U
#define HAL_ADC_EXINPUT_CH6 6U
#define HAL_ADC_EXINPUT_CH7 7U /*!<使用PA07*/
#define HAL_ADC_EXINPUT_CH8 8U /*!<使用PB00*/
#define HAL_ADC_EXINPUT_CH9 9U /*!<使用PB01*/
#define HAL_ADC_EXINPUT_CH10 10U /*!<使用PC00*/
#define HAL_ADC_EXINPUT_CH11 11U
#define HAL_ADC_EXINPUT_CH12 12U
#define HAL_ADC_EXINPUT_CH13 13U
#define HAL_ADC_EXINPUT_CH14 14U
#define HAL_ADC_EXINPUT_CH15 15U /*!<使用PC05*/
#define HAL_ADC_EXINPUT_CH16 16U /*!<使用PB02*/
#define HAL_ADC_EXINPUT_CH17 17U /*!<使用PB10*/
#define HAL_ADC_EXINPUT_CH18 18U
#define HAL_ADC_EXINPUT_CH19 19U
#define HAL_ADC_EXINPUT_CH20 20U
#define HAL_ADC_EXINPUT_CH21 21U
#define HAL_ADC_EXINPUT_CH22 22U /*!<使用PB15*/
#define HAL_ADC_EXINPUT_CH23 23U /*!<使用PE15*/
#define HAL_ADC_EXINPUT_CH24 24U /*!<使用PE14*/
#define HAL_ADC_EXINPUT_CH25 25U /*!<使用PE13*/
#define HAL_ADC_DAC_CH 26U /*!<使用DAC输出(必须使用输入增益)*/
#define HAL_ADC_AVDD_DIV3_INPUT_CH 27U /*!<使用1/3 AVCC(必须使用输入增益)*/
#define HAL_ADC_TS_CH 28U /*!<使用内置温度传感器BGR_TS(必须使用输入增益)*/
#define HAL_ADC_VREF_DIV2_CH 29U /*!<使用内部基准1.2V(必须使用输入增益)*/
/*转换完成状态标志*/
#define HAL_ADC_IRQ_JQR (1u<<5) /*!<ADC插队扫描转换完成*/
#define HAL_ADC_IRQ_SQR (1u<<4) /*!<ADC顺序扫描转换完成*/
#define HAL_ADC_IRQ_REG (1u<<3) /*!<ADC转换结果比较区间内*/
#define HAL_ADC_IRQ_HT (1u<<2) /*!<ADC转换结果高于HT*/
#define HAL_ADC_IRQ_LT (1u<<1) /*!<ADC转换结果低于LT*/
#define HAL_ADC_IRQ_SGL (1u<<0) /*!<ADC单次转换完成*/
#define HAL_ADC_IRQ_STATE_TYPE_DEF uint32_t
#define HAL_ADC_CH_TYPE_DEF uint32_t
#define sHalAdcTypeDef M0P_ADC_TypeDef
typedef struct
{
uint32_t adc_conv_mode; /*! ADC采样模式*/
uint32_t adc_sample_cycle; /*采样周期设置*/
uint32_t adc_ref_sel; /*采样周期选择*/
uint32_t adc_data_align; /*! ADC转换结果对齐控制*/
} sHalAdcInitTypeDef;
/*配置*/
extern void HalAdcInit(sHalAdcTypeDef* adc_reg, sHalAdcInitTypeDef* adc_cfg);
extern void HalAdcCmd(sHalAdcTypeDef* adc_reg, eFunctionalState enable_or_disable);
/*读取数据*/
/*多次采样接口*/
extern uint16_t HalSampleAdcAverageGet(HAL_ADC_CH_TYPE_DEF ch,uint8_t times);
/*用于休眠下的功耗管理关闭内部基准会降低功耗,ADC采样必须打开内部进准电压*/
extern void HalMcuInterVRefEnable(void);
extern void HalMcuInterVRefDisable(void);
#endif
|
|