51单片机输出周期脉冲方波(利用定时器)

要求如下:系统接4个按键, 1号键按下时P1.0引脚输出500ms周期脉冲方波信号, 2 号键输出50ms,3号健输出5ms, 4号键按下输出1ms。

搞个定时器就行了,按下一个键定时器改变周期,然后在定时器里面输出高低电平

定时器开启一个2.5ms的中断(因为最低周期是5ms,半个周期翻转一次),中断里计数累加,达到设定计数值上限就翻转IO。通过按键来控制计数的上限值:5ms对应的是是1,50ms对应的是10, 500ms对应的是250.
500ms的周期很长,已经接近51能定时的上限(12M时钟下),理论上也还是能用定时器中断直接实现250ms的周期,但假如题目再稍稍改大一点点,这种方式就不适用了,但计数累加的方式,无论多长的周期,都没问题。

不知道单片机的类型 也不知道时钟的频率 我只简单写个了大体思路 题主根据这个思路改一下吧

#include <reg52.h>

//定义输出和按键使用的io口
sbit out=P1^0;
sbit key1=P1^1;
sbit key2=P1^2;
sbit key3=P1^3;
sbit key4=P1^4;

//time负责记录中断次数 key_flag负责记录是哪一个按键被按下
unsigned int time=0;
unsigned char key_flag=0;

//延时函数负责消抖
void delay_10ms()
{
    unsigned char i, j;

    i = 18;
    j = 235;
    do
    {
        while (--j);
    } while (--i);
}

void main()
{
    //此处初始化定时器和打开中断
    
    //循环负责检测按键
    while(1)
    {
        if(key1==0)
        {
            delay_10ms();
            if(key1==0)
                key_flag=1;
        }
        if(key2==0)
        {
            delay_10ms();
            if(key2==0)
                key_flag=2;
        }
        if(key3==0)
        {
            delay_10ms();
            if(key3==0)
                key_flag=3;
        }
        if(key4==0)
        {
            delay_10ms();
            if(key4==0)
                key_flag=4;
        }
    }
}

//定时器中断
void timer_work() interrupt 1
{
    //TH0=0x;
    //TL0=0x;
    //上面两行根据使用的单片机类型决定是否重复赋值
    
    //中断一次time++
    time++;

    //根据按下按键的键值和中断的次数翻转输出口的电平
    if(key1==1&&time==500)
    {
        time=0;
        out=~out;
    }
    else if(key1==2&&time==50)
    {
        time=0;
        out=~out;
    }
    else if(key1==3&&time==5)
    {
        time=0;
        out=~out;
    }
    else if(key1==4&&time==1)
    {
        time=0;
        out=~out;
    }
}

开定时器,并在里面做累加,累加到指定值N的时候就翻转io口,而N可以通过按键中断,在中断函数中进行更新,就可以实现按键切换方波周期了。