[技术问答] 求助华大HC32F4A0芯片ADC连续采样问题

[复制链接]
2413|5
 楼主| lindajillduan 发表于 2022-10-8 18:32 | 显示全部楼层 |阅读模式
问题:在使用华大HC32F4A0芯片实现ADC连续采样时,发现根据用户手册算出来的连续采样间隔与实际不符。配置了ADC1的通道2与通道6两个通道,进行连续采样。系统时钟为PLLH配置为240MHz,PCLK2配置为60MHz,PCLK4配置为120MHz,但是根据用户手册使用PLL做PCLK时钟源时PCLK4与PCLK2一样为60MHz.
453376341503dc4b8c.png
9485063415047c8687.png
下面根据上图内容计算连续采样间隔:
DSSTR两个通道均选择14,采样分辨率为12位,两个通道的最小连续触发事件间隔为(13PCLK2+14PCLK2)*2+6PCLK2=60PCLK2;
那么连续采样频率=60M/60=1MHz,对频率为40kHz的信号进行采样,应该是每周期采样25次,但是实测只有12次。



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

  2. void CLK_Init(void)
  3. {
  4.     stc_clk_xtal_init_t stcXtalInit;
  5.     stc_clk_pllh_init_t stcPLLHInit;

  6.     /* PCLK2  Max 240MHz */
  7.     /* PCLK4  Max 120MHz */
  8.    
  9.     //CLK_ClkDiv((CLK_CATE_HCLK|CLK_CATE_PCLK2|CLK_CATE_PCLK4), (CLK_HCLK_DIV2|CLK_PCLK2_DIV4|CLK_PCLK4_DIV2));
  10.     CLK_ClkDiv((CLK_CATE_PCLK1|CLK_CATE_PCLK2|CLK_CATE_PCLK4), (CLK_PCLK1_DIV2|CLK_PCLK2_DIV4|CLK_PCLK4_DIV2));

  11.     CLK_XtalStructInit(&stcXtalInit);
  12.     /* Config Xtal and enable Xtal */
  13.     stcXtalInit.u8XtalMode = CLK_XTALMODE_OSC;
  14.     stcXtalInit.u8XtalDrv = CLK_XTALDRV_LOW;
  15.     stcXtalInit.u8XtalState = CLK_XTAL_ON;
  16.     stcXtalInit.u8XtalStb = CLK_XTALSTB_2MS;
  17.     CLK_XtalInit(&stcXtalInit);

  18.     (void)CLK_PLLHStructInit(&stcPLLHInit);
  19.      /*VCO = (8/1)*120 = 960MHz*/
  20.      /*PLLH = 960/4 = 240MHz*/
  21.      /*PCLK2 = 240/4 = 60MHz*/
  22.      /*PCLK4 = 240/2 = 120MHz*/

  23.     stcPLLHInit.u8PLLState = CLK_PLLH_ON;
  24.     stcPLLHInit.PLLCFGR = 0UL;
  25.     stcPLLHInit.PLLCFGR_f.PLLM = 1UL - 1UL;
  26.     stcPLLHInit.PLLCFGR_f.PLLN = 120UL - 1UL;
  27.     stcPLLHInit.PLLCFGR_f.PLLP = 4UL - 1UL;
  28.     stcPLLHInit.PLLCFGR_f.PLLQ = 4UL - 1UL;
  29.     stcPLLHInit.PLLCFGR_f.PLLR = 4UL - 1UL;
  30.     stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLLSRC_XTAL;
  31.     (void)CLK_PLLHInit(&stcPLLHInit);
  32.      /* 4 cycles for 200 ~ 250MHz */


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

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

  37.    
  38.     GPIO_SetReadWaitCycle(GPIO_READ_WAIT_4);//系统时钟变了可能需要调整
  39.     EFM_SetWaitCycle(EFM_WAIT_CYCLE_5);
  40.     CLK_SetSysClkSrc(CLK_SYSCLKSOURCE_PLLH);
  41.     //CLK_SetSysClkSrc(CLK_SYSCLKSOURCE_XTAL);  

  42.   
  43.     CLK_PERI_ClkConfig(CLK_PERI_CLK_PCLK);  
  44. }



  45. //////////--------ADC配置---------///////////

  46. #define APP_ADC_UNIT                        (M4_ADC1)
  47. #define APP_ADC_PERIP_CLK                   (PWC_FCG3_ADC1)

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

  50. #define APP_ADC_SA_SAMPLE_TIME              { 14, 14 }

  51. /**
  52. * [url=home.php?mod=space&uid=247401]@brief[/url]  ADC configuration, including clock configuration, initial configuration
  53. *         and channel configuration.
  54. * @param  None
  55. * @retval None
  56. */
  57. static void AdcConfig(void)
  58. {
  59.     //AdcClockConfig();
  60.     AdcInitConfig();
  61.     AdcChannelConfig();
  62. }


  63. /**
  64. * @brief  Initializes ADC.
  65. * @param  None
  66. * @retval None
  67. */
  68. static void AdcInitConfig(void)
  69. {
  70.     stc_adc_init_t stcInit;

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

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

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

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

  80. /**
  81. * @brief  Configures ADC channel(s).
  82. * @param  None
  83. * @retval None
  84. */
  85. static void AdcChannelConfig(void)
  86. {
  87.     uint8_t au8AdcSASplTime[] = APP_ADC_SA_SAMPLE_TIME;

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

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

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

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

  113.     u8PinNum = 0U;
  114.     while (u32Channel != 0U)
  115.     {
  116.         if ((u32Channel & 0x1UL) != 0UL)
  117.         {
  118.             AdcSetPinAnalogMode(ADCx, u8PinNum);
  119.         }

  120.         u32Channel >>= 1U;
  121.         u8PinNum++;
  122.     }
  123. }

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

  142.     stc_gpio_init_t stcGpioInit;

  143.     stc_adc_pin_t astcADC12[ADC1_CH_COUNT] = { \
  144.             {GPIO_PORT_A, GPIO_PIN_00}, {GPIO_PORT_A, GPIO_PIN_01}, \
  145.             {GPIO_PORT_A, GPIO_PIN_02}, {GPIO_PORT_A, GPIO_PIN_03}, \
  146.             {GPIO_PORT_A, GPIO_PIN_04}, {GPIO_PORT_A, GPIO_PIN_05}, \
  147.             {GPIO_PORT_A, GPIO_PIN_06}, {GPIO_PORT_A, GPIO_PIN_07}, \
  148.             {GPIO_PORT_B, GPIO_PIN_00}, {GPIO_PORT_B, GPIO_PIN_01}, \
  149.             {GPIO_PORT_C, GPIO_PIN_00}, {GPIO_PORT_C, GPIO_PIN_01}, \
  150.             {GPIO_PORT_C, GPIO_PIN_02}, {GPIO_PORT_C, GPIO_PIN_03}, \
  151.             {GPIO_PORT_C, GPIO_PIN_04}, {GPIO_PORT_C, GPIO_PIN_05}, \
  152.     };
  153.     stc_adc_pin_t astcADC3[ADC3_CH_COUNT] = { \
  154.             {GPIO_PORT_A, GPIO_PIN_00}, {GPIO_PORT_A, GPIO_PIN_01}, \
  155.             {GPIO_PORT_A, GPIO_PIN_02}, {GPIO_PORT_A, GPIO_PIN_03}, \
  156.             {GPIO_PORT_F, GPIO_PIN_06}, {GPIO_PORT_F, GPIO_PIN_07}, \
  157.             {GPIO_PORT_F, GPIO_PIN_08}, {GPIO_PORT_F, GPIO_PIN_09}, \
  158.             {GPIO_PORT_F, GPIO_PIN_10}, {GPIO_PORT_F, GPIO_PIN_03}, \
  159.             {GPIO_PORT_C, GPIO_PIN_00}, {GPIO_PORT_C, GPIO_PIN_01}, \
  160.             {GPIO_PORT_C, GPIO_PIN_02}, {GPIO_PORT_C, GPIO_PIN_03}, \
  161.             {GPIO_PORT_F, GPIO_PIN_04}, {GPIO_PORT_F, GPIO_PIN_05}, \
  162.             {GPIO_PORT_H, GPIO_PIN_02}, {GPIO_PORT_H, GPIO_PIN_03}, \
  163.             {GPIO_PORT_H, GPIO_PIN_04}, {GPIO_PORT_H, GPIO_PIN_05}, \
  164.     };

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

  167.     if (ADCx == M4_ADC3)
  168.     {
  169.         (void)GPIO_Init(astcADC3[u8PinNum].u8Port, astcADC3[u8PinNum].u16Pin, &stcGpioInit);
  170.     }
  171.     else
  172.     {
  173.         (void)GPIO_Init(astcADC12[u8PinNum].u8Port, astcADC12[u8PinNum].u16Pin, &stcGpioInit);
  174.     }
  175. }



  176. //////////--------ADC使用---------///////////


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

  180.     ADC_Start(APP_ADC_UNIT);

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

  186.     }

  187. //------------略去一些数据处理--------------
  188.     ADC_Stop(APP_ADC_UNIT);
  189.    

  190. }






毛大人跟班 发表于 2022-10-9 11:26 | 显示全部楼层
找技术支持协助  877378012
 楼主| lindajillduan 发表于 2022-10-9 15:21 来自手机 | 显示全部楼层
毛大人跟班 发表于 2022-10-9 11:26
找技术支持协助  877378012

这个人也是个代理,不是华大售后
cyclefly 发表于 2022-10-11 21:17 | 显示全部楼层
能解决问题就好,
软核硬核 发表于 2022-10-12 20:53 | 显示全部楼层
感觉是时钟有问题。可以抓一下时钟看看。
lzbf 发表于 2022-11-5 13:44 | 显示全部楼层
这个同一个通道之间信号存在干扰,怎么解决呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部