打印
[技术问答]

求助华大HC32F4A0芯片ADC连续采样问题

[复制链接]
1269|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
问题:在使用华大HC32F4A0芯片实现ADC连续采样时,发现根据用户手册算出来的连续采样间隔与实际不符。配置了ADC1的通道2与通道6两个通道,进行连续采样。系统时钟为PLLH配置为240MHz,PCLK2配置为60MHz,PCLK4配置为120MHz,但是根据用户手册使用PLL做PCLK时钟源时PCLK4与PCLK2一样为60MHz.


下面根据上图内容计算连续采样间隔:
DSSTR两个通道均选择14,采样分辨率为12位,两个通道的最小连续触发事件间隔为(13PCLK2+14PCLK2)*2+6PCLK2=60PCLK2;
那么连续采样频率=60M/60=1MHz,对频率为40kHz的信号进行采样,应该是每周期采样25次,但是实测只有12次。



代码如下
//////////--------时钟配置---------///////////

void CLK_Init(void)
{
    stc_clk_xtal_init_t stcXtalInit;
    stc_clk_pllh_init_t stcPLLHInit;

    /* PCLK2  Max 240MHz */
    /* PCLK4  Max 120MHz */
   
    //CLK_ClkDiv((CLK_CATE_HCLK|CLK_CATE_PCLK2|CLK_CATE_PCLK4), (CLK_HCLK_DIV2|CLK_PCLK2_DIV4|CLK_PCLK4_DIV2));
    CLK_ClkDiv((CLK_CATE_PCLK1|CLK_CATE_PCLK2|CLK_CATE_PCLK4), (CLK_PCLK1_DIV2|CLK_PCLK2_DIV4|CLK_PCLK4_DIV2));

    CLK_XtalStructInit(&stcXtalInit);
    /* Config Xtal and enable Xtal */
    stcXtalInit.u8XtalMode = CLK_XTALMODE_OSC;
    stcXtalInit.u8XtalDrv = CLK_XTALDRV_LOW;
    stcXtalInit.u8XtalState = CLK_XTAL_ON;
    stcXtalInit.u8XtalStb = CLK_XTALSTB_2MS;
    CLK_XtalInit(&stcXtalInit);

    (void)CLK_PLLHStructInit(&stcPLLHInit);
     /*VCO = (8/1)*120 = 960MHz*/
     /*PLLH = 960/4 = 240MHz*/
     /*PCLK2 = 240/4 = 60MHz*/
     /*PCLK4 = 240/2 = 120MHz*/

    stcPLLHInit.u8PLLState = CLK_PLLH_ON;
    stcPLLHInit.PLLCFGR = 0UL;
    stcPLLHInit.PLLCFGR_f.PLLM = 1UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLN = 120UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLP = 4UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLQ = 4UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLR = 4UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLLSRC_XTAL;
    (void)CLK_PLLHInit(&stcPLLHInit);
     /* 4 cycles for 200 ~ 250MHz */


    /* Highspeed SRAM set to 1 Read/Write wait cycle */
    SRAM_SetWaitCycle(SRAM_SRAMH, SRAM_WAIT_CYCLE_1, SRAM_WAIT_CYCLE_1);

    /* SRAM1_2_3_4_backup set to 2 Read/Write wait cycle */
    SRAM_SetWaitCycle((SRAM_SRAM123 | SRAM_SRAM4 | SRAM_SRAMB), SRAM_WAIT_CYCLE_2, SRAM_WAIT_CYCLE_2);

   
    GPIO_SetReadWaitCycle(GPIO_READ_WAIT_4);//系统时钟变了可能需要调整
    EFM_SetWaitCycle(EFM_WAIT_CYCLE_5);
    CLK_SetSysClkSrc(CLK_SYSCLKSOURCE_PLLH);
    //CLK_SetSysClkSrc(CLK_SYSCLKSOURCE_XTAL);  

  
    CLK_PERI_ClkConfig(CLK_PERI_CLK_PCLK);  
}



//////////--------ADC配置---------///////////

#define APP_ADC_UNIT                        (M4_ADC1)
#define APP_ADC_PERIP_CLK                   (PWC_FCG3_ADC1)

#define APP_ADC_SA_CH                       (ADC_CH2 | ADC_CH6 ) //ADC1通道2与通道6
#define APP_ADC_SA_CH_COUNT                 (2U)

#define APP_ADC_SA_SAMPLE_TIME              { 14, 14 }

/**
* [url=home.php?mod=space&uid=247401]@brief[/url]  ADC configuration, including clock configuration, initial configuration
*         and channel configuration.
* @param  None
* @retval None
*/
static void AdcConfig(void)
{
    //AdcClockConfig();
    AdcInitConfig();
    AdcChannelConfig();
}


/**
* @brief  Initializes ADC.
* @param  None
* @retval None
*/
static void AdcInitConfig(void)
{
    stc_adc_init_t stcInit;

    /* Set a default value. */
    (void)ADC_StructInit(&stcInit);

    /* 1. Modify the default value depends on the application. It is not needed in this example. */

    stcInit.u16ScanMode    = ADC_MODE_SA_CONT;//modify scan convert mode to sequence A continuous
    /* 2. Enable ADC peripheral clock. */
    PWC_Fcg3PeriphClockCmd(APP_ADC_PERIP_CLK, Enable);

    /* 3. Initializes ADC. */
    (void)ADC_Init(APP_ADC_UNIT, &stcInit);
}

/**
* @brief  Configures ADC channel(s).
* @param  None
* @retval None
*/
static void AdcChannelConfig(void)
{
    uint8_t au8AdcSASplTime[] = APP_ADC_SA_SAMPLE_TIME;

    /* 1. Set the ADC pin to analog input mode. */
    AdcSetChannelPinAnalogMode(APP_ADC_UNIT, APP_ADC_SA_CH);

    /* 2. Enable the ADC channels. */
    (void)ADC_ChannelCmd(APP_ADC_UNIT, ADC_SEQ_A, \
                         APP_ADC_SA_CH, au8AdcSASplTime, \
                         Enable);

    /* 3. Set the number of averaging sampling and enable the channel, if needed. */
#if (defined APP_ADC_AVG_CH) && (APP_ADC_AVG_CH != 0U)
    ADC_AvgChannelConfig(APP_ADC_UNIT, APP_ADC_AVG_CNT);
    ADC_AvgChannelCmd(APP_ADC_UNIT, APP_ADC_AVG_CH, Enable);
#endif
}

/**
* @brief  Set the pin(s) corresponding to the specified channel(s) to analog mode.
* @param  [in]  ADCx                   Pointer to ADC instance register base.
*                                      This parameter can be a value of the following:
*   [url=home.php?mod=space&uid=2817080]@ARG[/url]  M4_ADC1:                     ADC unit 1 instance register base.
*   @arg  M4_ADC2:                     ADC unit 2 instance register base.
*   @arg  M4_ADC3:                     ADC unit 3 instance register base.
* @param  [in]  u32Channel             The specified channel(s).
* @retval None
*/
static void AdcSetChannelPinAnalogMode(const M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
{
    uint8_t u8PinNum;

    u8PinNum = 0U;
    while (u32Channel != 0U)
    {
        if ((u32Channel & 0x1UL) != 0UL)
        {
            AdcSetPinAnalogMode(ADCx, u8PinNum);
        }

        u32Channel >>= 1U;
        u8PinNum++;
    }
}

/**
* @brief  Set specified ADC pin to analog mode.
* @param  [in]  ADCx                   Pointer to ADC instance register base.
*                                      This parameter can be a value of the following:
*   @arg  M4_ADC1:                     ADC unit 1 instance register base.
*   @arg  M4_ADC2:                     ADC unit 2 instance register base.
*   @arg  M4_ADC3:                     ADC unit 3 instance register base.
* @param  [in]  u8PinNum               The ADC pin number.
*                                      This parameter can be a value of [url=home.php?mod=space&uid=144993]@ref[/url] ADC_Pin_Number
* @retval None
*/
static void AdcSetPinAnalogMode(const M4_ADC_TypeDef *ADCx, uint8_t u8PinNum)
{
    typedef struct
    {
        uint8_t  u8Port;
        uint16_t u16Pin;
    } stc_adc_pin_t;

    stc_gpio_init_t stcGpioInit;

    stc_adc_pin_t astcADC12[ADC1_CH_COUNT] = { \
            {GPIO_PORT_A, GPIO_PIN_00}, {GPIO_PORT_A, GPIO_PIN_01}, \
            {GPIO_PORT_A, GPIO_PIN_02}, {GPIO_PORT_A, GPIO_PIN_03}, \
            {GPIO_PORT_A, GPIO_PIN_04}, {GPIO_PORT_A, GPIO_PIN_05}, \
            {GPIO_PORT_A, GPIO_PIN_06}, {GPIO_PORT_A, GPIO_PIN_07}, \
            {GPIO_PORT_B, GPIO_PIN_00}, {GPIO_PORT_B, GPIO_PIN_01}, \
            {GPIO_PORT_C, GPIO_PIN_00}, {GPIO_PORT_C, GPIO_PIN_01}, \
            {GPIO_PORT_C, GPIO_PIN_02}, {GPIO_PORT_C, GPIO_PIN_03}, \
            {GPIO_PORT_C, GPIO_PIN_04}, {GPIO_PORT_C, GPIO_PIN_05}, \
    };
    stc_adc_pin_t astcADC3[ADC3_CH_COUNT] = { \
            {GPIO_PORT_A, GPIO_PIN_00}, {GPIO_PORT_A, GPIO_PIN_01}, \
            {GPIO_PORT_A, GPIO_PIN_02}, {GPIO_PORT_A, GPIO_PIN_03}, \
            {GPIO_PORT_F, GPIO_PIN_06}, {GPIO_PORT_F, GPIO_PIN_07}, \
            {GPIO_PORT_F, GPIO_PIN_08}, {GPIO_PORT_F, GPIO_PIN_09}, \
            {GPIO_PORT_F, GPIO_PIN_10}, {GPIO_PORT_F, GPIO_PIN_03}, \
            {GPIO_PORT_C, GPIO_PIN_00}, {GPIO_PORT_C, GPIO_PIN_01}, \
            {GPIO_PORT_C, GPIO_PIN_02}, {GPIO_PORT_C, GPIO_PIN_03}, \
            {GPIO_PORT_F, GPIO_PIN_04}, {GPIO_PORT_F, GPIO_PIN_05}, \
            {GPIO_PORT_H, GPIO_PIN_02}, {GPIO_PORT_H, GPIO_PIN_03}, \
            {GPIO_PORT_H, GPIO_PIN_04}, {GPIO_PORT_H, GPIO_PIN_05}, \
    };

    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;

    if (ADCx == M4_ADC3)
    {
        (void)GPIO_Init(astcADC3[u8PinNum].u8Port, astcADC3[u8PinNum].u16Pin, &stcGpioInit);
    }
    else
    {
        (void)GPIO_Init(astcADC12[u8PinNum].u8Port, astcADC12[u8PinNum].u16Pin, &stcGpioInit);
    }
}



//////////--------ADC使用---------///////////


unsigned char ISO6C_deal_ADC(unsigned int timeout,unsigned int decode_len,unsigned int head)
{
//------------略去一些定义和数据处理--------------

    ADC_Start(APP_ADC_UNIT);

    for(i=0;i<rcv_len;i++)
    {
       while(!ADC_SeqGetStatus(APP_ADC_UNIT,ADC_SEQ_FLAG_EOCA));
       Data_channel_I[i]=ADC_GetValue(APP_ADC_UNIT,ADC_CH_NUM_2);
       Data_channel_Q[i]=ADC_GetValue(APP_ADC_UNIT,ADC_CH_NUM_6);     

    }

//------------略去一些数据处理--------------
    ADC_Stop(APP_ADC_UNIT);
   

}






使用特权

评论回复
沙发
毛大人跟班| | 2022-10-9 11:26 | 只看该作者
找技术支持协助  877378012

使用特权

评论回复
板凳
lindajillduan|  楼主 | 2022-10-9 15:21 | 只看该作者
毛大人跟班 发表于 2022-10-9 11:26
找技术支持协助  877378012

这个人也是个代理,不是华大售后

使用特权

评论回复
地板
cyclefly| | 2022-10-11 21:17 | 只看该作者
能解决问题就好,

使用特权

评论回复
5
软核硬核| | 2022-10-12 20:53 | 只看该作者
感觉是时钟有问题。可以抓一下时钟看看。

使用特权

评论回复
6
lzbf| | 2022-11-5 13:44 | 只看该作者
这个同一个通道之间信号存在干扰,怎么解决呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

1

粉丝