zoukankan      html  css  js  c++  java
  • 单片机计数脉冲

    #include <pic.h>

    __CONFIG(0x3004);//(0X30C4);
    #define T0_40MS 100    // 定义 TMR0 延时10MS 的时间常数
    #define T1_100MS 40536

    #define        DN                        RA5        //Motor rise                 2        DN
    #define        UP                        RA0        //Motor decline                13  UP
    #define        MOTA                RC5        //Motor Forward                5
    #define        MOTB                RC4        //Motor Reversal        6

    bit rise;        //正反转标志位
    bit tmrl;        //正反转标志位
    bit tmrh;        //正反转标志位

    unsigned int num;  //脉冲总个数
    unsigned int cnnt; //脉冲计数
    unsigned int timerl; //TMR1脉冲上升沿时间
    unsigned int timerh; //TMR1脉冲下降沿时间
    unsigned int cnnt_timer;//TMR1脉冲总时间
    unsigned int cnnt_tmr2;        //TMR2脉冲总时间

    unsigned int signal_key();
    unsigned int getkey() ;
    void Delay_MS(unsigned int t);
    void initial()
    {
            TRISA=0x3D;//3D;RA2=1,
            TRISC=0X0E;
            OPTION=0x87;//RA2内部中断时源
           
            INTCON=0xF0;//外围中断允许
            CMCON0 = 0X07;
            ANSEL = 0;

    //        TMR0=T0_40MS;//启动TMR0自带振荡器,分频比为1:256

            T1CON=0X22;//2启动TMR1自带振荡器,分频比为1:4关闭TRM1ON=0;
            TMR1H=T1_100MS>>8;//0X80;         //设初值
            TMR1L==T1_100MS;//0X00;
            TMR1IE=1;         //TMR1中断允许

            T2CON=0x63;  //TMR2 预分频系数为1:16 ,后分频系数为1:13,开始工作  关闭TRM2ON=0;
            PR2=239;   //TMR2的溢出值,当 TMR2 为此值+1时溢出
            TMR2IE=1;         //TMR1中断允许  50MS

            cnnt=0;
            cnnt_timer=0;
            num=10;
    }
    void Delay_MS(unsigned int t)
    {
            unsigned int a,b;
            for(a=t;a>0;a--)
            for(b=110;b>0;b--);
    }
    void Forward()
    {
            rise=1;
        MOTB=1;       
            MOTA=0;
            signal_key();
    }
    void Reversal()
    {
            rise=0;
            MOTB=0;
            MOTA=1;
            signal_key();
    }
    void Stop()
    {
            MOTA=0;
            MOTB=0;
    }
    unsigned int getkey()
    {

            if(!UP)
            {
                    while(!UP)
                    {
                            if(cnnt==num){Stop();break;}
                            Forward();
                    }
            }       
           
            if(!DN)
            {
                    while(!DN)
                    {               
                            if(cnnt==0){Stop();break;}
                            Reversal();                       
                    }
            }
           
            while(DN&&UP)
            {
                    tmrh=0;
                    tmrl=0;
                    break;
            }
           
    }
    unsigned int signal_key()
    {
    //----------------------  信号下降沿检测  --------------------------//
                 while(!RA2)                                     //再次确认信号,没有按下信号则退出
            {
                            tmrh=0;
                            if(tmrl) break;
                            tmrl=1;

                            RA1=0;
                            INTF=0;       
                            TMR1ON=0;
                            TMR2ON=1;
                            if(TMR2IF==1)//检测是否50MS错误信号,停止运行
                            {
                                    TMR2ON=0;
                                    TMR2IF=0;
                                    PR2=239;         //设初值
                                    Stop(); //停止电机运行
                                    return;
                            }
                                           
                    }
    //----------------------  信号上升沿检测  --------------------------//
                    while(RA2)
                    {   
                            tmrl=0;                       
                            if(tmrh) break;
                            tmrh=1;

                            TMR2ON=0;
                            INTF=1;
                           
                            if(TMR1IF==1)//检测是否100MS错误信号,停止运行
                            {
                                    TMR1ON=0;
                                    TMR1IF=0;
                                    TMR1H=T1_100MS>>8;//0X80;         //设初值
                                    TMR1L=T1_100MS;//0X00;
                                    Stop(); //停止电机运行
                                    return;
                            }
                            break;
                    }
    //----------------------   取出上升沿脉冲信号时间  --------------------------//
                    if(TMR1ON==0)
                    {
                            timerh=TMR1H;
                            timerl=TMR1L;
                            cnnt_timer = timerh<<8;
                            cnnt_timer += timerl;

                            TMR1IF=0;
                            TMR1H=T1_100MS>>8;//0X80;         //设初值
                            TMR1L=T1_100MS;//0X00;               
                    }
    //----------------------  取出下降沿脉冲信号时间  --------------------------//
                    if(TMR2ON==0)
                    {
                            cnnt_tmr2 = TMR2;

                            TMR2IF=0;
                            PR2=239;         //设初值       
                    }

    }

    void interrupt ISR(void)
    {
            if(INTF==1)        //脉冲开始计数,同时开启TMR1上升降计时
            {
                    INTF=0;
                    RA1=1;
                    if(rise) cnnt++;
                    else cnnt--;       
                    TMR1ON=1;
            }

            if(        TMR1IF==1)
            {
                    TMR1IF=0;
                    TMR1H=T1_100MS>>8;//0X80;         //设初值
                    TMR1L=T1_100MS;//0X00;
            }

            if(        TMR2IF==1)
            {
                    TMR2IF=0;       
                    PR2=239;         //设初值       
            }

    }
    void main()
    {
            initial();
        while (1)
        {
                    getkey();     
            }       
    }

    /************************************************************************************
    跳线设置:J7第一脚通过杜邦线连接到单片机    P3.4(T0)
    效果:转动RP1精密电位器就可看到数码管上显示的ne555此时的频率值
    晶振:12MHz                                    
    /                                                                                    
    /    4. 程序设计内容                                                                 
    /                                                                                    
    /    (1). 定时/计数器T0和T1的工作方式设置,由图可知,T0是工作在计数状态下,                    
    /            对输入的频率信号进行计数,但对工作在计数状态下的T0,                                
    /            最大计数值为fOSC/24,由于fOSC=12MHz,因此:T0的最大计数频率为250KHz。
    /            对于频率的概念就是在一秒只数脉冲的个数,即为频率值。                                 
    /            所以T1工作在定时状态下,每定时1秒中到,就停止T0的计数,                                  
    /            而从T0的计数单元中读取计数的数值,然后进行数据处理。送到数码管显示出来。                 
    /                                                                                                    
    /    (2). T1工作在定时状态下,最大定时时间为65ms,达不到1秒的定时,                                 
    /            所以采用定时50ms,共定时20次,即可完成1秒的定时功能。                                      
    *********************************************************************************************************/
    #include<reg52.h>
    #include<math.h>
    #define uchar unsigned char
    #define unit unsigned int
    #define ulong unsigned long           //(共阴)
    sbit DUAN=P2^6;     //74HC573的LE端  U5  LED的段选端
    sbit WEI=P2^7;      //74HC573的LE端  U4  LED的位选端
    uchar code dispbit[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};    // 定义位选
    uchar code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};//定义段码
    uchar dispbuf[8]={0,0,0,0,0,0,0,0}; //显示缓冲
    uchar temp[8];
    uchar dispcount;
    uchar T0count;//T0计数
    uchar timecount;//时间计数
    bit flag;
    ulong x;
    void main(void)
    {
        TMOD=0x15;
        TH0=0;
        TL0=0;
        TH1=(65536-4000)/256;
        TL1=(65536-4000)%256;
        TR1=1;
        TR0=1;
        ET0=1;
        ET1=1;
        EA=1;
        while(1)
        {
            uchar i;
            if(flag==1)
            {
                flag=0;
                x=T0count*65536+TH0*256+TL0;
                for(i=0;i<8;i++)
                {
                 temp[i]=0;
                }
                i=0;
                while(x/10)
                {
                    temp[i]=x%10;
                    x=x/10;
                    i++;
                }
                temp[i]=x;
                for(i=0;i<6;i++)
                {
                    dispbuf[i]=temp[i];
                }
                timecount=0;
                T0count=0;
                TH0=0;
                TL0=0;
                TR0=1;
            }
        }
    }
    void t0(void) interrupt 1 using 1//T0工作在计数状态下,T0的最大计数频率为250KHz
    {
        T0count++;
    }
    void t1(void) interrupt 3 using 2
    {
        TH1=(65536-4000)/256;
        TL1=(65536-4000)%256;
        timecount++;
        if(timecount==250)
        {
            TR0=0;
            timecount=0;
            flag=1;
        }
        DUAN=1;
        P0=dispcode[dispbuf[dispcount]];
        DUAN=0;
         
        WEI=1;
        P0=dispbit[dispcount];
        WEI=0;
        dispcount++;
        if(dispcount==8)
        {
            dispcount=0;
        }
    }  

  • 相关阅读:
    C#多线程参数传递
    Delphi单元测试工具Dunit介绍
    使用javascript生成文件
    Windows自动登录源码
    [Win32]一个调试器的实现
    用MASM写一个简单的实现递归操作的汇编程序,所谓递归,上课已经跟大家说清楚了,如果我们只考虑简单的只分一次的递
    C#多线程编程(4)多线程与UI操作
    在Delphi中实现类型安全的容器,Delphi泛型库DGL引介(提供源码下载) .
    delphi 中几种多线程操作方式
    C#实现WEB服务器
  • 原文地址:https://www.cnblogs.com/zym0805/p/6229800.html
Copyright © 2011-2022 走看看