PWMH DATA 30H ;高电平脉冲的个数
PWM DATA 31H ;PWM周期
COUNTER DATA 32H
TEMP DATA 33H
ORG 0000H
AJMP MAIN
ORG 000BH
AJMP INTT0
ORG 0100H
MAIN:
MOV SP,#60H ;给堆栈指针赋初值
MOV PWMH,#02H ;
MOV COUNTER,#01H
MOV PWM,#15H
MOV TMOD,#02H ;定时器0在模式2下工作
MOV TL0,#38H ;定时器每200us产生一次溢出
MOV TH0,#38H ;自动重装的值
SETB ET0 ;使能定时器0中断
SETB EA ;使能总中断
SETB TR0 ;开始计时
KSCAN:
JNB P11,K1CHECK ;扫描KEY1,
JNB P12,K2CHECK ;扫描KEY2,如果按下KEY2,跳转到KEY2处理程序
SJMP KSCAN
K1CHECK:
JB P11,K1HANDLE ;去抖动,如果按下KEY1,跳转到KEY1处理程序
SJMP K1CHECK
K1HANDLE:
MOV A,PWMH
CJNE A,PWM,K1H0 ;判断是否到达上边界
SJMP KSCAN ;是,则不进行任何 *** 作
K1H0:
MOV A,PWMH
INC A
CJNE A,PWM,K1H1 ;如果在加1后到达最大值
CLR TR0 ;定时器停止
SETB P10 ;P10为高电平
SJMP K1H2
K1H1:
CJNE A,#02H,K1H2 ;如果加1后到达下边界
SETB TR0 ;重开定时器
K1H2:
INC PWMH ;增加占空比
SJMP KSCAN
K2CHECK:
JB P12,K2HANDLE ;去抖动,如果按下KEY2,跳转到KEY2处理程序
SJMP K2CHECK
K2HANDLE:
MOV A,PWMH
CJNE A,#01H,K2H0 ;判断是否到达下边界
SJMP KSCAN ;是,则不进行任何 *** 作
K2H0:
MOV A,PWMH
MOV TEMP,PWM
DEC A
CJNE A,#01H,K2H1 ;如果在减1后到达下边界
CLR TR0 ;定时器停止
CLR P10 ;P10为低电平
SJMP K2H2
K2H1:
DEC TEMP
CJNE A,TEMP,K2H2 ;如果到达上边界
SETB TR0 ;启动定时器
K2H2:
DEC PWMH ;降低占空比
SJMP KSCAN
INTT0:
PUSH PSW ;现场保护
PUSH ACC
INC COUNTER ;计数值加1
MOV A,COUNTER
CJNE A,PWMH,INTT01 ;如果等于高电平脉冲数
CLR P10 ;P10变为低电平
INTT01:
CJNE A,PWM,INTT02 ;如果等于周期数
MOV COUNTER,#01H ;计数器复位
SETB P10 ;P10为高电平
INTT02:
POP ACC ;出栈
POP PSW
RETI
END
递增,应有极限,不能从0再开始循环。
while(1) {
if(Key1 == 0) //判断是否K1键按下
{
Num++;
Delay10ms(1);
if(Num >= 9)
Num = 9; //我只是改了这一句
PWM_DA_Percent_change( PWM_Data[Num] ); //改变PWM的值
while(Key1 == 0); //等待按键抬起
}
}
while(1)
{p1=0xff;
delayms(num);
p1=~p1;
delayms(num); //括号里面数字需要根据你方波周期大小及单片机晶振确定
}
void delay(void)
{
int x;
for(x = 0;x < 500;x++) //500只是瞎写同上根据需要自己确定一个值
}
void delay_ms(unsigned char num)
{
int x;
do{
num--;
for(x = 0;x < 500;x)
x++;
}
while(num > 0x01);
}
设计思路:
分别描述占空比为40%、50%、60%、70%和80%的电路模块,然后将5路输出送至一个8选1多路选择器的其中5个输入端(例如3位选择控制信号为000~101选中的那5路输入)。
再设计一个编码器,将5个按键编码成为000~101后送至8选1多路选择器的3位选择控制端就行了。
//晶振12MHz
//在P1_0输出20KHz,0-255级可调占空比 每一级039%
#include<at89x51h>
unsigned char PWM=0x80;//PWM的百分比
void InitT0(void)
{
TMOD=0x02;//定时器0工作方式2 8位自动重装
TH0=205;//pwm 50us 20khz
TL0=205;
TR0=1;//开始计时
ET0=1;//允许定时器中断
EA=1;//开启总中断
}
void main(void)
{
InitT0();//初始化T0定时器
while(1)
{
//添加处理代码
//调整PWM的值就能调整输出占空比
}
}
void Timer0(void) interrupt 1//用于PWM的定时器
{
static unsigned char counter=0;//记录中断次数
counter++;
if(counter >= PWM) P1_0 = 0; else P1_0 = 1;
}
#include "reg52h"
unsigned char count; //05ms次数标识
sbit pwm =P2^7 ; //PWM信号输出
sbit jia =P2^4; //角度增加按键检测IO口
sbit jan =P2^5; //角度减少按键检测IO口
unsigned char jd; //角度标识
void delay(unsigned char i)//延时
{
unsigned char j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void Time0_Init() //定时器初始化
{
TMOD = 0x01; //定时器0工作在方式1
IE = 0x82;
TH0 = 0xfe;
TL0 = 0x33; //110592MZ晶振,05ms
TR0=1; //定时器开始
}
void Time0_Int() interrupt 1 //中断程序
{
TH0 = 0xfe; //重新赋值
TL0 = 0x33;
if(count< jd) //判断05ms次数是否小于角度标识
pwm=1; //确实小于,PWM输出高电平
else
pwm=0; //大于则输出低电平
count=(count+1); //05ms次数加1
count=count%40; //次数始终保持为40 即保持周期为20ms
}
void keyscan() //按键扫描
{
if(jia==0) //角度增加按键是否按下
{
delay(10); //按下延时,消抖
if(jia==0) //确实按下
{
jd++; //角度标识加1
count=0; //按键按下 则20ms周期从新开始
if(jd==6)
jd=5; //已经是180度,则保持
while(jia==0); //等待按键放开
}
}
if(jan==0) //角度减小按键是否按下
{
delay(10);
if(jan==0)
{
jd--; //角度标识减1
count=0;
if(jd==0)
jd=1; //已经是0度,则保持
while(jan==0);
}
}
}
void main()
{
jd=1;
count=0;
Time0_Init();
while(1)
{
keyscan(); //按键扫描
}
}
以上就是关于怎样用单片机STC 89C52实现pwm控制占空比的输出波形,求程序!能详细备注的最好!全部的内容,包括:怎样用单片机STC 89C52实现pwm控制占空比的输出波形,求程序!能详细备注的最好!、关于PWM占空比调节的变成问题,有源程序请教!、51单片机 p1口产生一个固定频率的占空比50%的方波信号的程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)