STC单片机输出PWM信号,频率要25KHz,请大神指教,怎么实现,或者直接给我一个程序,谢谢!

STC单片机输出PWM信号,频率要25KHz,请大神指教,怎么实现,或者直接给我一个程序,谢谢!,第1张

void PWM_init (void){//PWM初始化函数

CMOD=0x02; //设置PCA定时器,计数频率为晶振频率/2 当为12Mhz时,PWM输出频率约234Khz

//CMOD=0x00; //设置PCA定时器,计数频率为晶振频率/12 当为12Mhz时,PWM输出频率约39Khz

//CMOD=0x04; //设置PCA定时器,计数频率为定时器0的溢出率,如果让定时器0设为16位计数模式,其溢出频率可以在很大范围内调节,从而以产生很高或很低的PWM频率

CL=0x00;

CH=0x00;

CCAPM1=0x42; //PWM1设置PCA工作方式为PWM方式(0100 0010)

CCAP1L=0x00; //设置PWM1初始值与CCAP0H相同

CCAP1H=0x00; // PWM1初始时为0

CR=1; //启动PCA定时器

}

实际上要产生低频率的PWM波,不用其硬件PWM功能完全可以

用定时器中断方式即可实现

让定时器 200us中断一次(中断不算频繁呀) ,设一变量a,每次中断a加1,100次就是20ms,,另设一变量b,数值在1-100之间,每次中断比较a和 b的大小,如果a<b,则引脚 输出高电平,否则为低电平,这样通过改变b的值,就可实现频率为50HZ,占空比1-100%可调的PWM方波

用两个定时器的方法是用定时器T0来控制频率,定时器T1来控制占空比。大致的的编程思路是这样的:T0定时器中断让一个I0口输出高电平,在这个定时器T0的中断当中起动定时器T1,而这个T1是让IO口输出低电平,这样改变定时器T0的初值就可以改变频率,改变定时器T1的初值就可以改变占空比。

用一个定时器时(如定时器T0),首先你要确定PWM的周期T和占空比D,确定了这些以后,你可以用定时器产生一个时间基准t,比如定时器溢出n次的时间是PWM的高电平的时间,则DT=nt,类似的可以求出PWM低电平时间需要多少个时间基准n'。

因为这里我们是产生周期为1ms(1000HZ)的PWM,所以可设置中断的时间基准为001ms,,然后中断100次即为1ms。在中断子程序内,可设置一个变量如time,在中断子程序内,有三条重要的语句:1、当time>=100时,time清零(此语句保证频率为1000HZ),2、当time>n时(n应该在0-100之间变化开),让单片相应的I/O口输出高电平,当time<n时,让单片相应的I/O口输出低电平,此时占空比就为%n。

参考资料:

>

#include<at89x51h>

unsigned char PWM0=0x80,PWM1=0x80,PWM2=0x80;//PWM的百分比

void InitT0(void)

{

TMOD=0x02;//定时器0工作方式2 8位自动重装

TH0=0;//pwm频率为系统时钟/256

TL0=0;

TR0=1;//开始计时

ET0=1;//允许定时器中断

EA=1;//开启总中断

}

void main(void)

{

InitT0();//初始化T0定时器

while(1)

{

//添加处理代码

}

}

void Timer0(void) interrupt 1//用于PWM的定时器

{

static unsigned char counter=0;//记录中断次数

counter++;

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

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

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

}

// PWM 控制 LED 灯渐亮渐灭程序

// 适用 ME300B 开发系统

// 晶振为110592M

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

// 按K1,PWM值增加,则占空比减小,LED 灯渐暗。

// 按K2,PWM值减小,则占空比增加,LED 灯渐亮。

// 当PWM值增加到最大值或减小到最小值时,蜂鸣器将报警。//#include < reg51h >

#include < intrinsh >sbit K1 =P1^4 ; //增加键

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

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++) ;

}

}

这个挺简单的吧

不知道你的DSP设置情况,我就说下我怎么设置吧。我设置的DSP频率是150M,你要发的PWM波周期是20KHz,设置连续增减模式,计数的最大值应该设为150M/40k=3750,你在设置比较值,如果占空比是50%,就设一半。然后你设个计数值,确定是什么时候开通哪个PWM,定义个flag就可以 了,设置为012,到了你的PWM长度就加1,到3时清0,等于0开PWM1,1开PWM2,2开PWM3就ok了。

#include <reg52h> //头文件

#define uchar unsigned char

#define uint unsigned int

sbit KEY1= P3^4; //定义按钮

sbit KEY2= P3^5; //定义按钮

sbit PWM= P1^7;//PWM输出的管脚定义

#define PERIOD 1000 //pwm周期

#define MIN_POSITIVE 100 //最小占空比100/1000

#define MAX_POSITIVE 900 //最大占空比900/1000

#define STEP 10 //步长

uint POSITIVE=MIN_POSITIVE;

void delay(uint i)//延时函数

{

while(--i);

}

void init_timer0()//设置定时器

{

TMOD=0X01;

TL0=(POSITIVE-PERIOD)%256;//具体怎么实现的你看一下51单片机定时器的东西,TLO,THO。

TH0=(POSITIVE-PERIOD)/256;

ET0=1;

}

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

{

TMOD|=0X10;

TL1=(0-POSITIVE)%256;

TH1=(0-POSITIVE)/256;

ET1=1;

EA=1;

}

void TIMER0_ISR(void)interrupt 1 //中断响应函数

{

TL0=(POSITIVE-PERIOD)%256;

TH0=(POSITIVE-PERIOD)/256;

TR0=0;

TR1=1;

PWM=0;

}

void TIMER1_ISR(void)interrupt 3 //中断响应函数

{

TL1=(0-POSITIVE)%256;

TH1=(0-POSITIVE)/256;

TR1=0;

TR0=1;

PWM=1;

}

void key_scan() 按钮扫描函数

{

uint step=0;

step=(PERIOD-MIN_POSITIVE-100)/STEP;

KEY1=1;

KEY2=1;

if(KEY1==0||KEY2==0)

{

delay(100);

if(KEY1==0)

{

POSITIVE+=step;

if(POSITIVE>MAX_POSITIVE)

POSITIVE=MAX_POSITIVE;

}

if(KEY2==0)

{

POSITIVE-=step;

if(POSITIVE<MIN_POSITIVE)

POSITIVE=MIN_POSITIVE;

}

while(KEY1==0||KEY2==0);

}

}

void main() //主函数

{

init_timer0();

init_timer1();

TR0=1;

while(1)key_scan();

}

//这里的意思就是高电平使用一个定时器,低电平使用一个定时器,其实可以使用一个定时器就可以完成这个任务。他的左右只是1ms响应一个中断,然后计数。

//

#include <REGX51H>

#define TIMER0_COUNT 0xFC18 //每秒中端1000次

unsigned long int m,a;

static void timer0_isr(void) interrupt 1 using 1

{

TR0=0;

TL0=(TIMER0_COUNT & 0x00FF);

TH0=(TIMER0_COUNT >> 8);

TR0=1;

m++;

}

static void timer0_initialize(void)

{

EA=0; / 设定系统不接受所有的中断 /

m=0;

TR0=0; / 关闭Timer0 /

TMOD =0x01; / 设定计时器0为16位的工作模式 /

TL0=(TIMER0_COUNT & 0x00FF); / 设定TL0的数值 /

TH0=(TIMER0_COUNT >> 8); / 设定TH0的数值 /

PT0=0; / 设定计时器0有比较高的优先级 /

ET0=1; / 设定接受Timer0的中断 /

TR0=1; / 启动Timer0 /

EA=1; / 设定系统接受中断 /

}

void main (void)

{

timer0_initialize();

P2_0=0;

P2_1=1;

P3_0=0;

P3_1=1;

a=25;

while(1)

{

if(m==a)

{

P2_2=0;

P3_2=0;

}

if(m==50)

{

P2_2=1;

P3_2=1;

m=0;

}

}

}

//

这是我之前写的程序,你看看吧。希望对你有帮助,这个好理解点

以上就是关于STC单片机输出PWM信号,频率要25KHz,请大神指教,怎么实现,或者直接给我一个程序,谢谢!全部的内容,包括:STC单片机输出PWM信号,频率要25KHz,请大神指教,怎么实现,或者直接给我一个程序,谢谢!、如何利用51单片机输出PWM波、跪求单片机输出pwm波控制电调的程序!!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存