怎样用单片机STC 89C52实现pwm控制占空比的输出波形,求程序!能详细备注的最好!

怎样用单片机STC 89C52实现pwm控制占空比的输出波形,求程序!能详细备注的最好!,第1张

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%的方波信号的程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/9431913.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存