3回答

0收藏

STM32上FreeModbus通讯影响其他定时器问题求助

STMCU STMCU 5010 人阅读 | 3 人回复 | 2015-10-22

本帖最后由 斑斑 于 2015-11-5 13:25 编辑

我的程序是这样的,在STM32上有FreeModbus通讯,在main程序里作为后台程序持检测续接收上位机送来的数据帧。
        把定时器TIM1配制成比较输出的PWM模式,作为ADC启动的触发源。
        然后把ADC1配置成外部触发启动,单次、扫描模式,采集9个通道的ADC值。
        再通过DMA1搬运这组数据到指定内存,通过DMA1传送完成标志触发中断。在中断服务程序里执行计算。

        另外,我用的FreeModbus通讯里还有两个中断,分别是TIM4中断和UART2中断,中断分组如下:
  1. void NVIC_Config(void)
  2. {
  3. NVIC_InitTypeDef NVIC_InitStruct;
  4. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //2位抢占优先级,2位响应优先级
  5. //TIM4中断配置
  6. NVIC_InitStruct.NVIC_IRQChannel = TIM4_IRQn;
  7. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
  8. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
  9. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  10. NVIC_Init(&NVIC_InitStruct);
  11. //UART2中断配置
  12. NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
  13. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
  14. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
  15. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  16. NVIC_Init(&NVIC_InitStruct);
  17. //DMA1中断配置
  18. NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  19. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
  20. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
  21. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  22. NVIC_Init(&NVIC_InitStruct);
  23. }
复制代码
ADC1启动触发源TIM1是这样配置的:
  1. /*定时器1配置函数*/
  2. void TIM1_Config(void)
  3. {
  4. TIM_TimeBaseInitTypeDef tbInit;
  5. TIM_OCInitTypeDef ocInit;

  6. tbInit.TIM_Period = 7200-1;
  7. tbInit.TIM_Prescaler = 0x0000;
  8. tbInit.TIM_ClockDivision = TIM_CKD_DIV1;
  9. tbInit.TIM_CounterMode = TIM_CounterMode_Up;
  10. tbInit.TIM_RepetitionCounter = 0x0000;
  11. TIM_TimeBaseInit(TIM1, &tbInit);

  12. ocInit.TIM_OCMode = TIM_OCMode_PWM1; //将定时器配置成比较输出PWM模式
  13. ocInit.TIM_OutputState = TIM_OutputState_Enable;//TIM_OutputState_Disable;
  14. ocInit.TIM_Pulse = 2000;
  15. ocInit.TIM_OCPolarity = TIM_OCPolarity_Low; //如果是PWM1要为Low,PWM2则为High
  16. TIM_OC1Init(TIM1, &ocInit);

  17. TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC1);

  18. TIM_Cmd(TIM1, ENABLE);
  19. TIM_CtrlPWMOutputs(TIM1, ENABLE);
  20. }
复制代码
Modbus程序里是这样配置TIM4程序里是这样的:
  1. /*定时器初始化函数*/
  2. BOOL
  3. xMBPortTimersInit( USHORT usTim1Timerout50us ) //配置一个时基
  4. {
  5. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  6. //NVIC_InitTypeDef NVIC_InitStructure;
  7. //
  8. uint16_t PrescalerValue = 0;

  9. //使能定时器4时钟
  10. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  11. //定时器时间基配置说明
  12. //HCLK为72MHz,APB1经过2分频为36MHz
  13. //TIM4的时钟倍频后为72MHz(硬件自动倍频,达到最大)
  14. //TIM4的分频系数为3599,时间基频率为72 / (1 + Prescaler) = 20KHz,基准为50us
  15. //TIM最大计数值为usTim1Timerout50u
  16. PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1;
  17. //定时器4初始化
  18. TIM_TimeBaseStructure.TIM_Period = (uint16_t) usTim1Timerout50us;
  19. TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
  20. TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  21. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  22. TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  23. //预装载使能
  24. TIM_ARRPreloadConfig(TIM4, ENABLE);

  25. //清除溢出中断标志位
  26. TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
  27. //定时器4溢出中断关闭
  28. TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE);
  29. //定时器4禁能
  30. TIM_Cmd(TIM4, DISABLE);
  31. return TRUE;
  32. }
复制代码
        现在出现的问题是这样的:这个函数一返回true,TIM1就不能正常触发ADC转换。若不返回true,通讯就不能正常进行,但是TIM1——ADC1——DMA1那一条链就能跑的通。

       我把代码工程附在这里,MDK5的编译环境,我是新手,查了好久无头绪,求高手帮忙看看。不胜感激!

        工程代码:
CTL_DOME.zip (385.21 KB, 下载次数: 5)
分享到:
回复

使用道具 举报

回答|共 3 个

倒序浏览

沙发

淘气坏坏

发表于 2015-10-22 16:21:15 | 只看该作者

先支持下,
板凳

hwolf1

发表于 2015-10-22 16:33:40 | 只看该作者

我只是来回帖的
地板

斑斑

发表于 2015-10-22 16:44:30 | 只看该作者

hwolf1 发表于 2015-10-22 16:33
我只是来回帖的

阿威,别光回帖呀,帮忙看看么
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条