用51单片机产生占空比可调的pwm,且可以定时持续输出一定占空比的pwm~

1、我是在做课程设计,要求产生一定频率的 占空比可以根据设定,而且输出的占空比恒定的PWM的持续时间也可以设定;

2、有具体的计算公式(方法)和一些程序注释,小弟将不胜感激!

占空比课设
//************************************************************************
// File : PwmDrive_12C5A.c
// Date : 2009-08-22
// Version : 1.0
// Powerd by : weishao2401 QQ:115393395
// modify by :
//*************************************************************************
// Descriptoon:
// STC12C5A60AD/S2系列驱动程序
//
// 注: AD结果的读取有查询和中断这两种方式
// 本驱动用的是查询方式
// STC12C5A60S2系列的模块0对应P1.0/CEX0/PCA0/PWM0
// 产品网站 http://www.sxcckj.com 传诚科技
//*************************************************************************
#include "pwmdrive.h"
#include "LCD5110.h"

char idata Duty0[4];
char idata Duty1[4];

//sfr CCON = 0xD8; //PCA控制寄存器
//sfr CMOD = 0xD9; //PCA模式寄存器
//sfr CCAPM0 = 0xDA; //PCA模块0模式寄存器 //模块0对应P1.3/CEX0/PCA0/PWM0(STC12C5A60S2系列)
//sfr CCAPM1 = 0xDB; //PCA模块1模式寄存器 //模块1对应P1.4/CEX1/PCA1/PWM1(STC12C5A60S2系列)
//sfr CL = 0xE9; //PCA 定时寄存器 低位
//sfr CH = 0xF9; //PCA 定时寄存器 高位
//sfr CCAP0L = 0xEA; //PCA模块0的 捕获寄存器 低位
//sfr CCAP0H = 0xFA; //PCA模块0的 捕获寄存器 高位
//sfr CCAP1L = 0xEB; //PCA模块1的 捕获寄存器 低位
//sfr CCAP1H = 0xFB; //PCA模块1的 捕获寄存器 高位
//sfr PCA_PWM0 = 0xF2; //PCA PWM 模式辅助寄存器0
//sfr PCA_PWM1 = 0xF3; //PCA PWM 模式辅助寄存器1
//sbit CF = 0xDF; //PCA计数溢出标志位
//sbit CR = 0xDE; //PCA计数器 运行控制位
//sbit CCF1 = 0xD9; //PCA模块1中断标志
//sbit CCF0 = 0xD8; //PCA模块0中断标志

//* CMOD |= 0X00; // PCA/PWM时钟源为 Fosc/12
//* CMOD |= 0X02; // PCA/PWM时钟源为 Fosc/2
//* CMOD |= 0X04; // PCA/PWM时钟源为 定时器0的溢出,一般设为模式2,可实现可调频率PWM输出
//* CMOD |= 0X06; // PCA/PWM时钟源为 ECI/P3.4脚的外部时钟输入(最大速率=Fosc/2)
//* CMOD |= 0X08; // PCA/PWM时钟源为 Fosc
//* CMOD |= 0X0A; // PCA/PWM时钟源为 Fosc/4
//* CMOD |= 0X0C; // PCA/PWM时钟源为 Fosc/6
//* CMOD |= 0X0E; // PCA/PWM时钟源为 Fosc/8
//*** 由于PWM是8位,PWM频率 = PCA时钟频率 / 256

//* CCAPOH = CCAPOL = 0XC0; //模块0输出 占空因数为25%
//* CCAPOH = CCAPOL = 0X80; //模块0输出 占空因数为50%
//* CCAPOH = CCAPOL = 0X40; //模块0输出 占空因数为75%

/*===========================================
*函数名:PWM_clock(U8 clock)
*功 能:PWM端口初始化 子函数,
* clock取值为0-7,依次对应8种时钟模式
*返回值:无
*调用函数:无
*作 者:weishao2401 2009/8/22
*============================================*/
void PWM_clock(U8 clock)
{
CMOD |= (clock<<1);
//CMOD=0x08;
CL = 0x00;
CH = 0x00;
}

/*===========================================
*函数名:PWM_start(module,mode)
*功 能:选择PWM模块和PWM模式,
* module=0/1/2,打开模块0/1/两者
* module=0/1/2/3,无中断/下降沿中断/上升沿中断/跳变中断
*返回值:无
*调用函数:无
*作 者:weishao2401 2009/8/22
*============================================*/
void PWM_start(U8 module,U8 mode,U8 DutyCycle0,U8 DutyCycle1)
{
//CCAP0L = 0XC0;
//CCAP0H = 0XC0; //模块0初始输出 占空因数为25%
//CCAP1L = 0XC0;
//CCAP1H = 0XC0; //模块1初始输出 占空因数为25%
Duty0[0]=DutyCycle0/10+'0';
Duty0[1]=DutyCycle0%10+'0';
Duty0[2]='\0';
Duty1[0]=DutyCycle1/10+'0';
Duty1[1]=DutyCycle1%10+'0';
Duty1[2]='\0';

CCAP0L=(65535-65535*DutyCycle0/100)%256;
CCAP0H=(65535-65535*DutyCycle0/100)/256;
//CCAPM0=0x42;

CCAP1L=(65535-65535*DutyCycle1/100)%256;
CCAP1H=(65535-65535*DutyCycle1/100)/256;
//CCAPM1=0x42;

if(module==0)
{
switch(mode)
{
case 0: CCAPM0 = 0X42;break; //模块0设置为8位PWM输出,无中断
case 1: CCAPM0 = 0X53;break; //模块0设置为8位PWM输出,下降沿产生中断
case 2: CCAPM0 = 0X63;break; //模块0设置为8位PWM输出,上升沿产生中断
case 3: CCAPM0 = 0X73;break; //模块0设置为8位PWM输出,跳变沿产生中断
default: break;
}
}
else
if(module==1)
{
switch(mode)
{
case 0: CCAPM1 = 0X42;break; //模块1设置为8位PWM输出,无中断
case 1: CCAPM1 = 0X53;break; //模块1设置为8位PWM输出,下降沿产生中断
case 2: CCAPM1 = 0X63;break; //模块1设置为8位PWM输出,上升沿产生中断
case 3: CCAPM1 = 0X73;break; //模块1设置为8位PWM输出,跳变沿产生中断
default: break;
}
}
else
if(module==2)
{
switch(mode)
{
case 0: CCAPM0 = CCAPM1 = 0X42;break; //模块0和1设置为8位PWM输出,无中断
case 1: CCAPM0 = CCAPM1 = 0X53;break; //模块0和1设置为8位PWM输出,下降沿产生中断
case 2: CCAPM0 = CCAPM1 = 0X63;break; //模块0和1设置为8位PWM输出,上升沿产生中断
case 3: CCAPM0 = CCAPM1 = 0X73;break; //模块0和1设置为8位PWM输出,跳变沿产生中断
default: break;
}
}
CR=1; //PCA计数器开始计数
}

/************pwm的显现函数************************/
void PWM_dis(void)
{
LCD_write_english_string(0,0,"DutyCycle0:");
LCD_write_english_string(66,0,Duty0);
LCD_write_english_string(78,0,"%");
LCD_write_english_string(0,1,"DutyCycle1:");
LCD_write_english_string(66,1,Duty1);
LCD_write_english_string(78,1,"%");
}

/*===========================================
*函数名:PCA_PWM(void) interrupt 7
*功 能:PCA中断子函数,
*返回值:无
*调用函数:无
*作 者:weishao2401 2009/8/22
*============================================*/
void PCA_Intrrpt(void) interrupt 7
{
//如果是CCF0产生的中断
if(CCF0)
{
CCF0=0; //软件清零

}
//如果是CCF1产生的中断
if(CCF1)
{
CCF1=0; //软件清零

}
//如果是CF产生的中断
if(CF)
{
CF=0; //软件清零

}

}
温馨提示:内容为网友见解,仅供参考
第1个回答  推荐于2016-08-27
/***************在OCR1B(PD4)上可测到100HZ的PWM波***********************/
/***************在OCR1A(PD5)上可测到50HZ的方波************************/
#include <iom16v.h>
#include <macros.h>
void PWM()
{
DDRD=0X30;//设置OC1B(PD4)和OC1A(PD5)为输出
TCCR1A=0X63;
TCCR1B=0X1B;

OCR1A=7;//得到10KHZ的PWM波
OCR1B=5;//得到2ms(1810/5)的高电平时间
}
1.这是AVR的程序,51不能产生PWM波,你用AVR吧。主要是设置存放的TOP值 (OCR1A的值),然后你要多大的占空比 再设置OCR1B的值,至于持续时间就更简单了,你要产生多久,就调用此函数就可以了哈
2.产生方波的频率计算公式(KHZ)
f=fclk(晶振)/{*N(1+OCRNA)}
N:代表分频因子
根据你要的产生方波的频率,就能算出OCRNA的值,就可以了!本回答被提问者采纳

如何用51单片机定时器产生一个PWM,频率20kHz,占空比可调的PWM
CYCLE = 10;\/\/ 时间可以调整 这个是10步调整 周期10ms 8位PWM就是256步 while(1){ if(!KEY1){ delay(20000);if(!KEY1){ PWM_Num++;if(PWM_Num==4)PWM_Num=0;switch(PWM_Num){ case 0:P0=0x06;PWM_ON=0;break;\/\/高电平时长 case 1:P0=0x5B;PWM_ON=4;break;case 2:P0=0...

51单片机咋样产生占空比,频率可变的PWM波
51的话 直接修改定时中断的定时时间就可以改变频率,修改高电平的定时时间,就能改变 占空比。- ARM的话--直接修改匹配0的值 就能改变PWM频率(MR0),修改其他匹配就能改变占空比,毕竟在ARM单边极性匹配中断时候,第一次复位时候,总是以高电平起始,会自动拉高!希望回答能给你点帮助,不过你问的问题...

51单片机产生一定占空比和频率的PWM.
define TL_M1 (65536-count)%256 \/\/设置定时器T0的定时时间 unsigned char ucount=0;sbit PWM=P1^0;unsigned char DR;\/\/定义全局变量占空比 \/*主函数***\/ void main(void){ \/\/IP=0x10; \/\/将串口中断定义为高优先级 TMOD|=0X21; \/\/将Timer1设置Mode 2 以产生波特率,同时将Timer0...

51单片机怎样输出频率F=0.2-50HZ,占空比D=1-100%可调的PWM波形
利用定时器。uint PwmCnt = 0;sbit PWN_OUT = P1^1;\/\/可改动uint PwmD = 50;\/\/占空比 可调uint PwmF = 500;\/\/频率 可调 10 = 1HZ 500 =50HZuint PwmCnt = 0;\/\/占空比计数值uint FreCnt = 0;\/\/频率分频值void T0 interrupt 1{ ...\/\/赋值TO计数值 50us if(++...

怎么用51单片机来实现pwm调节占空比
可以用两级中断来实现,该方法可实现精确占空比与频率的调整。。。大致思想是:1.在定时器T0中开定时器T1,并使pwm=1,2.在定时器T1中关掉T1,即TR1=0;并使pwm=0;注:t0控制频率(周期),t1控制占空比(高电平时间),你只要装载相应的定时器初值即可。很实用的哦 ...

51单片机输出PWM的最高频率和占空比
51所能输出的PWM的最大频率 是由单片机的时钟周期决定的,25Hz以上肉眼就基本看不出来了 占空比是可以0%~100%调整的,这个是由程序决定 include <REGX52.H> define uchar unsigned char define uint unsigned int sbit PWM_OUT=P3^0; \/\/PWM输出 void DelayMS(uint ms){ uchar i,j;for(j=ms;...

怎样利用51单片机发生PWM,通过调节PWM的占空比控制可控硅调节电机转速...
需要利用交流电的作触发信号,单片机生成延迟脉冲,不必使用pwm 注意是调节过零后的延迟时间,再出脉冲。

你好,请问51单片机产生的PWM波形占空比是否只能是50%的?然后如果是,那 ...
可以产生任意占空比的,虽然51定时器本身没有PWM模式,但是可以通过交替改变初始值的方式,也就是说,中断后,写入高电平时间对应的初值,再中断后,写入低电平时间对应的初值,如此循环。如果是驱动电机的话,PWM频率建议到5至10kHz,不要太高也不要太低。另外注意,PWM调速时,速度不是线性的,占空比太...

跪求!想用51单片机通过按键触发来输出一个可调占空比的的PWM波形。用C...
开个定时器,0.1ms的中断周期,中断100次为一个PWM周期,得出10ms周期的PWM波,然后在这100次的中断中,前30次中断让IO口输出高,后70次让IO口输出低,然后就得出了30%占空比的PWM波,根据这个方法即可实现你的要求。

51单片机如何用一个定时器产生20KHZ占空比可调的PWM波
20kHz周期是50us,可以把某个端口赋高电平延时Xus,然后赋低(50-X)us,占空比就是(x\/50)

相似回答