基于51单片机的pwm和串口通信

此例程设置了按键可以调整100-1000hz的不同频率(100的倍数)的方波,另外还加入了串口通信,可以通过串口发送来的数字来设置相对应的频率;

#include <reg52.h>
#include"uart.h"

sbit PWMOUT = P1^0;
sbit led = P2^2;
sbit KEY1 = P1^2;
sbit KEY2 = P3^3;

unsigned char HighRH = 0;  //高电平重载值的高字节
unsigned char HighRL = 0;  //高电平重载值的低字节
unsigned char LowRH  = 0;  //低电平重载值的高字节
unsigned char LowRL  = 0;  //低电平重载值的低字节
unsigned int fr;
unsigned int k=0,t,i;
unsigned int s= 100;
unsigned char a[3];
unsigned int b=0;
   
void ConfigPWM(unsigned int fr, unsigned char dc);
void ConfigUART(unsigned int baud);
void delay(unsigned int n){ while (n--);}

void main()
{   
	bit backup1 = 1;
	bit backup2 = 1;
	bit keybuf1 = 1;  //按键值暂存,临时保存按键的扫描值
	bit keybuf2 = 1;  //按键值暂存,临时保存按键的扫描值
    //keybuf1 = KEY1;            //把当前扫描值暂存
	EA=1;
	led = 0;
    ConfigUART(9600);  //配置波特率为9600
	ConfigPWM(100,50);
	//Timer1Init();
    while (1)
    {
	  if(k==1)
	  {
	      k=0;
		  ConfigPWM(s,50);
	  	  led = ~led;delay(2000);
	  }

          	keybuf1 = KEY1;            //把当前扫描值暂存
          if (keybuf1 != backup1)     //当前值与前次值不相等说明此时按键有动作
          { 
            delay(1000);              //延时大约10ms
            if (keybuf1 == KEY1)   //判断扫描值有没有发生改变,即按键抖动
            {
               if (backup1 == 0)  //如果前次值为0,则说明当前是弹起动作
                  {
                    s = s-50;      
                }
                backup1 = keybuf1;  //更新备份为当前值,以备进行下次比较
            }
			ConfigPWM(s,50);
          }
		  keybuf2 = KEY2;            //把当前扫描值暂存
          if (keybuf2 != backup2)     //当前值与前次值不相等说明此时按键有动作
          {
            delay(1000);              //延时大约10ms
            if (keybuf2 == KEY2)   //判断扫描值有没有发生改变,即按键抖动
            {
                if (backup2 == 0)  //如果前次值为0,则说明当前是弹起动作
                {
                    s = s+50;      
                }
                backup2 = keybuf2;  //更新备份为当前值,以备进行下次比较
            }
			ConfigPWM(s,50);
          }
		   



	}
}

void ConfigUART(unsigned int baud)
{
    SCON  = 0x50;  //配置串口为模式1
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x20;  //配置T1为模式2
    TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
    TL1 = TH1;     //初值等于重载值
	ET1 = 0;		//中断T1
	ES = 1;			//串口中断
    TR1 = 1;       //启动T1
}

void ConfigPWM(unsigned int fr, unsigned char dc)
{
unsigned int high, low;
unsigned long tmp;
tmp = (11059200/12)/fr; //计算一个周期所需的计数值
high = (tmp*dc) / 100; //计算高电平所需的计数值
low = tmp -  high; //计算低电平所需的计数值
high = 65536 - high + 12; //计算高电平的重载值并补偿中断延时
low = 65536 - low + 12; //计算低电平的重载值并补偿中断延时
HighRH = (unsigned char)(high>>8); //高电平重载值拆分为高低字节
HighRL = (unsigned char)high;
LowRH = (unsigned char)(low>>8); //低电平重载值拆分为高低字节
LowRL = (unsigned char)low;
TMOD &= 0xF0; //清零 T0 的控制位
TMOD |= 0x01; //配置 T0 为模式 1
TH0 = HighRH; //加载 T0 重载值
TL0 = HighRL;
ET0 = 1; //使能 T0 中断
TR0 = 1; //启动 T0
PWMOUT = 1; //输出高电平
}

void InterruptTimer0() interrupt 1
{
    if (PWMOUT == 1)  //当前输出为高电平时,装载低电平值并输出低电平
    {
        TH0 = LowRH;
        TL0 = LowRL;
        PWMOUT = 0;
    }
    else              //当前输出为低电平时,装载高电平值并输出高电平
    {
        TH0 = HighRH;
        TL0 = HighRL;
        PWMOUT = 1;
    }
}

/*void Timer1Init()
{
	TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。

	TH1=0XFC;	//给定时器赋初值,定时1ms
	TL1=0X18;	
	ET1=1;//打开定时器1中断允许
	EA=1;//打开总中断
	TR1=1;//打开定时器			
}
void Timer1() interrupt 3
{
	static u16;
	TH1=0XFC;	//给定时器赋初值,定时1ms
	TL1=0X18;
	i++;
	if(i==1000)
	{
		i=0;
		t++;
		if(t%2==0)
		{
		   SBUF=t/10;
		   SBUF=t%10;
		}
	}	
}*/

void ComINT() interrupt 4	 //中断接收程序
{	
	if(RI)			   //判断是否接收完,接收完成后,由硬件置RI位
	{
	  RI=0;									 
	  //SBUF=SBUF;
	  a[b]=SBUF;
	  b++;
	   if(b==3)
	   {
	     /*if(a[0]=='a'&&a[1]=='b'&&a[2]=='c') 
		 {led = 0;delay(2000);}
		 else
		 {led = 1;}*/
	   	 b=0;s=(a[0]-0x30)*100+(a[1]-0x30)*10+(a[2]-0x30);
		  k=1;
		  //SBUF = 'T';
	   }  
}	  
if(TI)
{
	  TI=0;

	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值