【HC32L196PCTA测评】7.ADC+发现一个驱动文件错误+DAC测试

7.1ADC测试
ADC(Analog to Digital Converter)模拟量转换为数字量,有些外设输出的是模拟量电压,这时就需要用ADC将模拟量转换为数字量来计算,在低功耗的设备中常用来检测电池电压,HC32L196内部集成了一个12位的ADC,30个输入通道,包括26路外部管脚输入、1路内部温度传感器电压、1路1/3电源电压、1路内建BGR1.2V电压、DAC内部输出
 


使用ADC时还需要使能BGR控制寄存器
 


先来测一下内置温度传感器,这个不需要外接其它设备测起来比较方便
初始化ADC模块
 

复制

void adc_init()

{

    stc_adc_cfg_t              stcAdcCfg;

    DDL_ZERO_STRUCT(stcAdcCfg);

    ///< 开启ADC/BGR外设时钟

    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);

    Bgr_BgrEnable();

    Bgr_TempSensorEnable();

    ///< ADC 初始化配置

    stcAdcCfg.enAdcMode         = AdcSglMode;               ///<采样模式-单次

    stcAdcCfg.enAdcClkDiv       = AdcMskClkDiv1;            ///<采样分频-1

    stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle12Clk;     ///<采样周期数-12

    stcAdcCfg.enAdcRefVolSel    = AdcMskRefVolSelInBgr2p5;  ///<参考电压选择-内部2.5V

    stcAdcCfg.enAdcOpBuf        = AdcMskBufEnable;          ///<打开放大器

    stcAdcCfg.enInRef           = AdcMskInRefEnable;        ///<内部参考电压使能-开

    stcAdcCfg.enAdcAlign        = AdcAlignRight;            ///<转换结果对齐方式-右

    Adc_Init(&stcAdcCfg);

    ///< 配置单次采样通道

    Adc_CfgSglChannel(AdcAiTsInput);

    ///< 启动单次一直采样

    Adc_SGL_Always_Start(); 

}

然后就发现了一个驱动文件的错误:
写完后发现这里一直报错,已经包含了bgr.h
 


查看bgr.h发现这里居然是CRC,而我工程里正好还包含了crc.h,修改为BGR后问题解决,打开HC32L19x_DDL_Rev1.2.0.zip压缩包内的原始文件也是CRC,1.1那个也是,希 望官方后续修复吧
 


手册里有温度计算的方法
 


在主循环里打印adc和温度
 

复制

int32_t main(void)

{

    float TemF;

    uint16_t adc_trim;

    uint32_t adc_result;

    xth_init();

    //时钟分频设置

    Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);

    Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);

    flash_init();

    led_init();

    key_init();

    timer0_init();

    uart0_io_init();

    uart0_init();

    adc_init();

    adc_trim = *((unsigned short int *)0x00100C36);

    while(1)

    {

        if(TRUE == Adc_GetIrqStatus(AdcMskIrqSgl))

        {

            ///< 获取采样值

            adc_result = Adc_GetSglResult();

            TemF = 25 + 0.0795 * 2.5 * ( adc_result - adc_trim );

            printf("ADC %04X% 校准值:%04X 温度:%0.1f℃",adc_result,adc_trim,TemF);

            Adc_ClrIrqStatus(AdcMskIrqSgl);

        }

        yuyy_delay_ms(1000);

    }

}

运行效果
 


接下来测试一下外部输入,用这个游戏手柄的摇杆作为输入,选用PA00和PA01作为XY方向的输入
 


参考电压选择AVDD,采样通道0和1,初始化IO和ADC模块
 

复制

void adc_io_init()

{

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

    Gpio_SetAnalogMode(GpioPortA, GpioPin0);        //PA00 (AIN0)

    Gpio_SetAnalogMode(GpioPortA, GpioPin1);        //PA01 (AIN1)

}

void adc_init()

{

    stc_adc_cfg_t              stcAdcCfg;

    stc_adc_sqr_cfg_t          stcAdcSqrCfg;

    DDL_ZERO_STRUCT(stcAdcCfg);

    ///< 开启ADC/BGR外设时钟

    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);

    Bgr_BgrEnable();

    ///< ADC 初始化配置

    stcAdcCfg.enAdcMode         = AdcScanMode;              ///<采样模式-扫描

    stcAdcCfg.enAdcClkDiv       = AdcMskClkDiv1;            ///<采样分频-1

    stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle8Clk;      ///<采样周期数-8

    stcAdcCfg.enAdcRefVolSel    = AdcMskRefVolSelAVDD;      ///<参考电压选择-AVDD

    stcAdcCfg.enAdcOpBuf        = AdcMskBufDisable;         ///<打开放大器

    stcAdcCfg.enInRef           = AdcMskInRefDisable;       ///<内部参考电压使能-关

    stcAdcCfg.enAdcAlign        = AdcAlignRight;            ///<转换结果对齐方式-右

    Adc_Init(&stcAdcCfg); 

    

    ///< 顺序扫描模式功能及通道配置

    ///< 注意:扫描模式下,当配置转换次数为n时,转换通道的配置范围必须为[SQRCH(0)MUX,SQRCH(n-1)MUX]

    stcAdcSqrCfg.bSqrDmaTrig = FALSE;

    stcAdcSqrCfg.enResultAcc = AdcResultAccDisable;

    stcAdcSqrCfg.u8SqrCnt    = 2;

    Adc_SqrModeCfg(&stcAdcSqrCfg);



    Adc_CfgSqrChannel(AdcSQRCH0MUX, AdcExInputCH0);

    Adc_CfgSqrChannel(AdcSQRCH1MUX, AdcExInputCH1);

    

    ///< 启动顺序扫描采样

    Adc_SQR_Start();

}

在主循环中打印ADC值

复制

int32_t main(void)

{

    uint32_t adcresult0;

    uint32_t adcresult1;

    xth_init();

    //时钟分频设置

    Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);

    Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);

    

    flash_init();

    led_init();

    key_init();

    uart0_io_init();

    uart0_init();

    adc_io_init();

    adc_init();

    while(1)

    {

        if(TRUE == Adc_GetIrqStatus(AdcMskIrqSqr))

        {

            Adc_ClrIrqStatus(AdcMskIrqSqr);

            adcresult0   = Adc_GetSqrResult(AdcSQRCH0MUX);  //获取顺序扫描通道0

            adcresult1   = Adc_GetSqrResult(AdcSQRCH1MUX);  //获取顺序扫描通道1

            printf("adc0:%d     adc1:%d",adcresult0,adcresult1);

            Adc_SQR_Start();

        }

        yuyy_delay_ms(200);

    }

}

摇动摇杆在串口工具上查看打印的ADC值的变化
 


7.2DAC
DAC(Digital to Analog Converter)与ADC模数转换相反,是将数字量转换为模拟量输出,HC32L196内部集成了一个12位的单通道DAC,输出IO是PA04
 


利用DAC输出一些波形,按键切换波形,初始化IO和DAC模块
 

复制

void dac_io_init()

{

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);    // 使能GPIO模块的外设时钟

    Gpio_SetAnalogMode(GpioPortA, GpioPin4);       //PA04作为DAC的模拟输出

}



void dac_init()

{

    stc_dac_cfg_t  dac_initstruct;

    Sysctrl_SetPeripheralGate(SysctrlPeripheralDac, TRUE);     ///< 使能DAC模块的时钟

    dac_initstruct.boff_t = DacBoffDisable;

    dac_initstruct.ten_t  = DacTenDisable;

    dac_initstruct.sref_t = DacVoltageAvcc;

    dac_initstruct.wave_t = DacWaveDisable;      

    dac_initstruct.mamp_t = DacMenp4095;

    dac_initstruct.tsel_t = DacSwTriger;          ///< 软件触发方式

    dac_initstruct.align  = DacRightAlign;        ///< 右对齐

    dac_initstruct.dhr12  = 0;

    Dac_Init(&dac_initstruct);

    Dac_Cmd(TRUE);

}

生成波形

复制

void proc_dac_wave()

{

    uint8_t changed = 0;

    switch(wavetype)

    {

        case 0:

            if(wavestep > 0)

                wavestep -= 1;

            else

            {

                if(dacvalue == 0)

                    dacvalue = 255;

                else

                    dacvalue = 0;

                changed = 1;

                wavestep = 9;

            }

            break;

        case 1:

            dacvalue+=1;

            changed = 1;

            break;

        case 2:

            if(wavestep > 0)

                wavestep -= 1;

            else

            {

                wavestep = 10;

                dacvalue+=15;

                changed = 1;

            }

            break;

        case 3:

            if(wavestep < 255)

            {

                dacvalue=wavestep;

                changed = 1;

            }

            else if(wavestep > 300 && wavestep < 556)

            {

                dacvalue= 555 - wavestep;

                changed = 1;

            }

            if(wavestep < 600)

                wavestep++;

            else 

                wavestep = 0;

            break;

        case 4:

            if(wavestep < 90)

            {

                dacvalue = sinvalues[wavestep];

                changed = 1;

            }

            else

            {

                dacvalue = sinvalues[180 - wavestep];

                changed = 1;

            }

            if(wavestep < 179)

                wavestep++;

            else 

                wavestep = 0;

            break;

        case 5:

            if(wavestep < 90)

            {

                dacvalue = 127 + (sinvalues[wavestep]/2);

                changed = 1;

            }

            else

            {

                dacvalue = 128 - (sinvalues[180 - wavestep]/2);

                changed = 1;

            }

            if(wavestep < 179)

                wavestep++;

            else 

                wavestep = 0;

            break;

        case 6:

            if(wavestep < 90)

            {

                dacvalue = 127 + (sinvalues[wavestep]/2);

                changed = 1;

            }

            else if(wavestep < 180)

            {

                dacvalue = 127 + (sinvalues[180 - wavestep]/2);

                changed = 1;

            }

            else if(wavestep < 270)

            {

                dacvalue = 128 - (sinvalues[wavestep - 180]/2);

                changed = 1;

            }

            else

            {

                dacvalue = 128 - (sinvalues[360 - wavestep]/2);

                changed = 1;

            }

            if(wavestep < 359)

                wavestep++;

            else 

                wavestep = 0;

            break;

        default:

            break;

    }

    if(changed > 0)

        Dac_SetChannelData(DacRightAlign,DacBit8,dacvalue);

}

波形效果展示,不是示波器波形有点失真
 

 

 

 

 

 

 

---------------------
作者:yuyy1989
链接:https://bbs.21ic.com/icview-3319844-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值