英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

 找回密码
 立即注册
搜索
电子烟方案单片机单片机开发深圳单片机开发
单片机方案国产单片机8位单片机电子烟方案开发
查看: 4633|回复: 0
打印 上一主题 下一主题

Multiple non-blocking delays with 1 timer

[复制链接]
跳转到指定楼层
1#
发表于 2012-8-21 14:42:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 eva 于 2012-8-21 14:43 编辑

This example shows you how to create multiple non-blocking delays with only one timer, using :
  • timer 1
  • interrupts
  • arrays of pointers to functions
  • structures
It is made for a P18F452 but it could be used with others pics with just minor adjustments.
The binary code is less than 2K, so that you can use the unlicenced mikroC compiler to build the HEX file.
/* * this source code shows how to use pic timers, interrupts, and arrays of pointers to functions * and how to make non-blocking multiples delays, using a single timer * * Bruno Gavand, march 2006 *
* * P18F452 @8Mhz, HS clock, EASYPIC2 / EASYPIC3 * pull-down on PORTB * pull-up on keyboard * enable PORTB, PORTC and PORTD LEDs * * pressing RB0 key will toggle PORTC after a 2s non-blocking delay * pressing RB1 key will toggle PORTD after a 3s non-blocking delay * * used ROM : 1676 bytes *//* * number of delayed keys, up to 255 */#define NBKEYS  2/* * struct for one key */typedef struct        {        unsigned char   flag ;          // active = 1, 0 otherwise        unsigned char   ctr ;           // counter of timer1 overflows        void            (*stop)() ;     // pointer to a function to call after delay        } KEY_STRUCT ;        KEY_STRUCT      keys[NBKEYS] ;          // struct array/* * functions that do something visible for the example */void    toggleC()        {        PORTC = ~PORTC ;        // invert PORTC (toggle LEDs)        }void    toggleD()        {        PORTD = ~PORTD ;        // invert PORTD (toggle LEDs)        }/* * start to count down d milliseconds for key i */void    keyStart(unsigned char i, unsigned long d)        {        KEY_STRUCT *k ;                k = &keys ;                          // struct pointer        if(k->flag == 0)                        // if free ?                {                d <<= 18 ;                      // multiply by 4 * 2 ^ 16                d /= 1000 ;                     // divide by 1000 because                d /= (long)Clock_Khz() ;        // clock frequency is known in Khz                k->ctr = d ;                    // assign counter                k->flag = 1 ;                   // set flag to start countdown in interrupt                }        }/* * interrupt vector */void    interrupt()        {        if(PIR1.TMR1IF)         // timer1 overflow, Fosc/(4 * 2^16) times per second                {                unsigned char i ;                                for(i = 0 ; i < NBKEYS ; i++)   // for each keys                        {                        KEY_STRUCT      *k ;                                                k = &keys ;          // get pointer to the key struct                        if(k->flag)             // if key countdown activated                                {                                if(k->ctr)      // if countdown in progress                                        {                                        k->ctr-- ;      // count down                                        }                                else                                        {                                        k->flag = 0 ;   // count down reached 0, disable                                        (k->stop)() ;   // call user's function                                        }                                }                        }                PIR1.TMR1IF = 0 ;               // reset timer1 interrupt flag                }        }/* * program starts here */void main()        {        unsigned char   i ;                ADCON1 |= 0x07;                         //  PORTA as digital I/O        PORTA = PORTB = PORTC = PORTD = 0 ;     //  clear ports        TRISA = 0 ;                             // PORTA as output        TRISB = 0b00000011 ;                    // 2 LSB of PORTB as inputs, others as outputs        TRISC = 0 ;                             // PORTC as output        TRISD = 0 ;                             // PORTD as output        keys[0].stop = toggleC ;                // assign user's function to first key        keys[1].stop = toggleD ;                // assign user's function to second key                for(i = 0 ; i < NBKEYS ; i++)           // for each keys                {                keys.flag = 0 ;              // reset struct                keys.ctr = 0 ;                }                T1CON.T1CKPS1 = 0 ;                     // no prescaler        T1CON.T1CKPS0 = 0 ;                     // on timer1        T1CON.T1OSCEN = 0 ;                     // disable timer1 oscillator        T1CON.TMR1CS = 0 ;                      // timer1 is on Fosc        T1CON.TMR1ON = 1 ;                      // start timer1        INTCON.GIE = 1 ;                        // enable global interrupts        INTCON.PEIE = 1 ;                       // enable peripheral interrupts        PIE1.TMR1IE = 1 ;                       // enable timer1 overflow interrupts        for(;;)                                 // forever                {                if(PORTB.F0)                    // if RB0 key pressed                        {                        keyStart(0, 2000) ;     // start key #0 countdown for 2000 ms                        }                else if(PORTB.F1)               // if RB1 key pressed                        {                        keyStart(1, 3000) ;     // start key #1 countdown for 3000 ms                        }                }        }
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

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

小黑屋|公司首页|Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 ( 粤ICP备09008620号 )

GMT+8, 2024-5-1 00:43 , Processed in 0.054913 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表