1. 程式人生 > >微控制器PWM輸出控制直流電機(89c51系列、stc12c5a60s2系列)

微控制器PWM輸出控制直流電機(89c51系列、stc12c5a60s2系列)

目錄

【pwm是如何控制電機轉速】

【89C51系列微控制器產生pwm波】

【STC12C5A60S2系列微控制器輸出PWM】


【pwm是如何控制電機轉速】

在本科學習中,學生所做的小車多數為使用lm298n或者tb6612來驅動簡單的直流電機,我們需要微控制器輸出pwm波來控制直流電機轉速。

直流電機的PWM調速原理為:通過調節驅動電壓脈衝寬度的方式,並與電路中一些相應的儲能元件配合,改變了輸送到電樞電壓的幅值,從而達到改變直流電機轉速的目的。

【89C51系列微控制器產生pwm波】

89c51微控制器沒有自帶pwm發生器,如果想要使用傳統的51微控制器產生pwm,只能通過軟體模擬的方法來產生pwm。

軟體模擬可以分為軟體延時和定時器兩種方法。

1、軟體延時輸出pwm

使用延時函式產生頻率為1kHz的pwm方波(@12MHz晶振)

#include <reg52.h>

sbit pwm = P1^0;

void delay100us(unsigned int x)
{
	unsigned char i;
	while(--x)
	{
		i = 20;
		while (--i);
	}
}

int main(void)
{
	while(1)
	{
		pwm = 1;
		delay100us(6);
		pwm = 0;
		delay100us(4);
	}
}

proteus模擬結果

使用簡單的延時函式即可簡單地模擬出pwm波。但是這種方法缺點很明顯,就是在輸出pwm時佔用大量機器週期,此時若進行其他操作時會影響pwm的準確度。所以這種方法我們很少使用。

2、定時器產生pwm

使用定時器的溢位中斷,在中斷服務程式中改變IO口的電平高低,可以在多操作情況下輸出比較準確的pwm波形。

比如我們使用定時器0。

定時器工作模式:我們設定定時器0工作模式為方式1,16位自動過載模式,這樣可以獲得較寬的調頻範圍。

定時器中斷:16位自動過載模式下最多可以記65536個數,一旦超出這個數值,便會進入中斷。定時器初值可以使用定時器計算器計算,方便快捷。

使用定時器0產生佔空比可調,頻率為100Hz的pwm波。

#include <reg52.h>

sbit pwm = P1^0;

unsigned int PWM = 50;	//pwm佔空比為50%,可調佔空比
unsigned char time = 0;

void Time0Init(void)
{
	TMOD = 0X01;	//定時器工作在方式1(16位定時器)
	TH0 = 0XFF;		//12M晶振下定時0.01ms
	TL0 = 0X9c;
	ET0 = 1;			//開定時器1中斷
	EA = 1;
	TR0 = 1;			//開啟定時器
}

void Timer0(void) interrupt 1
{
	TH0 = 0XFF;		//重灌初值
	TL0 = 0X9c;
	time++;
}

void main(void)
{
	Time0Init();
	while(1)
	{
		if(time >= 100)	//PWM週期為100*0.1ms
			time = 0;
		if(time < PWM)		
			pwm = 1;
		else if(time >= PWM)
			pwm = 0;
	}
}

proteus模擬結果

由模擬結果來看,所得波形還是不算很精準,實際應用過程中還會有很多誤差,但是這樣已經比延時函式產生pwm的結果可靠的多。

【STC12C5A60S2系列微控制器輸出PWM】

我在做循跡小車時使用的是stc12c5a60s2微控制器。stc12c5a60s2微控制器集成了兩路可程式設計計數器陣列(PCA)模組,可用於軟體定時器、外部脈衝的捕捉、高速輸出以及脈寬調製(PWM)輸出。

使用stc12c5a60s2微控制器的PCA模組可通過程式設定,使其工作於8位PWM模式,通過P13和P14輸出。

如下圖所示:

PWM輸出頻率取決於PCA定時器的時鐘源。

 由於所有模組共用僅有的PCA定時器,所以它們的輸出頻率相同。各個模組的輸出佔空比是獨立變化的,與使用的捕獲暫存器[EPCnL, CCAPnL]有關。當暫存器CL的值小於[EPCnL,CCAPnL]時,輸出為低;當暫存器CL的值等於或大於[EPCnL, CCAPnL]時,輸出為高。當CL的值由FF變為00溢位時,[EPCnH, CCAPnH]的內容裝載到[EPCnL, CCAPnL]中。這樣就可實現無干擾地更新PWM。要使能PWM模式,模組CCAPMn暫存器的PWMn和ECOMn位必須置位。

 PCA時鐘輸入源頻率由於PWM是8位的,所以

PWM頻率 = PCA時鐘輸入源頻率 / 256

PCA時鐘輸入源可以從以下8種中選擇一種: SYSclk,   SYSclk/2,  SYSclk/4,SYSclk/6,SYSclk/8,SYSclk/12, 定時器0的溢位,ECI/P3.4輸入。

當某個I/O口作為PWM使用時,該口狀態:

PWM之前口的狀態 PWM輸出時口的狀態
弱上拉/準雙向 強推輓輸出/強上拉輸出,要加輸出限流電阻1K-10K
強推輓輸出/強上拉輸出 強推輓輸出/強上拉輸出,要加輸出限流電阻1K-10K
僅為輸入/高阻輸入 PWM無效
開漏 開漏

------

#include "stc12c5a.h"

void PCA_Init(void)
{
	CCON = 0;				//PCA初始化
	CMOD = 0x00;			//空閒時不計數,不產生中斷,時鐘源為Sysclk/12,PWM頻率大約為4KHz
	CL = 0x00;				//PCA低8位清零
	CH = 0x00;				//PCA高8位清零

	CCAPM0 = 0x42;			//8位PWM模式,無中斷
	CCAP0H = 0xc0;			//PWM0佔空比(調節此處值調節PWM佔空比)
	CCAP0L = 0xc0;			//PWM0佔空比(調節此處值調節PWM佔空比)

	CCAPM1 = 0x42;			//8位PWM模式,無中斷
	CCAP1H = 0x40;			//PWM1佔空比(調節此處值調節PWM佔空比)
	CCAP1L = 0x40;			//PWM1佔空比(調節此處值調節PWM佔空比)

	CR = 1;					//啟動PCA計數器
}

/*PWM佔空比設定*/
void PWM_Set(unsigned char x,unsigned char y)
{
  CCAP0H = y;				//設定比較值
  CCAP0L = y;	
  CCAP1H = x;				//設定比較值
  CCAP1L = x;
}

void main(void)
{
  P1M0 = 0xff;				//P1口推輓輸出
  P1M1 = 0x00;
  PCA_Init();				//PCA初始化
  
  PWM_Set(0x80,0x80);       //設定佔空比
}

此時產生的就是佔空比為50%的PWM波。使用示波器可以在P13和P14口測得PWM輸出波形。