本帖最后由 斑斑 于 2015-11-5 13:25 编辑
我的程序是这样的,在STM32上有FreeModbus通讯,在main程序里作为后台程序持检测续接收上位机送来的数据帧。
把定时器TIM1配制成比较输出的PWM模式,作为ADC启动的触发源。
然后把ADC1配置成外部触发启动,单次、扫描模式,采集9个通道的ADC值。
再通过DMA1搬运这组数据到指定内存,通过DMA1传送完成标志触发中断。在中断服务程序里执行计算。
另外,我用的FreeModbus通讯里还有两个中断,分别是TIM4中断和UART2中断,中断分组如下: - void NVIC_Config(void)
- {
- NVIC_InitTypeDef NVIC_InitStruct;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //2位抢占优先级,2位响应优先级
- //TIM4中断配置
- NVIC_InitStruct.NVIC_IRQChannel = TIM4_IRQn;
- NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStruct);
- //UART2中断配置
- NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStruct);
- //DMA1中断配置
- NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
- NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStruct);
- }
复制代码ADC1启动触发源TIM1是这样配置的:- /*定时器1配置函数*/
- void TIM1_Config(void)
- {
- TIM_TimeBaseInitTypeDef tbInit;
- TIM_OCInitTypeDef ocInit;
- tbInit.TIM_Period = 7200-1;
- tbInit.TIM_Prescaler = 0x0000;
- tbInit.TIM_ClockDivision = TIM_CKD_DIV1;
- tbInit.TIM_CounterMode = TIM_CounterMode_Up;
- tbInit.TIM_RepetitionCounter = 0x0000;
- TIM_TimeBaseInit(TIM1, &tbInit);
- ocInit.TIM_OCMode = TIM_OCMode_PWM1; //将定时器配置成比较输出PWM模式
- ocInit.TIM_OutputState = TIM_OutputState_Enable;//TIM_OutputState_Disable;
- ocInit.TIM_Pulse = 2000;
- ocInit.TIM_OCPolarity = TIM_OCPolarity_Low; //如果是PWM1要为Low,PWM2则为High
- TIM_OC1Init(TIM1, &ocInit);
- TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC1);
- TIM_Cmd(TIM1, ENABLE);
- TIM_CtrlPWMOutputs(TIM1, ENABLE);
- }
复制代码 Modbus程序里是这样配置TIM4程序里是这样的:- /*定时器初始化函数*/
- BOOL
- xMBPortTimersInit( USHORT usTim1Timerout50us ) //配置一个时基
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- //NVIC_InitTypeDef NVIC_InitStructure;
- //
- uint16_t PrescalerValue = 0;
- //使能定时器4时钟
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
- //定时器时间基配置说明
- //HCLK为72MHz,APB1经过2分频为36MHz
- //TIM4的时钟倍频后为72MHz(硬件自动倍频,达到最大)
- //TIM4的分频系数为3599,时间基频率为72 / (1 + Prescaler) = 20KHz,基准为50us
- //TIM最大计数值为usTim1Timerout50u
- PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1;
- //定时器4初始化
- TIM_TimeBaseStructure.TIM_Period = (uint16_t) usTim1Timerout50us;
- TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
- //预装载使能
- TIM_ARRPreloadConfig(TIM4, ENABLE);
- //清除溢出中断标志位
- TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
- //定时器4溢出中断关闭
- TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE);
- //定时器4禁能
- TIM_Cmd(TIM4, DISABLE);
- return TRUE;
- }
复制代码 现在出现的问题是这样的:这个函数一返回true,TIM1就不能正常触发ADC转换。若不返回true,通讯就不能正常进行,但是TIM1——ADC1——DMA1那一条链就能跑的通。
我把代码工程附在这里,MDK5的编译环境,我是新手,查了好久无头绪,求高手帮忙看看。不胜感激!
工程代码:
CTL_DOME.zip
(385.21 KB, 下载次数: 5)
|