求助华大HC32F4A0芯片ADC连续采样问题
问题:在使用华大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;
/* PCLK2Max 240MHz */
/* PCLK4Max 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 }
/**
* @briefADC configuration, including clock configuration, initial configuration
* and channel configuration.
* @paramNone
* @retval None
*/
static void AdcConfig(void)
{
//AdcClockConfig();
AdcInitConfig();
AdcChannelConfig();
}
/**
* @briefInitializes ADC.
* @paramNone
* @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);
}
/**
* @briefConfigures ADC channel(s).
* @paramNone
* @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
}
/**
* @briefSet the pin(s) corresponding to the specified channel(s) to analog mode.
* @paramADCx Pointer to ADC instance register base.
* This parameter can be a value of the following:
* @ARGM4_ADC1: ADC unit 1 instance register base.
* @argM4_ADC2: ADC unit 2 instance register base.
* @argM4_ADC3: ADC unit 3 instance register base.
* @paramu32Channel 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++;
}
}
/**
* @briefSet specified ADC pin to analog mode.
* @paramADCx Pointer to ADC instance register base.
* This parameter can be a value of the following:
* @argM4_ADC1: ADC unit 1 instance register base.
* @argM4_ADC2: ADC unit 2 instance register base.
* @argM4_ADC3: ADC unit 3 instance register base.
* @paramu8PinNum The ADC pin number.
* This parameter can be a value of @ref ADC_Pin_Number
* @retval None
*/
static void AdcSetPinAnalogMode(const M4_ADC_TypeDef *ADCx, uint8_t u8PinNum)
{
typedef struct
{
uint8_tu8Port;
uint16_t u16Pin;
} stc_adc_pin_t;
stc_gpio_init_t stcGpioInit;
stc_adc_pin_t astcADC12 = { \
{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 = { \
{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.u8Port, astcADC3.u16Pin, &stcGpioInit);
}
else
{
(void)GPIO_Init(astcADC12.u8Port, astcADC12.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=ADC_GetValue(APP_ADC_UNIT,ADC_CH_NUM_2);
Data_channel_Q=ADC_GetValue(APP_ADC_UNIT,ADC_CH_NUM_6);
}
//------------略去一些数据处理--------------
ADC_Stop(APP_ADC_UNIT);
}
找技术支持协助877378012 毛大人跟班 发表于 2022-10-9 11:26
找技术支持协助877378012
这个人也是个代理,不是华大售后 能解决问题就好, 感觉是时钟有问题。可以抓一下时钟看看。 这个同一个通道之间信号存在干扰,怎么解决呢?
页:
[1]