一、介绍
MDS(MindSwitch)的作用是在不借助软件干预的情况下使几个不同的外设协同工作。它连接了若干
个源模块(比如 TIMx,EXTIx 等)和目标模块(比如 ADCx,DACx 等)。通过寄存器配置可以选通任意
一个源和目标之间的连接通道,使目标模块可以成功接收到源信号并自动开始预设的动作。
支持触发通道和连接通道
可配置触发源和触发目标
触发源和触发目标可自由配置
支持外设硬件触发和软件触发
内部集成四个组合逻辑单元 CLU(Combinational Logic Unit),提供 or-or 组合逻辑操作。
可配置连接源和连接目标
连接源和连接目标可自由配置
内部集成四个组合逻辑单元 CLU(Combinational Logic Unit),提供多种组合逻辑操作。
支持不同时钟频率的触发源和触发目标之间协同工作
触发目标分为触发(trigger)和连接(connection)两种,MindSwitch 会与触发类型的目标做握手,
以确保触发源能被触发目标正确接收,如 ADC/DAC 等的外部触发。对于连接类型的目标,MindSwitch 会
将选择过后的触发源与目标直接连接,如比较器输出窗口和 GPIO 等。
以上为用户手册中关于MDS的介绍,第一次在MCU中看到MDS这样的模块,说实话没有任何经验,只是感觉是一个很有趣的功能。
二、例程研究
以ADC和EXTI triger例程为例,路径:LibSamples_MM32F5260_V0.11.3\Samples\LibSamples\MDS\MDS_ADC_EXTI_Trigger
1、ADC初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_CalibrationConfig(ADC1, 0x1FE);
ADC_StructInit(&ADC_InitStruct);
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStruct.ADC_Prescaler = ADC_Prescaler_16;
ADC_InitStruct.ADC_Mode = ADC_Mode_Scan;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_Init(ADC1, &ADC_InitStruct);
ADC_SampleTimeConfig(ADC1, ADC_Channel_1, ADC_SampleTime_240_5);
ADC_SampleTimeConfig(ADC1, ADC_Channel_4, ADC_SampleTime_240_5);
ADC_SampleTimeConfig(ADC1, ADC_Channel_5, ADC_SampleTime_240_5);
ADC_ChannelCmd(ADC1, ADC_Channel_1, ENABLE);
ADC_ChannelCmd(ADC1, ADC_Channel_4, ENABLE);
ADC_ChannelCmd(ADC1, ADC_Channel_5, ENABLE);
ADC_ExternalTrigSourceConfig(ADC1, ADC_ExtTrig_Edge_Up, ADC_ExtTrig_Shift_16);
ADC_ExternalTrigConvCmd(ADC1, ENABLE);
配置了ADC1的3个通道:1、4、5,通过外部中断触发ADC采样
2、MDS初始化
MDS_TriggerNotCluStructInit(&MDS_TriggerNotCLU);
MDS_TriggerNotCLU.MDS_Channel = MDS_TriggerOutput_ADC1_EXT_TRIGGER;
MDS_TriggerNotCLU.MDS_InputEdge = MDS_InputEdge_Both;
MDS_TriggerNotCLU.MDS_InputSource = MDS_TriggerSource_EXTI1;
MDS_TriggerNotCluInit(&MDS_TriggerNotCLU);
配置了触发源为EXTI1,触发目标为ADC1。
3、EXTI1初始化
/* K2->PB1->EXTI_Line1 */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStruct);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource1);
EXTI_StructInit(&EXTI_InitStruct);
EXTI_InitStruct.EXTI_Line = EXTI_Line1;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Event;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
K2(B1)配置为EXTI1
4、主循环
while (1)
{
while (RESET == ADC_GetFlagStatus(ADC1, ADC_FLAG_EOS))
{
}
ADC_ClearFlag(ADC1, ADC_FLAG_EOS);
if (RESET != EXTI_GetFlagStatus(EXTI_Line1))
{
EXTI_ClearFlag(EXTI_Line1);
}
Voltage[0] = (float)ADC_GetChannelConvertedValue(ADC1, ADC_Channel_1) * (float)3.3 / (float)4096.0;
Voltage[1] = (float)ADC_GetChannelConvertedValue(ADC1, ADC_Channel_4) * (float)3.3 / (float)4096.0;
Voltage[2] = (float)ADC_GetChannelConvertedValue(ADC1, ADC_Channel_5) * (float)3.3 / (float)4096.0;
printf("\r\nPA1 Voltage = %0.2f \tPA4 Voltage = %0.2f \tPA5 Voltage = %0.2f", Voltage[0], Voltage[1], Voltage[2]);
}
按下K2采集一次,否则在“while (RESET == ADC_GetFlagStatus(ADC1, ADC_FLAG_EOS))”中循环。
用其他的方法也可以实现按键触发ADC采样。使用MDS的好处应该是不用软件干预而设外协同工作,也就是用EXTI1触发ADC1不占用CPU时间,这应该和DMA的设计出发点是一致,而且还可以提高效率。毕竟是新知识,对各项配置参数没有深入了解。