51单片机是可以输出PWM的,相对麻烦。此时需要用到内部定时器来实现,可用两个定时器实现,也可以用一个定时器实现。 用两个定时器的方法是用定时器T0来控制频率,定时器T1来控制占空比。大致的的编程思路是这样的:T0定时器中断让一个I0口输出高电平,在这个定时器T0的中断当中起动定时器T1,而这个T1是让IO口输出低电平,这样改变定时器T0的初值就可以改变频率,改变定时器T1的初值就可以改变占空比。 下面重点介绍用一个定时器的实现PWM的方法。以周期为0.1ms(10KHz)为例,要产生其它频率的PWM波,程序中只需作简单修改即可。用一个定时器时(如定时器T0),首先要确定PWM的周期T和占空比D,确定了这些以后,就可以用定时器产生一个时间基准t,比如定时器溢出n次的时间是PWM的高电平的时间,则D*T=n*t,类似的可以求出PWM低电平时间需要多少个时间基准n。 下面的程序让51单片机产生一个100KHz的PWM方波,使用按键加减速度,在实际调试中,发现占空比D达到17%时即可转动,但是需要外力启动,此时转速最慢;在没有外力的情况下,占空比需要达到75%才可以转动,此时转速已经非常快;通过按键将占空比D调节到%17或%16时停止转动。占空比的值是LCD1602显示的。附上代码和演示视频链接:链接:https://pan.baidu.com/s/1BqV4morVQeHN2uTd89DRWw 提取码:kqew。
单片机源程序如下:
- //12MHz的晶振,产生频率10KHz,占空比为x的PWM波
- #include "reg52.h"
- #include "lcd.h"
- typedef unsigned int u16;
- typedef unsigned char u8;
- sbit PWM_LED = P1^0;
- sbit KeyUp = P2^0;
- sbit KeyDown = P2^1;
- u8 value = 1;
- u8 Br, Sr, Gr;
- u8 str[] = {"Moto Speed Trim"};
- u8 str1[] = {"PWM:"};
- void delay(u16 i)
- {
- while(i--);
- }
- void Timer0_Init(void)
- {
- TMOD |= 0x01;
- TH0 = 0xFF;
- TL0 = 0x9C; //定时0.01ms
- TR0 = 1;
- ET0 = 1;
- EA = 1;
- }
- void datapros(u8 val)
- {
- Br = val / 100 + 0x30;
- Sr = val % 100 / 10 + 0x30;
- Gr = val % 10 + 0x30;
- }
- void main(void)
- {
- PWM_LED = 0;
- Timer0_Init();
- LcdInit();
- while(1)
- {
- if(KeyUp != 1)
- {
- delay(1000);
- if(KeyUp != 1)
- {
-
- }
- while(!KeyUp);
- value++;
- if(value == 100)
- {
- value = 1;
- }
- }
- if(KeyDown != 1)
- {
- delay(1000);
- if(KeyDown != 1)
- {
- }
- while(!KeyDown);
- value--;
- if(value == 0)
- {
- value = 1;
- }
- }
- datapros(value);
- LcdShowStr(0,0,str);
- LcdShowStr(0,1,str1);
- DisplayOneChar(5,1,Br);
- DisplayOneChar(6,1,Sr);
- DisplayOneChar(7,1,Gr);
- DisplayOneChar(8,1,'%');
- }
- }
- void Timer0() interrupt 1
- {
- static u8 time = 0;
- TR0 = 0; //关闭定时器
- TH0 = 0xFF;
- TL0 = 0x9C; //重装初值
- TR0 = 1;
- time++;
- if(time > 100)
- {
- time = 0;
- }
- if(time < value)
- {
- PWM_LED = 1;
- }
- else
- PWM_LED = 0;
- }
复制代码
所有程序51hei提供下载:
PWM波-按键控制电机速度.rar
(18.75 KB, 下载次数: 44)
|