标题: 让stm32也能像PLC一样 可以使用N多的定时器,从而不影响其他程序的运行 [打印本页]

作者: jinhua1916    时间: 2021-3-24 18:24
标题: 让stm32也能像PLC一样 可以使用N多的定时器,从而不影响其他程序的运行
让stm32 也能像PLC一样 可以使用N多的定时器,从而不影响其他程序的运行;我发现用plc做控制编程很快,用stm32 配置很麻烦。不知道大家有没有同感。一般情况下,我愿意用单片机工控板,用梯形图编程很方便。可是有时候用的地方PLC功能受到限制,在及时性和功能方面不如stm32的开发板好用。所有有的时候还是需要用单片机。为了控制方便,需要用到多个定时的地方,用单片机的定时器很浪费,所以我就做了一个可以定义出来多个软件定时器的办法,经过测试发现定时准确,使用也很方便。

作者: jinhua1916    时间: 2021-3-24 18:25
我定义了一个数组:再封装了一个函数,可以向用PLC的定时器一样来使用这个定时器;
作者: jinhua1916    时间: 2021-3-24 18:27
我定义了一个软件定时器的机构体,再封装了一个函数。就像使用PLC的定时器一样方便。
作者: jinhua1916    时间: 2021-3-24 18:32
struct students
{
        int start;
        int Count value;
        int Set value;
        int Time to mark;
}DSQ[3];
作者: jinhua1916    时间: 2021-3-24 18:33
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

        TIM_TimeBaseStructure.TIM_Period = arr;        
        TIM_TimeBaseStructure.TIM_Prescaler =psc;
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

        TIM_ITConfig(  
                TIM3, //TIM2
                TIM_IT_Update ,
                ENABLE  
                );
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);  

        TIM_Cmd(TIM3, ENABLE);
                                                         
}
作者: jinhua1916    时间: 2021-3-24 18:39
  1. void TIM3_IRQHandler(void)   
  2.    { int i=0;
  3.         if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
  4.                 {
  5.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );
  6. //                        LED0=!LED0;
  7.       
  8.                                 for (i=0;i<3;i++)
  9.                                 {
  10.                                                 if (DSQ[i].start==1)
  11.                                                 {
  12.                                                         DSQ[i].Count value++;
  13.                                                                         if(DSQ[i].Count value>=DSQ[i].dingshizhi)
  14.                                                                         {
  15.                                                                         DSQ[i].Time to mark=1;
  16.                                                                                 DSQ[i].Count value=0;
  17.                                                                         }
  18.                                                 }
  19.                                         }        



  20. }

  21. }
复制代码

作者: jinhua1916    时间: 2021-3-24 19:05
DSQ[1].Time to mark=0;
DSQ[1].start=1;

"DSQ[1].Count value=77;//77毫秒,随意定时
   
      if (DSQ[1].Time to mark==1)
      {
       LED0=1;
        DSQ[1].start=0;

      }
      
      else LED0=0;"

作者: 黄youhui    时间: 2021-3-25 08:44
硬汉的教程里面有这种功能。用滴答计时器做的,每隔1ms计入中断一次。在中断里面将所有的计数器加1,当计数器数值等于预装值时就将定时器达到标志位置1.如果是一次性的模式就在这里结束函数,如果不是一次性的那就将计数器归零重新开始。

定义一个结构体/* 定时器结构体,成员变量必须是 volatile, 否则C编译器优化时可能有问题 */
typedef struct
{
        volatile uint8_t Mode;                /* 计数器模式,0 1次性   1 自动重装*/
        volatile uint8_t Flag;                /* 定时到达标志  */
        volatile uint32_t Count;        /* 计数器 */
        volatile uint32_t PreLoad;        /* 计数器预装值 */
}SOFT_TMR;





作者: 适得府君书    时间: 2021-3-25 09:09
使用OS 创建任务更灵活。
作者: 神飞游光    时间: 2021-3-25 10:21
要是能把工程文件打包出来就更好了
作者: mvwtest    时间: 2021-3-25 10:59
是時候考慮上手RTOS了
作者: jinhua1916    时间: 2021-3-25 18:56
@ 黄youhui 。硬汉的教程里面有这种功能。我去看看。

作者: jinhua1916    时间: 2021-3-26 20:16
正点原子教的是UCOS II

作者: profile5    时间: 2021-3-28 16:06
操作系统就是这个思想哇。。
作者: wufa1986    时间: 2021-3-29 08:23
操作系统虚拟定时器




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1