PWM调速的C语言程序编写(非常简单)

合集下载

]单片机C语言编程模板(PWM脉宽调制)

]单片机C语言编程模板(PWM脉宽调制)

[转]单片机C语言编程模板(PWM脉宽调制)修改浏览权限| 删除∙- MCS-51系列单片机C语言编程PWM脉宽调制器程序模板∙- 适用于STC系列内嵌PWM的单片机产品(以STC12C2052为例)- 以PWM控制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//CCAPM1=0x42; //PWM1设置PCA工作方式为PWM方式(使用时删除//)//CCAP1L=0x00; //设置PWM1初始值与CCAP0H相同//CCAP1H=0x00; // PWM1初始时为0//CCAPM2=0x42; //PWM2设置PCA工作方式为PWM方式//CCAP2L=0x00; //设置PWM2初始值与CCAP0H相同//CCAP2H=0x00; // PWM2初始时为0//CCAPM3=0x42; //PWM3设置PCA工作方式为PWM方式//CCAP3L=0x00; //设置PWM3初始值与CCAP0H相同//CCAP3H=0x00; // PWM3初始时为0CR=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; //设置值直接写入CCAP0LCCAP0H= a; //设置值直接写入CCAP0H}/**********************************************************************************************/ - 程序模块/********************************************************************************************* 程序名:PWM模块调试程序(仅实验用)编写人:杜洋编写时间:2009年7月22日硬件支持:STC12C2052 12MHz接口说明:LED灌电流接P3.7接口(PWM0)修改日志:NO.1-/********************************************************************************************* 说明:/*********************************************************************************************/ #include<STC12C2052AD.H> //头文件/********************************************************************************************* 函数名: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//CCAPM1=0x42; //PWM1设置PCA工作方式为PWM方式(使用时删除//)//CCAP1L=0x00; //设置PWM1初始值与CCAP0H相同//CCAP1H=0x00; // PWM1初始时为0//CCAPM2=0x42; //PWM2设置PCA工作方式为PWM方式//CCAP2L=0x00; //设置PWM2初始值与CCAP0H相同//CCAP2H=0x00; // PWM2初始时为0//CCAPM3=0x42; //PWM3设置PCA工作方式为PWM方式//CCAP3L=0x00; //设置PWM3初始值与CCAP0H相同//CCAP3H=0x00; // PWM3初始时为0CR=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; //设置值直接写入CCAP0LCCAP0H= a; //设置值直接写入CCAP0H}/**********************************************************************************************//********************************************************************************************* 函数名:主函数调用:无参数:无返回值:无结果:程序开始处,无限循环备注:/**********************************************************************************************/ void main (void){PWM_init(); //PWM初始化PWM0_set(0x10); //设置PWM占空比while(1){//无限循环程序}}/**********************************************************************************************/ /************************************************************** 杜洋工作室/*************************************************************/- 应用实例- 使用说明。

PWM调速C程序编写

PWM调速C程序编写
通过定时器模拟!可以通过两个定时器,T0控制周期,T1控制占空比。
例如:实现周期为1000us,占空比为20%的PWM,用PA0实现
首先设置T0为83 (11.0592M晶振)
T1为65501
首先初始化PA0=1,两个定时器同时打开,在定时器T1中断时拉低PA0,
在定时器T0中断时在拉高PA0,同时将两定时器初始值初始化T0为83,T1为65501
一开始设置PA0为高电平,当count1加到200的时候拉低PA0,
等count1到1000了在拉高PA0,同时复位count1=0,
不过这样做的缺点是精度不高,要是PWM所需周期段,精度高的话还是用两个定时器来实现;
************************************************/
SREG=0x80;
while(1);
}
#pragma vector = TIMER0_OVF_vect
__interrupt void TIMER0_OVF(void)
{
PWM_PA0=1;
TCNT0=0x53;
}
#pragma vector = TIMER1_OVF_vect
__interrupt void TIMER1_OVF(void)
}
void timer0_init(void)
{
SREG=0x80;
TIMSK|=(1<<TOIE0);
TCCR0|=(0<<CS02)|(0<<CS01)|(1<<CS00);
TCNT0=0x91;
}
void main(void)
{
port_init();

PWM编程C语言例

PWM编程C语言例
T1SC&=~(1<<5); //允许定时器1计数器计数
Delay_ms(10); //延时10ms
}
}
/*PWMconf:PWM初始化设置--------------------------------*
*功能:PWM脉冲周期、占空比的设置*
*参数:rate=脉宽时钟数,cyc=脉冲周期时钟数*
*返回:无*
10.5.5 PWM编程C语言例
实例编号:C05_3路径:\C\C05_3PWM脉冲信号输出(PWM.prj)
/*-----------------------------------------------------*
*工程名:PWM.prj *
*硬件接线:PTD.4,即定时器1通道0(21脚)接指示灯或蜂鸣器*
if(Duty<Period)
Duty=Duty+1; //PWM占空比加1
else //占空比达到100%,设置占空比为0%
Duty=0;
T1SC|=(1<<5); //停止定时器1计数器计数
//[设置PWM脉宽]
T1CH0H = (Duty>>8); //设置高字节
T1CH0L = Duty; //设置低字节
unsigned int ; //PWM占空比
//[变量初始化]
Period =0x0180; //PWM周期默认为10ms
//[PWM初始化]
PWMInit(Period);
Duty = 0; //PWM占空比为0
//[主循环]
while(1)
{
//[判断脉宽是否达到周期的长度(占空比为100%)]
*-----------------------------------------------------*/

pwm电机调速程序

pwm电机调速程序

PWM电机调速程序*******************************************************************/ /* 程序名:PWM直流电机调速 *//* 晶振:11.00592 MHz CPU型号:AT89C51 *//* 直流电机的PWM波控制,可以直接的调速从0到20级的调速 *//*****************************************************************/ #include<reg51.h>#define TH0_TL0 (65536-1000)//设定中断的间隔时长unsigned char count0 = 50;//低电平的占空比unsigned char count1 = 0;//高电平的占空比bit Flag = 1;//电机正反转标志位,1正转,0反转sbit Key_add=P2 ^ 0; //电机减速sbit Key_dec=P2 ^ 1; //电机加速sbit Key_turn=P2 ^ 2; //电机换向sbit PWM1=P2^6;//PWM 通道 1,反转脉冲sbit PWM2=P2^7;//PWM 通道 2,正转脉冲unsigned char Time_delay;/************函数声明**************/void Delay(unsigned char x);void Motor_speed_high(void);void Motor_speed_low(void);void Motor_turn(void);void Timer0_init(void);/****************延时处理**********************/void Delay(unsigned char x){Time_delay = x;while(Time_delay != 0);//等待中断,可减少PWM输出时间间隔}/*******按键处理加pwm占空比,电机加速**********/void Motor_speed_high(void)//{if(Key_add==0)Delay(10);if(Key_add==0){count0 += 5;if(count0 >= 100){count0 = 100;}}while(!Key_add);//等待键松开}}/******按键处理减pwm占空比,电机减速*****/ void Motor_speed_low(void){if(Key_dec==0){Delay(10);if(Key_dec==0){count0 -= 5;if(count0 <= 0){count0 = 0;}}while(!Key_dec );}}/************电机正反向控制**************/ void Motor_turn(void){if(Key_turn == 0){Delay(10);if(Key_turn == 0){Flag = ~Flag;}while(!Key_turn);}/***********定时器0初始化***********/void Timer0_init(void){TMOD=0x01; //定时器0工作于方式1TH0=TH0_TL0/256;TL0=TH0_TL0%256;TR0=1;ET0=1;EA=1;}/*********主函数********************/void main(void){Timer0_init();while(1){Motor_turn();Motor_speed_high();Motor_speed_low();}}/**************定时0中断处理******************/ void Timer0_int(void) interrupt 1 using 1{TR0 = 0;//设置定时器初值期间,关闭定时器TL0 = TH0_TL0 % 256;TH0 = TH0_TL0 / 256 ;//定时器装初值TR0 = 1;if(Time_delay != 0)//延时函数用{Time_delay--;}if(Flag == 1)//电机正转{PWM1 = 0;if(++count1 < count0)PWM2 = 1;}elsePWM2 = 0;if(count1 >= 100){count1=0;}}else //电机反转{PWM2 = 0;if(++count1 < count0){PWM1 = 1;}elsePWM1 = 0;if(count1 >= 100){count1=0;}}}//-----------------------------------------------------------------------------#include <c8051f330.h> // SFR declarations#include <math.h>// Function Prototypes//-----------------------------------------------------------------------------#define CMD_RESET 0xA4 //HD7279复位#define DECODE1 0xc8 //方式0译码sbit cs=P1^3;sbit clk=P1^2;sbit dat=P1^1;sbit key=P1^0;sbit led_D1003=P0^7;sbit sw1=P1^7;sbit sw2=P1^6;sbit sw3=P1^5;sbit sw4=P1^4;void long_delay(void); //延时函数void short_delay(void);void delay10ms(unsigned char);void write7279(unsigned char,unsigned char); //HD7279写指令void send_byte(unsigned char);void delay(unsigned char);void disp1(unsigned int);void OSCILLATOR_Init (void);void PORT_Init (void);void PCA0_Init (void);void Timer0_Init(void);void Ext_Interrupt_Init (void);//-----------------------------------------------------------------------------// Global Variables//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// main() Routine//-----------------------------------------------------------------------------unsigned int CEX0_Compare_Value; // Holds current PCA compare valueunsigned int tmr,Speed_evaluate;unsigned char num,num1,num2,num3,a;unsigned int Speed,pi,Speed2;unsigned int Speed1[10];typedef struct {double SetPoint; /* 设定目标Desired Value */double Proportion; /* 比例常数Proportional Const */double Integral; /* 积分常数Integral Const */double Derivative; /* 微分常数Derivative Const */double LastError; /* 前一项误差*/double PrevError; /* 前第二项误差*/double SumError; /* 误差和*/} PID;double PIDCalc( PID *pp, double NextPoint ){double dError,Error,Pout;Error = pp->SetPoint - NextPoint; /* */pp->SumError += Error; /* /dError = pp->LastError - pp->PrevError; /* */pp->PrevError = pp->LastError;pp->LastError = Error; /* */Pout= pp->Proportion * Error + pp->Integral * pp->SumError +pp->Derivative * dError ;if(Pout>1100)Pout=1000;if(Pout<100)Pout=100;return (Pout);}PID sPID; //定义PID结构体变量double rOut; //PID响应输出unsigned char rIn; //设置PID反馈值double x;double sumout;unsigned char dd;//设置PID输出void main (void){sPID.Proportion = 0.44; //设置PsPID.Integral = 0.70; //设置IsPID.Derivative = 0.0; //设置D//sPID.SetPoint = CEX0_Compare_Value;//sPID.SetPoint = CEX0_Compare_Value; //设置PID输出PCA0MD = 0x00; // Disable watchdog timerled_D1003=0;PORT_Init (); // Initialize crossbar and GPIOOSCILLATOR_Init (); // Initialize oscillatorPCA0_Init (); // Initialize PCA0IP=0x82; //定时器中断0高于外部中断0Timer0_Init();Ext_Interrupt_Init ();for (tmr=0;tmr<0x2000;tmr++);send_byte(CMD_RESET);//HD7279复位// Globally enable interruptsEA = 1;sPID.SetPoint=70;while (1){delay10ms(100);//键盘程序 -------------------------------------------------------------if(sw1==0) //按键1是否按下{if(sw1==0)//再次检查按键{num++; //若按键按下,num加1if(num==1) //到9归0{num=0;}while(sw1==0);//按键释放}// delay10ms(100);}write7279(DECODE1+4,num); //将num写入HD7279第1位 delay10ms(1);if(sw2==0){if(sw2==0){num1++;if(num1==2){num1=0;}while(!sw2);}// delay10ms(100);}write7279(DECODE1+5,num1);//将num1写入HD7279第2位delay10ms(1);if(sw3==0){if(sw3==0){num2++;if(num2==10){num2=0;}while(!sw3);}// delay10ms(100);}write7279(DECODE1+6,num2);//将num1写入HD7279第2位delay10ms(1);if(sw4==0){if(sw4==0){num3++;if(num3==10){num3=0;}while(!sw4);}// delay10ms(100);}write7279(DECODE1+7,num3);//将num1写入HD7279第2位delay10ms(1);Speed_evaluate=num*1000+num1*100+num2*10+num3;sPID.SetPoint=Speed_evaluate;//控制程序-----------------------------------------------------------------//---------------------------------------------------------------------------}}void OSCILLATOR_Init (void){OSCICN = 0x83; // Set internal oscillator torun// at its maximum frequencyCLKSEL = 0x00;}void PORT_Init (void){XBR0 = 0x00;XBR1 = 0x41;// Enable crossbar and weak pull-upsP0MDOUT |= 0x10; // Set CEX0 (P0.4) to push-pull P0SKIP |=0x0F; //P1SKIP = 0x00;P1MDOUT= 0x0f;}void PCA0_Init (void){PCA0CN = 0x00; // Stop counter; clear allflagsPCA0MD = 0x01; // Use Ettern ime basePCA0CPM0 = 0xCB; // Module 0 = 16-bit PWM modeand// enable Module 0 Match and Interrupt// Flags// Configure initial PWM duty cycle = 50%CEX0_Compare_Value = 65536 - (65536 * 0.15);PCA0CPL0 = (CEX0_Compare_Value & 0x00FF);PCA0CPH0 = (CEX0_Compare_Value & 0xFF00)>>8;EIE1 |= 0x10; // Enable PCA interrupts// Start PCA counterCR = 1;}void Ext_Interrupt_Init (void){TCON |= 0x05; // /INT 0 and /INT 1 are edge triggeredIT01CF = 0x10; // /INT0 active low; /INT0 on P0.0;// /INT1 active low; /INT1 on P0.1EX0 = 1; // Enable /INT0 interrupts}void Timer0_Init(void){TH0 = 0 ; // Init Timer0 High registerTL0 = 0 ; // Init Timer0 Low registerTMOD |= 0x01; // Timer0 in 16-bit mode方式1CKCON |= 0x02; // Timer0 uses a 1:48 prescalerET0 = 1; // Timer0 interrupt enabledTCON|=0x10;// Timer0 ON}// PCA0_ISR//-----------------------------------------------------------------------------void PCA0_ISR (void) interrupt 11{CCF0 = 0; // Clear module 0 interrupt flag.PCA0CPL0 = (CEX0_Compare_Value & 0x00FF);PCA0CPH0 = (CEX0_Compare_Value & 0xFF00)>>8;}void Timer0_ISR (void) interrupt 1{int j,sum;TF0=0;// Clear interrupt flag.a++;if (a==4){Speed1[pi]=Speed;if(pi>=3){ EX0 = 0;for(j=0;j<=3;j++){sum=sum+Speed1[j];Speed2=sum/4;disp1(Speed2);Speed=0;pi=0;EX0 = 1;}a=0;sum=0;if(pi>=3)pi=0;elsepi++;TH0 = 0; // Reinit Timer0 High register TL0 = 0; // Reinit Timer0 Low registerif(abs( sPID.SetPoint-Speed2)<=5) {CEX0_Compare_Value=CEX0_Compare_Value;}else{rIn =Speed2;for(dd=0;dd<50;dd++)x=rIn;//x = 5.0 * (double)rIn / 256.0;rOut = PIDCalc ( &sPID,x );// sumout=rOut*256/5;if(rOut==100)sumout=0;elsesumout= (0.85/1000.0)*rOut;//CEX0_Compare_Value=CEX0_Compare_Value-sumout;CEX0_Compare_Value = 65536 - (65536 * ( sumout+0.15));}}else{TH0 = 0; // Reinit Timer0 High registerTL0 = 0; // Reinit Timer0 Low register}}void INT0_ISR (void) interrupt 0{IE0=0; // // Clear interrupt flag.Speed++;}void write7279(unsigned char cmd, unsigned char dta) {send_byte(cmd);send_byte(dta);}void send_byte( unsigned char out_byte){unsigned char i;cs=0;long_delay();for (i=0;i<8;i++){if (out_byte&0x80){dat=1;}else{dat=0;}clk=1;short_delay();clk=0;short_delay();out_byte=out_byte*2; }dat=0;}void long_delay(void){unsigned char i;for (i=0;i<0x30;i++);}void short_delay(void){unsigned char i;for (i=0;i<8;i++);}void delay10ms(unsigned char time) {unsigned char i;unsigned int j;for (i=0;i<time;i++){for (j=0;j<0x390;j++);}}void disp1(unsigned int date){unsigned char d0, d1, d2 , d3; d0=date / 1000;d1=(date-d0*1000)/100;d2=(date-d0*1000-d1*100)/10 ;d3= date-d0*1000-d1*100-d2*10;write7279(DECODE1,d0);delay10ms(1);write7279(DECODE1+1,d1);delay10ms(1);write7279(DECODE1+2,d2);delay10ms(1);write7279(DECODE1+3,d3);delay10ms(1);}。

单片机PWM控制C程序语言

单片机PWM控制C程序语言

单片机P W M控制C程序语言(总3页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--下面介绍一下单片机PWM控制C语言实例,单片机PWM可以应用在许多方面,如电机调速、温度控制、压力控制等。

PWM—脉冲宽度调制,是一种周期一定而高低电平可调的方波信号。

广泛使用电机调速的项目中,用了S52单片机的T2定时器产生PWM波信号,用于控制直流电机的转速,虽然电机的平均速度与占空比不是严格的线性关系,但是在调节占空比可以明显的看出电机转速发生了改变,也算是满足了课题的要求。

下面复习一下PWM的知识吧:PWM—脉冲宽度调制,当输出脉冲的频率一定时,输出脉冲的占空比越大,相对应的输出有效电压越大。

PWM可以应用在许多方面,如电机调速、温度控制、压力控制等。

T1为脉冲宽度(就是导通时间),周期为T,则输出电压的平均值为U=VCC*T1/T=a*VCC,a是占空比,变化范围为0≤a≤1。

VCC为电源电压。

所以当电源电压不变的情况下,输出电压的平均值U取决于占空比a的大小,改变a的大小就可以改变输出电压的平均值,这就是PWM的工作原理。

采用T2定时器产生PWM脉冲极其精确,误差只在几个us。

// 单片机PWM控制C语言实例文件名:// 单片机PWM控制C语言实例功能: 用T2定时器产生PWM波,频率实调1khz// 单片机PWM控制C语言实例说明: 单片机AT89S52,晶振12MHZ;#include ""#define uint unsigned int#define uchar unsigned charsbit PWM = P1^1;uchar pluse; //占空比寄存器void Timer2() interrupt 5{static uchar time;TF2=0;if(++time==pluse) PWM=0; //达到脉宽设定值时,输出PWM低电平 else if(time==40) //PWM的频率为1khz左右{time=0;PWM=1;}}void InitTimer2(void) //初始化函数{RCAP2H = 0xff ;//定时25us初值RCAP2L = 0x0e7;//ET2=1;EA=1;TR2=1;}void main(void){InitTimer2();while(1){pluse=20;}}把PWM波的周期定为1ms,占空比分40级可调(即每级差%),这样定时器T2每25us产生一个定时中断,每40次中断后进入下一个PWM波的周期。

PWM调速的C语言程序编写(非常简单)

PWM调速的C语言程序编写(非常简单)

PWM调速的C语言程序编写关于PWM的原理在上一篇文章中已经说的很详细了,现在就细说一下pwm C语言程序的编写。

C语言中PWM的编写有这么几种方法;一、用普通的I/O 口输出的PWM ,二、使用定时计数器编写,三、就是使用片内PWM了。

1 先说使用普通的I\O口编写PWM程序了。

使用I/O口输出PWM波形你必须首先明白PWM他的实质是:调制占空比,占空比就是波形中高电平的长度与整个波长的比值。

我们写C语言的目的是写PWM波形的一个周期。

在这个周期内高低电平的比值是可以改变的。

这也就符合了PWM的原意脉宽调制。

即高电平的宽度的调制。

当然了PWM他也可用于改变频率,我们这里只先说他改变脉宽。

一旦我们的C语言程序写完那么他产生的PWM波形的频率就一定了。

(也可写频率变化的PWM,难度有点大)一般我们控制使用1K到10K的PWM波进行控制。

当然了你也可在要求不是很高的地方使用频率更低的PWM波。

比如在飞思卡尔智能车比赛中我们学校使用的PWM波频率只有600HZ.我们要改变一个PWM波周期内的高电平的宽度显然需要将一个PWM波的周期分成单片机可以控制的N个小的周期,N的取值越大你的调速等级越高,但产生的PWM频率就越低。

我们下面以实现100级调速为例编写PWM程序。

先写出程序再慢慢给大家分析void pwm (uchar x,uint y) //X 为占空比 Y为函数使用时间{ uint i,j,a,b;for(i=y;i>0;i--)//定时外函数{for(j=7;j>0;j--)//定时内函数{for(a=y;a>0;a--) / /PWM波高电平宽度{PORTA=0X01;}for(b=100-y;b>0;b--) //PWM低电平宽度{PORTA=0X00;}}}}这个程序够简单吧轻松的实现AVR单片机的PA.0口输出7KHZ左右的PWM脉冲你可以将PORTA=0X01;改为P1.0=0X01;就可以移植到51单片机上了为什么使用参数Y定时是因为用普通I/O口控制它的开关没有使用定时器编写的灵活。

无刷直流电机调速--C语言源程序

无刷直流电机调速--C语言源程序

附录1. C语言源程序:#include"stdio.h"#include"myapp.h"#include"ICETEK-VC5502-EDU.h"#include"scancode.h"#include"lcd.h"#define CTRSTATUS (*(unsigned int * )0x608000) //port8000#define CTRLED (*(unsigned int * )0x608004) //port8004#define MCTRKEY (*(unsigned int * )0x608005) //port8005#define CTRCLKEY (*(unsigned int * )0x608006) //port8006#define CTRMOTORBSPEED (*(unsigned int * )0x608003)void InitMcBSP();void INTR_init( void );void InitForMotorB( void );void showparameters();void LCDPutString(unsigned int * pData,int x,int y,unsigned int nCharNumber,unsigned color);void PIDControl(int rk,int yk);void PrintParameters();//定时器分频参数#define T100 99 // 100个时钟周期中断一次#define T2Hz 20000 // 20000个时钟周期读取速度一次//工作变量usigned int uWork,uN,nCount,nCount1,nCount2,nCount3,nCount4;int nSSS,nJSSpeed,pwm1;int md,wc;unsigned int nScreenBuffer[30*128];float a=0.6f,b=0.2f,c=0.1f,duk;int ek,ek1,ek2,tz;int nInput;unsigned int *www=(unsigned int *)0x608003;Int m_nSpeed,m_bPCSet;// 主函数main(){unsigned char ccc;int speed[100],sp,lj;float ljh;int i,w1,w2,w3;unsigned int uWork1;unsigned int bWork1,*pWork;int breakflage;// 初始化工作变量for ( sp=0;sp<100;sp++ )speed[sp]=0;for ( sp=0;sp<1024;sp++ ) nScreenBuffer[sp]=0;sp=nSSS=nCount=nCount1=nCount2=nCount3=nCount4=nJSSpeed=0;nInput=tz=wc =0;ek=ek1=ek2=0;uN=40;md=70;pwm1=60;m_nSpeed=70;m_bPCSet=0;inputspeed=0;uWork1=0;breakflage=0;initemif();CLK_init();*(int*)0x400001=1;CREG=1; //使能外部总线接口InitCTR();CTRGR=0x80;CTRGR=0;CTRGR=0x80;LCDTurnoff();// 设置显示参数和内容LCDSetDelay(1); //设置延时等待参数LCDSetScreenBuffer(nScreenBuffer); // 显示缓冲区for (bWork=0,pWork=nScreenBuffer;bWork<30*128;bWork++,pWork++) (*pWork=0)LCDTurnOn();//打开显示LCDCLS();//清除显示内存LCDPutCString(str1,0,127,8,0);LCDPutCString(str2,0,111,2,1);LCDPutCString(str3,68,111,2,1);LCDPutCString(str4,68,79,2,1);LCDPutCString(str5,68,95,2,1);LCDPutCString(str6,0,95,2,1);LCDPutCString(str7,0,79,3,1);ShowParamctors();//参数显示InitMcBSP();INTR-init();InitForMotorB();While(!breakflage){if(nCount==0) //读取键盘标志{uWork=MCTRKEY;CTRCLKEY=0;Switch(uWork1){Casc 128;if(inputspecd!=0){Md=inputspecd;Inputspecd=0;LCDPutCString(numbers+104,104,79,1,1);LCDPutCString(numbers+104,112,79,1,1);LCDPutCString(numbers+104,120,79,1,1);LCDRefreshScreen();}break;case 64;breakflage=1;case 1;inputspeed=inputspeed+1break;case 2;inputspeed=inputspeed-1;break;case 4;inputspeed=inputspeed+10;break;case 8;inputspeed=inputspeed-10;break;}if(inputspeed>90){inputspeed=90;}if(inputspeed<0){inputspeed=0;}w1=inputspeed%1000/100;w2=inputspeed%100/10;w3=inputspeed%10; LCDPutString(numbers+w1*8,104,79,1,1);LCDPutString(numbers+w2*8,112,79,1,1);LCDPutString(numbers+w3*8,120,79,1,1);LCDRefreshScreen();}if(m-bPCSet){m-bPCSst=0;if (m-nSpeed>=0&&m-nSpeed<256){md=m-nSpeed;LCDPutCString(numbers+104,104,79,1,1); LCDPutCString(numbers+104,112,79,1,1); LCDPutCString(numbers+104,120,79,1,1); LCDRefreshScreen();printparameters();}}if(nJSSpeed==0) //读取速度标志{LED=1;nJSSpeed=0;ccc=CTRMOTORBSPEED; //读取端口速度计数ccc=ccc&0xff;nSSS=ccc;if(nSSS>=0 && nSSS<400) //合法性检测{speed(sp)=Nssssp++;sp%=33;}if(sp==0) //读取实际速度{lj=0;ljh=0;for(i=0;i<33;i++){if(speed(i)>=0&&speed(i)<400){ljh+=speed(i);lj++;}}nCount3++;nCount3%=3;if(nCount3==2){PIDControl(md,wc); //调用PID算法控制程序uN=100-pwml; //利用占空比调整控制Showparameters(); //显示各参数到LCD}CloseCTR();exit(0);}//PID算法控制子程序void PIDControl(int rk,int yk){ek=rk-yk;duk=a*ek+b*ek1+c*ek2; //计算控制输出ek2=ek1; ek1=ek;tz=(int)duk;pwm1+=tz; //计算当前占空比if(pwml<0) pwml=0;else if(pwml>99) pwml=99;}void interrupt Timer(){uWork=PCR1; //pwml输出if(nCont1>u N){uWork=4; //根据占空比设置FSR状态}else{uWork&=0x0fffb;}PCR1=uWork;//设置中断控制寄存器void INTR-init(void){asm(“BSET INTM”);IVPD=0x01;IVPH=0x01;IERO=0x10;DBIERO=0x10;IFRO=0xffff;asm(“BCLR INTM”);}void InitForMotorB(void){ioport unsigned int *GPTCTL1-0;ioport unsigned int *GPTPRD1-0;ioport unsigned int *GPTGCTL1-0;*GPTCTL1-0=0;*GPTPRD1-0=0x1d8;*GPTGCTL1-0=0x3;}//显示参数到LCDvoid ShowParameters(){int w1,w2,w3;w1=md%1000/100;w2=md%100/10,w3=md%10; LCDPutString(numbers+w1*8,36,111,1,1); LCDPutString(numbers+w2*8,44,111,1,1); LCDPutString(numbers+w3*8,52,111,1,1);if (ek>=0){LCDPutString(numbers+88,36,95,1,1);w3=((int)ek)%100;}else{LCDPutString(numbers+96,36,95,1,1);w3=((int)(-ek))%100;}for (j=0;j<16;j++,k<<=1){if (color==2) mcolor=2;else{mcolor=(pData(1*8+i)&k)(1):(0);if(color==0) mcolor=1-mcolor;}LCDPutPixel(x+1*8+I,y-j,mcolor);}int wwss;void PrintParameters(){wwcc=wc-md;printf(“测速(%3d) 设置(%3d) 误差(%+4d) PID调整量(%+3d) 占空比(%3d%%)\n”,wc,md,wwcc,tz,pwm1);}。

嵌入式PWM模块驱动调速电机C程序

嵌入式PWM模块驱动调速电机C程序

#include<lm3sxxx.h>unsigned long TheSysClock=12000000UL;#include"lcdinit.h"#define PB0_PWM2 GPIO_PIN_0 //PWM2、产生正转信号#define PB1_PWM3 GPIO_PIN_1 //PWM3、产生反转信号#define KEY_PERIPH SYSCTL_PERIPH_GPIOC#define KEY_PORT GPIO_PORTC_BASE#define KEY1_PIN GPIO_PIN_4 //正反转切换#define KEY2_PIN GPIO_PIN_5 //2档#define KEY3_PIN GPIO_PIN_6 //1档#define KEY4_PIN GPIO_PIN_7 //制动unsigned int flag,value,D,S;/*****************************************************************************/ void clockInit(void){SysCtlLDOSet(SYSCTL_LDO_2_50V); // 设置LDO输出电压SysCtlClockSet(SYSCTL_USE_OSC | // 系统时钟设置SYSCTL_OSC_MAIN | // 采用主振荡器SYSCTL_XTAL_6MHZ | // 外接6MHz晶振SYSCTL_SYSDIV_1); // 不分频TheSysClock = SysCtlClockGet(); // 获取当前的系统时钟频率}void GPIO_Port_C_ISR(void){unsigned long ulStatus;ulStatus = GPIOPinIntStatus(GPIO_PORTC_BASE, true); // 读取中断状态GPIOPinIntClear(GPIO_PORTC_BASE, ulStatus); // 清除中断状态,重要if (ulStatus & KEY1_PIN) // 如果PC4的中断状态有效{ SysCtlDelay(200); //消除按键抖动flag=~flag;}if (ulStatus & KEY2_PIN) // 如果PC5的中断状态有效{ SysCtlDelay(200);value=50;S=2; //S=2表示高速}if (ulStatus & KEY3_PIN) // 如果PC6的中断状态有效{ SysCtlDelay(200);value=200;S=1; //S=1表示低速}if (ulStatus & KEY4_PIN) // 如果PC7的中断状态有效{ SysCtlDelay(200);value=300;S=0; //S=0表示制动}}/***************************************************************************/ void lcd_disp(){ lcd_pos(0,0);lcd_strwdat("Direct Is:"); //第一行显示正反转lcd_pos(0,14);lcd_write(1,D); //LCD写数据lcd_pos(1,0);lcd_strwdat("Now Speed Is:");//第二行显示转速的档位lcd_pos(1,14);lcd_write(1,S); //LCD写数据}void flag_1() //反转{ PWMOutputState(PWM_BASE, PWM_OUT_3_BIT, true);PWMOutputState(PWM_BASE, PWM_OUT_2_BIT, false); //使能或禁止PWM的输出PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, 300); // 设置PWM发生器1的周期PWMPulseWidthSet(PWM_BASE, PWM_OUT_3, value); // 设置PWM2输出的脉冲宽度D=0; //D=0表示反转}void flag_0(){ PWMOutputState(PWM_BASE, PWM_OUT_2_BIT, true); //正转PWMOutputState(PWM_BASE, PWM_OUT_3_BIT, false);PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, 300); // 设置PWM发生器1的周期PWMPulseWidthSet(PWM_BASE, PWM_OUT_2, value); // 设置PWM3输出的脉冲宽度D=1; //D=1表示正转}/***************************************************************************/ int main (void){lcd_init();clockInit();SysCtlPeripheralEnable (KEY_PERIPH); // 使能KEY所在的GPIO端口GPIOPinTypeGPIOInput(KEY_PORT, KEY1_PIN|KEY2_PIN|KEY3_PIN|KEY4_PIN);// 设置key1、key2、key3、key4为输入GPIOIntTypeSet(KEY_PORT, KEY1_PIN|KEY2_PIN|KEY3_PIN|KEY4_PIN, GPIO_LOW_LEVEL);// 设置KEY1、KEY2、KEY3、KEY4管脚的中断类型GPIOPinIntEnable(KEY_PORT, KEY1_PIN|KEY2_PIN|KEY3_PIN|KEY4_PIN);// 使能KEY1、KEY2、KEY3、KEY4所在管脚的中断IntEnable(INT_GPIOC); // 使能GPIOC端口中断SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // 使能PWM2和PWM3输出所在GPIOSysCtlPeripheralEnable(SYSCTL_PERIPH_PWM); // 使能PWM模块SysCtlPWMClockSet(SYSCTL_PWMDIV_1); // PWM时钟配置:不分频GPIOPinTypePWM(GPIO_PORTB_BASE, PB0_PWM2); // PB0配置为PWM功能GPIOPinTypePWM(GPIO_PORTB_BASE, PB1_PWM3); // PB1配置为PWM功能PWMGenConfigure(PWM_BASE, PWM_GEN_1, // 配置PWM发生器1:加减计数PWM_GEN_MODE_UP_DOWN |PWM_GEN_MODE_NO_SYNC);PWMOutputState(PWM_BASE, PWM_OUT_2_BIT, true); //初始化时flag=0、即电机初始化时是正转PWMOutputState(PWM_BASE, PWM_OUT_3_BIT, false);PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, 300); // 设置PWM发生器1的周期PWMPulseWidthSet(PWM_BASE, PWM_OUT_2, value); // 设置PWM3输出的脉冲宽度PWMGenEnable(PWM_BASE, PWM_GEN_1); // 使能PWM发生器1IntMasterEnable( ); // 使能处理器中断while(1){ SysCtlDelay(200);if(flag){ flag_1();lcd_disp();}else{ flag_0();lcd_disp();}}}/*****************************************************************************/。

c单片机C语言编写的PWM程序

c单片机C语言编写的PWM程序

89c51单片机C语言编写的PWM程序PWM, 单片机, C语言, 程序, 编写分享到:新浪微博 QQ空间开心网人人网说明:本程序使用STC89C52RC单片机,22.1184MHz晶振,要使用本程序需要自己修改,我是用来控制直流电机的,外接了L298驱动电路,有问题或意见请回复,谢谢^_^#include "reg52.H"#include "MyType.h"//=============L298端口定义===============sbit ENA = P3^6;?//左轮驱动使能sbit IN1 = P0^3;?//左轮黑线(-)sbit IN2 = P0^4;?//左轮红线(+)sbit IN3 = P0^5;?//右轮红线(-)sbit IN4 = P0^6;?//右轮黑线(+)sbit ENB = P3^7;?//右轮驱动使能//=============PWM================#define PWM_COUST 100?//PWM细分等份uchar MOTO_speed1;??//左边电机转速uchar MOTO_speed2; ??//右边电机转速uchar PWM_abs1;???//左边电机取绝对值后占空比uchar PWM_abs2;???//左边电机取绝对值后占空比?uchar PWM_var1=20;??//左边电机直走速度(不同的电机,此参数不同)uchar PWM_var2=20;??//右边电机直走速度uchar PWMAnd = 0;??//PWM自增变量/****************************************************************** 名称:motor(char speed1,char speed2);功能:同时调节电机的转速参数:speed1:电机1的PWM值;speed2:电机2的PWM值?? speed>0.正转;speed<0.反转(-100~100)调用:extern int abs(int val); 取绝对值返回:/******************************************************************/ void motor(char speed1,char speed2){??//==============左边电机=============?if (speed1>0)??{??IN1 =0;IN2 =1;//正转??}???else if (speed1<0)??{??IN1 =1;IN2 =0;//反转??}?//==============右边电机=============?if (speed2>0)??{??IN3 =1;IN4 =0;//正转??}?else if (speed2<0)??{??IN3 =0;IN4 =1;//反转??}}/******************************************************************名称:motor_PWM();功能:PWM占空比输出参数:无调用:无返回:无/******************************************************************/void motor_PWM (){?uchar PWM_abs1;?uchar PWM_abs2;?PWM_abs1=MOTO_speed1;?PWM_abs2=MOTO_speed2;?if (PWM_abs1>PWMAnd) ENA=1;??? //左边电机占空比输出??else ENA=0;?if (PWM_abs2>PWMAnd) ENB=1;??? //右边电机占空比输出??else ENB=0;?if (PWMAnd>=PWM_COUST) PWMAnd=0;? //PWM计数清零??else PWMAnd+=1;}???/******************************************************************名称:void TIME_Init ();功能:定时器初始化指令:调用:无返回:无/******************************************************************/void TIME_Init ()?{//=========定时器T2初始化 PWM==================?T2CON = 0x00;? ?T2MOD = 0x00;? ?RCAP2H = 0xff;?//定时0.1ms? ?RCAP2L = 0x47;? ?TH2 = 0xff;? ?TL2 = 0x47;?ET2 = 1;??//定时器2中断开?TR2 = 1;??//PWM定时器关,PWM周期为10ms?}/******************************************************************名称:void PWM_Time2 () interrupt 5功能:T2中断,PWM控制参数:调用:motor_PWM();//PWM占空比输出返回:/******************************************************************/?void PWM_Time2 () interrupt 5{? ?TR2 = 0;?TF2 = 0;?ET2 = 0;?//定时器0中断禁止?motor_PWM();//PWM占空比输出?ET2 = 1;?//定时中断0开启?TR2 = 1;}main(){TIME_Init ()?;motor(50,50);//左右电机的转速都是50}。

直流电机PWM调速程序(C语言)

直流电机PWM调速程序(C语言)

直流电机PWM调速程序(C语言)#include<reg52.h>//头文件#define ulong unsigned long//关键字宏定义 #define uchar unsigned charsbit motor_l_a=P0^2;//直流电机控制线接口定义 sbit motor_l_b=P0^3;// sbit motor_r_a=P0^0;// sbit motor_r_b=P0^1;// sbit motor_l_en=P0^4;// sbit motor_r_en=P0^5;////*****************变量定义***************************//ulong delay_flag=0;//用于较精确延时的变量 uchar pwm=0;//定时器0中断服务程序中的计数变量 uchar PWM_L=0,PWM_R=0;//***************函数声明******************************//void init_time0();//定时器0初始化函数 void motor_run(uchardirect,uchar speed_l,uchar speed_r);//直流电机控制函数.direct 控制方向,speed分别控制两个电机转速//***************主函数********************************//void main(){uchar i;//用于直流电机循环工作中的变量init_time0();//调用初始化函数while(1){for(i=0;i<11;i++)//直流电机正向加速{motor_run(1,i,i);delay_flag=20000;while(delay_flag);}for(i=10;i>0;i--)//直流电机反向减速{motor_run(0,i,i);delay_flag=20000;while(delay_flag);}}}void time0_pwm() interrupt 1//定时器0中断服务程序 { //**********************直流电机PWM调速部分***************************//pwm++;if(pwm==10)//设置PWM调速周期为1ms。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PWM调速的C语言程序编写
关于PWM的原理在上一篇文章中已经说的很详细了,现在就细说一下pwm C语言程序的编写。

C语言中PWM的编写有这么几种方法;一、用普通的I/O 口输出的PWM ,二、使用定时计数器编写,三、就是使用片内PWM了。

1 先说使用普通的I\O口编写PWM程序了。

使用I/O口输出PWM波形你必须首先明白PWM他的实质是:调制占空比,占空比就是波形中高电平的长度与整个波长的比值。

我们写C语言的目的是写PWM波形的一个周期。

在这个周期内高低电平的比值是可以改变的。

这也就符合了PWM的原意脉宽调制。

即高电平的宽度的调制。

当然了PWM他也可用于改变频率,我们这里只先说他改变脉宽。

一旦我们的C语言程序写完那么他产生的PWM波形的频率就一定了。

(也可写频率变化的PWM,难度有点大)一般我们控制使用1K到10K的PWM波进行控制。

当然了你也可在要求不是很高的地方使用频率更低的PWM波。

比如在飞思卡尔智能车比赛中我们学校使用的PWM波频率只有600HZ.
我们要改变一个PWM波周期内的高电平的宽度显然需要
将一个PWM波的周期分成单片机可以控制的N个小的周期,N的取值越大你的调速等级越高,但产生的PWM频率就越低。

我们下面以实现100级调速为例编写PWM程序。

先写出程序再慢慢给大家分析
void pwm (uchar x,uint y) //X 为占空比 Y为函数使用时间
{ uint i,j,a,b;
for(i=y;i>0;i--)
//定时外函数
{
for(j=7;j>0;j--)
//定时内函数
{
for(a=y;a>0;a--) / /PWM波高电平宽度
{
PORTA=0X01;
}
for(b=100-y;b>0;b--) //PWM低电平宽度
{
PORTA=0X00;
}
}
}
}
这个程序够简单吧轻松的实现AVR单片机的PA.0口输出7KHZ左右的PWM脉冲
你可以将PORTA=0X01;改为P1.0=0X01;就可以移植到51单片机上了为什么使用参数Y定时是因为用普通I/O口控制它的开关没有使用定时器编写的灵活。

如果这不符合你的需要你可以不使用时间参数Y控制他的开关,只要去掉关于Y的部分利用控制I/O口的方向来控制它的使用
上面的程序参数如下
在mega16单片机上使用 8M晶振
一个PWM脉冲大约128μs
循环7次是940ms 所以输出PWM脉冲频率是7KHZ左右
注意:我使用时精度要求不高所以没有考虑for语句运行时花费的时间故实际占空比略低,但误差是很小的。

需要高精度的朋友可以自己做修改。

2.下面说如何使用定时/计数器来编写PWM C语言程序;。

相关文档
最新文档