356053261 发表于 2019-6-29 00:26:12

分享一个超级简单的定时程序,几条语句完成多种定时

分享一个超级简单的定时程序,几条语句完成多种定时,
在别人的汇编程序里看到的,觉得非常好用,
以芯海MCU为载体,可以移植到其它各种MCU,


u8                ext                Task_Flag_Byte                @0x41;                //定义指定地址的变量,方便定义各种时间的定时标志位
sbit        ext         f_Task_8ms                        @0x41*8+0;                //
sbit        ext         f_Task_16ms                        @0x41*8+1;
sbit        ext         f_Task_32ms                        @0x41*8+2;
sbit        ext         f_Task_64ms                        @0x41*8+3;
sbit        ext         f_Task_128ms                @0x41*8+4;
sbit        ext         f_Task_256ms                @0x41*8+5;
sbit        ext         f_Task_512ms                @0x41*8+6;
sbit        ext         f_Task_1024ms                @0x41*8+7;



//=======================================================
//下面这段代码写在中断服务函数里面,定时8ms,也可以由其它方法得到8ms
//=======================================================
                        Time_8ms_Count ++;                                       
                       
                        asm("movfw        _Time_8ms_Count");                        //先把8ms计数送到ACC
                        asm("xorwf        _Time_Flag_Old,0");                        //ACC与旧值异或,结果先暂时放到ACC
                        asm("xorwf        _Time_Flag_Old,1");                        //再将异或后放在ACC中的结果与旧值异或,更新到旧值
                        asm("iorwf        _Time_Flag_Byte,1");                //此时的ACC还是上上条语句的结果,作为定时更新标志
                       
        //                Time_Flag_Old^= (Time_Flag_Old ^ Time_8ms_Count);
        //                Time_Flag_Byte |=(Time_Flag_Old ^ Time_8ms_Count);                //这两条C语句等同于上面的4条汇编语句,


//=======================================================
//下面这段代码写主程序的大循环里面,也可以单独写成函数后在主大循环里面调用
//=======================================================
                //更新标志前先关闭中断,防止在更新标志过程的同时在中断服务函数中也被更新,而出错
                GIE = 0;                                                               
                Task_Flag_Byte = Time_Flag_Byte;                //更新任务定时标志
                Time_Flag_Byte = 0;                                                //清中断定时标志位
                GIE = 1;                                                                //开中断



//=======================================================
//然后就可以这样调用定时的时间了,是不是很简单?
//=======================================================
                if(f_Task_512ms)                //可以这样用了
                {
                        Uart_Send_Data();
                }

356053261 发表于 2019-6-29 00:27:37

就这么几条语句,就完成从8ms到1024ms的8种定时时间了

yanyanyan168 发表于 2019-6-29 07:49:42

多谢分享

bg6agf 发表于 2019-6-29 10:00:51

标志没清。。。反复调用。。。

356053261 发表于 2019-6-29 12:35:07

bg6agf 发表于 2019-6-29 10:00
标志没清。。。反复调用。。。

Time_Flag_Byte = 0;                  
这一句,清了所有的标志

356053261 发表于 2019-6-29 12:35:45

Task_Flag_Byte = Time_Flag_Byte;                //更新任务定时标志
这一句又重新更新了时间标志

lb0857 发表于 2019-6-29 13:39:46

keil做一个工程文件发上来   {:lol:}

mcu5i51 发表于 2019-6-29 14:29:10

芯海的芯片,几代IDE就没有代码兼容过,还是用C表示一下吧

bg6agf 发表于 2019-6-29 14:52:11

356053261 发表于 2019-6-29 12:35
Time_Flag_Byte = 0;                  
这一句,清了所有的标志

我了个去原来是这么用的。。。不管3721都清啊。。你不妨学习一下RTOS里的定时的用法。。任意时间定时。而且不需要关中断。

lcw_swust 发表于 2019-6-29 16:14:07

虽然没看懂,但我觉得那两句C语言应该交换:
Time_Flag_Byte |=(Time_Flag_Old ^ Time_8ms_Count);//得到有跳变的位
Time_Flag_Old=Time_8ms_Count;//保存旧值

356053261 发表于 2019-6-29 17:43:32

bg6agf 发表于 2019-6-29 14:52
我了个去原来是这么用的。。。不管3721都清啊。。你不妨学习一下RTOS里的定时的用法。。任意时间定时。而 ...

一个大循环下来,该用的都用了,没用的也用不上

356053261 发表于 2019-6-29 17:45:36

lcw_swust 发表于 2019-6-29 16:14
虽然没看懂,但我觉得那两句C语言应该交换:
Time_Flag_Byte |=(Time_Flag_Old ^ Time_8ms_Count);//得到 ...

试过就知道了,我刚开始也看不懂,但测试后,发现确实很好用
那两条C语句也没用过,从别人的汇编移过来的,一直在用,而且非常好用

356053261 发表于 2019-6-29 17:50:00

bg6agf 发表于 2019-6-29 14:52
我了个去原来是这么用的。。。不管3721都清啊。。你不妨学习一下RTOS里的定时的用法。。任意时间定时。而 ...

不清的话,时间标志就会一直有效了,那就等同于在大循环里持续运行了
这个只是一个时间戳标志,程序里很多任务不用高速执行,需要间隔一定的时间才执行一次,这样就很好用

356053261 发表于 2019-6-29 17:51:16

mcu5i51 发表于 2019-6-29 14:29
芯海的芯片,几代IDE就没有代码兼容过,还是用C表示一下吧

芯海从5.2.0到5.4.0的汇编代码还是兼容的,就这么几条语句而已

lovecxm 发表于 2020-2-27 22:56:34

下周研究一下,神代码

十个核桃 发表于 2020-2-28 08:52:06

mark学习下

ziziy 发表于 2020-2-29 00:27:44

本帖最后由 ziziy 于 2020-2-29 00:40 编辑

    //                Time_Flag_Old^= (Time_Flag_Old ^ Time_8ms_Count);      
   //                Time_Flag_Byte |=(Time_Flag_Old ^ Time_8ms_Count);                //这两条C语句等同于上面的4条汇编语句,
                   单单看这两行代码Time_Flag_Byte值的运算结果一直是0 ,这难道正常?

dongwang_fl 发表于 2020-2-29 08:16:08

标记一下。

andyliuguohua 发表于 2020-2-29 22:24:05

主循环直接去判断Time_8ms_Count 来实现延时,是不是更简单点

zhcj66 发表于 2020-3-1 03:07:11

lz在转成c通俗点

356053261 发表于 2020-3-2 17:45:30

andyliuguohua 发表于 2020-2-29 22:24
主循环直接去判断Time_8ms_Count 来实现延时,是不是更简单点

当然可以,但那样的话,只有一个8ms的定时标志,而这几条语句却包含了8ms, 16ms, 32ms, 64ms, 128ms, 256ms,512ms, 1024ms共8个定时标志

356053261 发表于 2020-3-2 17:53:37

lcw_swust 发表于 2019-6-29 16:14
虽然没看懂,但我觉得那两句C语言应该交换:
Time_Flag_Byte |=(Time_Flag_Old ^ Time_8ms_Count);//得到 ...

是的,原来高人在此

356053261 发表于 2020-3-2 17:54:26

ziziy 发表于 2020-2-29 00:27
//                Time_Flag_Old^= (Time_Flag_Old ^ Time_8ms_Count);      
   //                ...

10楼是正确的,这两句的顺序是有问题

356053261 发表于 2020-3-2 17:54:50

zhcj66 发表于 2020-3-1 03:07
lz在转成c通俗点

请参看10楼回复

356053261 发表于 2020-3-2 17:57:57

356053261 发表于 2020-3-2 17:53
是的,原来高人在此

   //                Time_Flag_Byte |=(Time_Flag_Old ^ Time_8ms_Count);                //这两条C语句等同于上面的4条汇编语句,
//                Time_Flag_Old^= (Time_Flag_Old ^ Time_8ms_Count);      
页: [1]
查看完整版本: 分享一个超级简单的定时程序,几条语句完成多种定时