求51单片机PWM程序(一个定时器产生三路PWM 可独立运作) 简单来说就是用三路独立的pwm控制三个LED

求51单片机PWM程序(一个定时器产生三路PWM 可独立运作) 简单来说就是用三路独立的pwm控制三个LED,第1张

怎么可能搞不了三路独立的呢楼下那位是被STC12C5A60S2的硬件蒙蔽了视线,他认为,STC12C只有两路PWM,无法实现3路,你却忘记了最原始的办法,不要说STC12有PWM功能,即使是传统的AT89S52这类没有PWM功能的单片机也一样能够实现楼主的要求

下面我简单的分析一下我的思路,楼主尝试编程,如果不懂,再追问:

你是用三路独立的PWM调光用的,PWM调光,为了保证不让人眼产生闪烁,理论上PWM的频率要大于20Hz,而在实际的测试用,一般PWM要大于25Hz才能保证不闪烁为了保险起见,我们将PWM的频率设定在30Hz左右,那么,周期就是33333333ms,假设,我们实现10级调光,那个 每级的时间是333333ms

然后设置三个变量和一个计数器,我描述不太清楚,你看一下程序:

sbit P1_0 = P1^0; //---P10,P11,P12是三路PWM输出

unsigned char Set_PWM0 = 0; //--Set_PWM0 Set_PWM1 Set_PWM2

//--分别是低电平占整个脉冲的百分比

//--他们最小取0,最大取9

unsigned char counter = 0;//--用于计数的

void ISR_Timer0(void) interrupt 1 //---我们就用定时器0来做,不用PWM硬件

{ //----33333ms中断一次

counter++;

if(counter >= 10) counter = 0;

if(counter >= Set_PWM0) P1_0 = 0; else P1_0 = 1;

if(counter >= Set_PWM1) P1_1 = 0; else P1_1 = 1;

if(counter >= Set_PWM2) P1_2 = 0; else P1_2 = 1;

}

这样,定时器0用于决定PWM的反占空比,你只要设置 Set_PWM0等三个参数就可以了

怎么会实现不了呢

第一,要理解中断在这里的作用是固定的“一小段”时间进入一次。

第二,PWM_ON在程序中的作用很大,它会由0------>CYCLE------>0并且一直循环下去。可以把它看成一个有规律的变化的量。

第三,每进入中断一次count++,满足条件count==PWM_ON或count==CYCLE时改变LED的当前状态。作用是给小灯亮或灭的时间不同。

第四,LED的亮度与其通电时间有关,也可以说成是占空比。上面的条件要理解成是呈线性增加或减小的频率。可以理解成三角波,对应的面积就是通电时间。

不知能不能给你讲明白!

你用定时器开中断吧,如果只是简单的用IO口的话,得到的频率很不准确的!

思路:根据单片机的晶振大小计算定时器的初值,在中断程序里给对要输出脉冲的引脚取反 *** 作就是了,例如:P1^0=~P1^0;

还有脉冲频率不能太高哦,要保证定时器的计时时间大于中断程序执行时间~~

程序大体结构:

void Init_timer() //定时器初始化

{

}

void main() //主程序

{

}

void t0() interrupt 1//t0的中断程序

{

}

1、 利用定时器控制产生占空比可变的 PWM 波

按K1,PWM值增加,则占空比减小,电机减速。

按K2,PWM值减小,则占空比增加,电机加速。

当PWM值增加到最大值或减小到最小值时,蜂鸣器将报警。

2、例程:

//

#include<reg51h>

#include<intrinsh>

sbit K1 =P1^4 ; //PWM值增加键

sbit K2 =P1^5 ; //PWM值减少键

sbit BEEP =P3^7 ; //蜂鸣器

unsigned char PWM=0x7f ; //赋初值

void Beep();

void delayms(unsigned char ms);

void delay(unsigned char t);

//

void main()

{

P1=0xff;

TMOD=0x21 ;

TH0=0xfc ; //1ms延时常数

TL0=0x66 ; //频率调节

TH1=PWM ; //脉宽调节

TL1=0 ;

EA=1;

ET0=1;

ET1=1;

TR0=1 ;

while(1)

{

do{

if(PWM!=0xff)

{PWM++ ;delayms(10);}

else Beep() ;

}

while(K1==0);

do{

if(PWM!=0x02)

{PWM-- ;delayms(10);}

else Beep() ;

}

while(K2==0);

}

}

//

// 定时器0中断服务程序 (频率)

//

void timer0() interrupt 1

{

TR1=0 ;

TH0=0xfc ;

TL0=0x66 ;

TH1=PWM ;

TR1=1 ;

P0=0x00 ; //启动输出

}

//

// 定时器1中断服务程序 (脉宽)

//

void timer1() interrupt 3

{

TR1=0 ;

P0=0xff ; //结束输出

}

//

//蜂鸣器子程序

//

void Beep()

{

unsigned char i ;

for (i=0 ;i<100 ;i++)

{

delay(100) ;

BEEP=!BEEP ; //Beep取反

}

BEEP=1 ; //关闭蜂鸣器

delayms(100);

}

//

// 延时子程序

//

void delay(unsigned char t)

{

while(t--) ;

}

//

// 延时子程序

//

void delayms(unsigned char ms)

{

unsigned char i ;

while(ms--)

{

for(i = 0 ; i < 120 ; i++) ;

}

}

//

给个我自己写的程序你,我试过了,通过!

#include

#define

uchar

unsigned

char

#define

uint

unsigned

int

sbit

P0_0=P0^0;

uchar

a;

/

TH0和TL0是计数器0的高8位和低8位计数器,

计算办法:TL0=(65536-C)%256;

TH0=(65536-C)/256,

其中C为所要计数的次数即多长时间产生一次中断;

TMOD是计数器工作模式选择,0X01表示选用模式1,

它有16位计数器,最大计数脉冲为65536,最长时间

为1ms65536=65536ms

/

void

init_sys(void);

/系统初始化函数/

void

main

(void)

{

init_sys();

while(1);

}

void

init_sys(void)

{

TMOD=0x01;

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

EA=1;

ET0=1;

TR0=1;

}

void

timer0(void)

interrupt

1

{

TH0=(65536-100)/256;

TL0=(65536-100)%256;

a++;

if(a<=3)

{

P0_0=1;

if(a==3)

//改变低电平持续时间

{

//也即改变占空比

P0_0=~P0_0;

}

}

else

{

P0_0=0;

if(a==5)

//改变周期

{

a=0;

}

}

}

以上就是关于求51单片机PWM程序(一个定时器产生三路PWM 可独立运作) 简单来说就是用三路独立的pwm控制三个LED全部的内容,包括:求51单片机PWM程序(一个定时器产生三路PWM 可独立运作) 简单来说就是用三路独立的pwm控制三个LED、请教51单片机利用PWM控制灯的亮度的程序、51单片机怎样做PWM等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/10212164.html

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

发表评论

登录后才能评论

评论列表(0条)

保存