|
本帖最后由 ilawp 于 2016-9-19 18:11 编辑
学习cube中,的确很方便,但好久不写程序恢复起来好痛苦。
目的是用stm32同步采集两路正弦波信号,频率72k,单片机是f103c8。计划用规则同步模式+dma传输,下面是一些经验与大家分享。另外发现了一个cube可能的bug
把adc1设置成dual regularsimu、、、模式之后adc2也会改成相同模式。ADC1设置为timer1的比较输出1触发。timer1的cc1最好设置成pwm模式,其它模式貌似不好用,我也没仔细试。
adc2的触发不要设置,cube生成的代码里会自动设置为软件触发。
生成的代码如下:
void MX_ADC1_Init(void)
{
ADC_MultiModeTypeDef multimode;
ADC_ChannelConfTypeDef sConfig;
/**Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/**Configure the ADC multi-mode
*/
multimode.Mode = ADC_DUALMODE_REGSIMULT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/**Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
/* ADC2 init function */
void MX_ADC2_Init(void)
{
ADC_MultiModeTypeDef multimode;
ADC_ChannelConfTypeDef sConfig;
/**Common config
*/
hadc2.Instance = ADC2;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = DISABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
/**Configure the ADC multi-mode
*/
// multimode.Mode = ADC_DUALMODE_REGSIMULT;
// if (HAL_ADCEx_MultiModeConfigChannel(&hadc2, &multimode) != HAL_OK)
// {
// Error_Handler();
// }
/**Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
在开始转换前,要先吧adc1和2再配置和启动一下(要先启动adc2)
HAL_ADC_MspInit(&hadc1);
HAL_ADC_MspInit(&hadc2);
HAL_ADC_Start(&hadc2);
然后就可以开始启动adc1和dma了
HAL_ADCEx_MultiModeStart_DMA(&hadc1,adcDataBuff,64);
这里我发现cube自动生成的代码里有问题
这一部分被我注释掉在了,在adc2的初始化里,这一步必定返回失败,然后程序就sb了。
在下面函数里面
HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode)
{
。
。
。
if ((ADC_IS_ENABLE(hadc) == RESET) &&
(ADC_IS_ENABLE(&tmphadcSlave) == RESET) &&
(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)) )
{
MODIFY_REG(hadc->Instance->CR1,
ADC_CR1_DUALMOD ,
multimode->Mode );
}
/* If one of the ADC sharing the same common group is enabled, no update */
/* could be done on neither of the multimode structure parameters. */
else
{
/* Update ADC state machine to error */
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
tmp_hal_status = HAL_ERROR;
}
/* Process unlocked */
__HAL_UNLOCK(hadc);
/* Return function status */
return tmp_hal_status;
}
#############
这里面的
(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)) )这句肯定返回false
因为
#define IS_ADC_MULTIMODE_MASTER_INSTANCE(INSTANCE) ((INSTANCE) == ADC1)
这里就变成了判断ADC2 == ADC1.肯定是false
另外在同步模式下,adc2的数据会自动发到adc1-dr的高16位,但这个是有前提的,那就是ADC1->CR2->DMA这一位必须置位,不然adc1-dr的高16位还是0。一开始单独调试adc同步模式的时候因为这个问题蛋疼了好久。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|