
你的问题涉及到硬件,应该说清楚
一般来说 PWM调速程序的步骤是:
1 先写一个固定的PWM产生函数 例如多用定时
器优先级要高点 这样PWM质量较好 2修改定时器常数 定时器常数可以放到一个固定的地址单元 在其他的程序段时直接修改该单元数值即可实现调速
一般的调速都是基于PID调速的 更详细的资料你在找找
这个我经常用,电机调速控制,严格说这不是PWM,是可控硅移相触发。\x0d\电路很简单,一个可控硅触发电路,一个过零检测电路,配合一段中断服务程序就能完成。\x0d\\x0d\不知道你应用的一些详情,简单说一下思路。\x0d\可控硅触发一般使用MOC3021,相关手册上有典型电路,CPU端接一个GPIO就可以。\x0d\闭环控制时过零检测不需要很精确,一般用一个双向光耦就足够,光耦输入接交流电输入,输出接CPU中断,用史密特整形一下输出信号最好。\x0d\中断程序的结构分成两部分,过零中断与延时中断。\x0d\过零中断做两件事,输出复位,开始延时。如果定时器有外部管脚复位启动功能,可以不要这段。\x0d\延时中断做一件事,触发输出。如果定时器有触发输出功能,可以没有这段中断程序。\x0d\具体的延时时间,由主程序控制,一般是根据PID的计算结果进行设置。注意,延时时间越长,输出电压越小。
#include<reg52h>
sfr CCON =0xD8;
sfr CMOD =0xD9;
sfr CCAPM0 =0xDA;
sfr CCAPM1 =0xDB;
sfr CCAPM2 =0xDc;
sfr CCAPM3 =0xDd;
sfr CL =0xE9;
sfr CH =0xF9;
sfr CCAP0L =0xEA;
sfr CCAP0H =0xFA;
sfr CCAP1L =0xEb;
sfr CCAP1H =0xFb;
sfr CCAP2L =0xEc;
sfr CCAP2H =0xFc;
sfr CCAP3L =0xEd;
sfr CCAP3H =0xFd;
sbit CR =0xDE;
voidinit_pwm()
{
//定时器的来源CPS1,CPS0
CMOD=0x02;//Setup PCA timer
CL=0x00;
CH=0x00;
}
//控制占空比
voidpulse_0(unsigned char p_on)
{
CCAP0L=p_on;//Set the initial value same asCCAP0H
CCAP0H=p_on;//
//CCAPMn1使能脉宽调制模式,EC0M必须=1
CCAPM0=0x42;//0100,0010 Setup PCA module 0in PWM mode
}
voidpulse_1(unsigned char p_on)
{
CCAP1L=p_on;//Set the initial value same asCCAP0H
CCAP1H=p_on;//25% Duty Cycle
//CCAPMn1使能脉宽调制模式,EC0M必须=1
CCAPM1=0x42;//0100,0010 Setup PCA module 0in PWM mode
}
voidpulse_2(unsigned char p_on)
{
CCAP2L=p_on;//Set the initial value same asCCAP0H
CCAP2H=p_on;//25% Duty Cycle
//CCAPMn1使能脉宽调制模式,EC0M必须=1
CCAPM2=0x42;//0100,0010 Setup PCA module 0in PWM mode
}
voidpulse_3(unsigned char p_on)
{
CCAP3L=p_on;//Set the initial value same asCCAP0H
CCAP3H=p_on;//25% Duty Cycle
//CCAPMn1使能脉宽调制模式,EC0M必须=1
CCAPM3=0x42;//0100,0010 Setup PCA module 0in PWM mode
}
voiddelay(int a)
{
int i;
for(i=0;i<a;i++);
}
voidmain(void)
{
unsigned char i=0;
init_pwm();
CR=1; //Start PCA Timer
while(1)
{
while(++i)
{
pulse_0(i+50);
pulse_1(i+100);
pulse_2(i+150);
pulse_3(i+200);
delay(1000);
}
while(--i)
{
pulse_0(i+50);
pulse_1(i+100);
pulse_2(i+150);
pulse_3(i+200);
delay(1000);
}
}
}
共两个:
/
程序名: 触控调光台灯
编写人: 杜洋
编写时间: 2009年 7月 25日
硬件支持: STC12C2052 12MHz
接口说明: P37(PWM0)用PWM控制LED,P15~P17接3路触摸键
修改日志:
NO1-20090725_0622 完成触控开关LED灯部分和PWM调光部分程序。
NO2-20090725_0638 完成开关灯时的渐变亮度。
/
说明:电路制作时需要将触摸键和VCC线放在一起,然后触摸时将手同时触摸按键引脚和VCC线。
//
#include <STC12C2052ADH> //STC12Cx052或STC12Cx052AD系列单片机头文件
sbit ON_OFF_Key = P1 ^ 7; //ON/OFF开关键
sbit Add_Key = P1 ^ 6; //加亮度(+)
sbit Doc_Key = P1 ^ 5; //减亮度(-)
//LED与P37(PWM0)连接
unsigned char Bright=0x88; //全局变量,亮度值
bit POWER=0; //LED灯开/关状态标志位
/
函数名:PWM初始化函数
调 用:PWM_init();
参 数:无
返回值:无
结 果:将PCA初始化为PWM模式,初始占空比为0
备 注:需要更多路PWM输出直接插入CCAPnH和CCAPnL即可
//
void PWM_init (void){
CMOD=0x02; //设置PCA定时器
CL=0x00;
CH=0x00;
CCAPM0=0x42; //PWM0设置PCA工作方式为PWM方式(0100 0010)
CCAP0L=0x00; //设置PWM0初始值与CCAP0H相同
CCAP0H=0x00; // PWM0初始时为0
CR=1; //启动PCA定时器
}
//
/
函数名:PWM0占空比设置函数
调 用:PWM0_set();
参 数:0x00~0xFF(亦可用0~255)
返回值:无
结 果:设置PWM模式占空比,为0时全部高电平,为1时全部低电平
备 注:如果需要PWM1的设置函数,只要把CCAP0L和CCAP0H中的0改为1即可
//
void PWM0_set (unsigned char a){
CCAP0L= a; //设置值直接写入CCAP0L
CCAP0H= a; //设置值直接写入CCAP0H
}
//
/
函数名:毫秒级CPU延时函数
调 用:DELAY_MS ();
参 数:1~65535(参数不可为0)
返回值:无
结 果:占用CPU方式延时与参数数值相同的毫秒时间
备 注:应用于1T单片机时i<600,应用于12T单片机时i<125
//
void DELAY_MS (unsigned int a){
unsigned int i;
while( --a != 0){
for(i = 0; i < 600; i++);
}
}
//
/
函数名:主函数
调 用:无
参 数:无
返回值:无
结 果:程序开始处,无限循环
备 注:
//
void main (void){
PWM_init(); //PWM初始化
P1M0 = 0xff; //将P1接口设置为高阻态输入
P1M1 = 0x00; //触摸按键启用
DELAY_MS (200); //延时等待I/O接口电平状态稳定
while(1){ //循环程序部分
unsigned char a; //临时变量
if(ON_OFF_Key == 1){ //开关键按下
if(POWER == 0){ //如果当前状态为关,则执行开灯程序
for(a=0;a<=Bright;a++){ //
PWM0_set(a);
DELAY_MS (20); //渐暗的时间间隔
}
PWM0_set(Bright); //达到存储的LED亮度
POWER = 1; //把状态标志位变成开
}else{ //如果当前状态为开,则执行关灯程序
for(a=Bright;a>0;a--){ //循环渐暗
PWM0_set(a);
DELAY_MS (20); //渐暗的时间间隔
}
PWM0_set(0); //关LED
POWER = 0; //把状态标志位变成关
}
while(ON_OFF_Key == 1); //等待按键放开
}
if(Add_Key == 1 && POWER == 1){ //加亮度键按下,同时在开灯状态下
Bright++; //亮度值加1
PWM0_set(Bright); //将值写入PWM控制LED亮度
if(Bright >= 0xFD){ //如果亮度值大于0xFD,则不再增加
Bright = 0xFD;
}
DELAY_MS (20); //渐变亮度的时间间隔
}
if(Doc_Key == 1 && POWER == 1){ //减亮度键按下,同时在开灯状态下
Bright--; //亮度值减1
PWM0_set(Bright); //将值写入PWM控制LED亮度
if(Bright < 0x08){ //如果亮度值小于0x08,则不再减少
Bright = 0x08;
}
DELAY_MS (20); //渐变亮度的时间间隔
}
}
}
//
/
杜洋工作室 DoYoung Studio
与电子爱好者同行 >
以上就是关于怎样用汇编语言编写pwm电机调速程序全部的内容,包括:怎样用汇编语言编写pwm电机调速程序、单片机控制PWM,用到双向可控硅。怎样设计相关电路图和程序(C语言的)、如何利用单片机自带的PWM功能产生可调PWM波,求相应程序,谢谢!!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)