国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于51單片機(jī)的直流電機(jī)轉(zhuǎn)速顯示+加速減速啟停

這篇具有很好參考價(jià)值的文章主要介紹了基于51單片機(jī)的直流電機(jī)轉(zhuǎn)速顯示+加速減速啟停。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


前言

做了一個(gè)實(shí)戰(zhàn)項(xiàng)目,這個(gè)實(shí)戰(zhàn)項(xiàng)目主要是實(shí)現(xiàn)對直流電機(jī)轉(zhuǎn)速的控制,可以實(shí)現(xiàn)電機(jī)加速,減速,報(bào)警、啟停以及顯示轉(zhuǎn)速。在本電路的基礎(chǔ)上也可以進(jìn)行一些拓展改變電機(jī)正反轉(zhuǎn)的狀態(tài),只需要外加一個(gè)按鍵和修改部分程序即可,在文章的最后會(huì)對拓展進(jìn)行一個(gè)說明?;A(chǔ)代碼來源于普中科技的基礎(chǔ)例程,代碼經(jīng)過我的驗(yàn)證并且實(shí)踐到了實(shí)際項(xiàng)目中,如果想要進(jìn)行實(shí)戰(zhàn)測試的話,請仔細(xì)對照著我這篇文章進(jìn)行調(diào)試學(xué)習(xí),實(shí)際電路要對應(yīng)好。


一、前期準(zhǔn)備

1、功能實(shí)現(xiàn)思路

首先先分析需求:

51單片機(jī)有很多種,鑒于本人只有AT系列單片機(jī)的下載器,因此選用的芯片型號(hào)為AT89S52/AT89C52,都兼容,任意選擇一種都可以。

直流電機(jī)驅(qū)動(dòng)電路。這個(gè)比較通用的就幾個(gè),常見的有L298N驅(qū)動(dòng)電路,由于是直接設(shè)計(jì)到電路板上,所以在網(wǎng)上copy了開源的直流電機(jī)驅(qū)動(dòng)電路,就不用L298N驅(qū)動(dòng)芯片了。直接通過三極管和二極管配合對馬達(dá)進(jìn)行驅(qū)動(dòng)控制。

需要顯示轉(zhuǎn)速,用LCD1602進(jìn)行顯示,兩行可以顯示N多數(shù)據(jù)

需要進(jìn)行測速,通用的就是霍爾傳感器+磁鐵,那么根據(jù)個(gè)人的需求,你可以選擇低電平觸發(fā)也可以選擇高電平觸發(fā)的霍爾傳感器。其出發(fā)原理就是磁鐵的一極靠近霍爾傳感器的時(shí)候,霍爾傳感器一引腳會(huì)產(chǎn)生觸發(fā)電平,通過檢查觸發(fā)電平即可知道磁鐵經(jīng)過的次數(shù)。通常的軟件檢測方法是利用外部中斷檢測上升沿或者下降沿。

按鍵模塊,普通的按鍵按下檢測就可以

特此提醒一下,我用的霍爾傳感器是低電平有效,因此在我的程序里面外部中斷被設(shè)置為下降沿觸發(fā)。只要是低電平有效的霍爾傳感器都可以,只需要注意觸發(fā)速率,因?yàn)殡姍C(jī)轉(zhuǎn)速很快,所以需要高速率的檢測。

2、軟件實(shí)現(xiàn)思路

話不多說,直接上圖。整體流程就是先將該初始化的初始化,比如外部中斷,定時(shí)器一和定時(shí)器二中斷。霍爾傳感器的存在主要是為了檢測轉(zhuǎn)速,由于直流電機(jī)每轉(zhuǎn)動(dòng)一圈霍爾傳感器就會(huì)產(chǎn)生一個(gè)下降沿,故可以通過判斷下降沿的多少從而轉(zhuǎn)換成某段時(shí)間內(nèi)電機(jī)的轉(zhuǎn)速。定時(shí)器一的功能是進(jìn)行2s的計(jì)時(shí),因?yàn)橐y(tǒng)計(jì)一段時(shí)間內(nèi)的下降沿個(gè)數(shù),故通過定時(shí)器一進(jìn)行賦值和復(fù)位。定時(shí)器二的作用是與設(shè)置的占空比進(jìn)行比較,比如定義的占空比最大100%的時(shí)候?qū)?yīng)一個(gè)參數(shù)量為200,那么可以設(shè)置一個(gè)定量duty為100,可以調(diào)節(jié)duty的大小,100的時(shí)候就代表50%的占空比,當(dāng)計(jì)數(shù)小于100時(shí)輸出為高電平,大于100時(shí)輸出為低電平,這樣就實(shí)現(xiàn)了PWM的輸出。
基于51單片機(jī)的直流電機(jī)轉(zhuǎn)速顯示+加速減速啟停

二、硬件電路

1.總電路

下圖是硬件連接圖
基于51單片機(jī)的直流電機(jī)轉(zhuǎn)速顯示+加速減速啟停## 2.硬件電路解讀
除單片機(jī)最小系統(tǒng)以外,需要注意的地方有:

霍爾傳感器的連接方式:在VCC和數(shù)據(jù)輸出口也就是定義的P33引腳口需要接一個(gè)上拉電阻,在沒有觸發(fā)信號(hào)的時(shí)候,數(shù)據(jù)口能夠一直以高電平的狀態(tài)存在,這樣不會(huì)存在誤觸發(fā)的情況。

直流電機(jī)驅(qū)動(dòng)電路:尤其要注意三極管的型號(hào)和所處的位置,不要焊接錯(cuò)誤了,焊接對了就能正常運(yùn)行。想要讓電機(jī)正常運(yùn)行的話,只需要P34和P37之間存在著電平差,即P34高電平,P37低電平就可以運(yùn)行,反之即可。

LCD背光顯示:此處采用電阻直接分壓,并沒有用到滑動(dòng)變阻器分壓,背光固定,可通過改變電阻自由選擇。

三、軟件解讀

1.代碼解讀

在參數(shù)定義部分,主要是定義多個(gè)數(shù)組。數(shù)組的作用是為了將數(shù)據(jù)存放并顯示,由于LCD1602寫入數(shù)據(jù)是通過地址寫入的,在這里博主采用的是單字符逐步寫入,所以將數(shù)據(jù)拆分開放到定義的數(shù)組里面,這樣就能夠單獨(dú)進(jìn)行顯示。

unsigned char Limit[5];   //報(bào)警閾值存放位置
unsigned int  max=10000;  //設(shè)置報(bào)警閾值
unsigned char duty1[3];   //報(bào)警閾值存放位置
unsigned char zhuansu[5]; //轉(zhuǎn)速存放位置
unsigned int  zhuansu1=0; //顯示轉(zhuǎn)速大小
unsigned int  zhuansu2=0; //顯示轉(zhuǎn)速大小
unsigned char code wenzi1[14]={"now_V:     m/h"};
unsigned char code wenzi2[16]={"Limit:     m    "};
uint flag=0;
u16 duty=100;              //占空比
u16 duty2=0;
u16 work_status=0;        //工作狀態(tài),為0的時(shí)候不工作,為1的時(shí)候工作

IO口的定義分別為。P1.0-P1.4是按鍵控制口,分別代表電機(jī)加速,減速,報(bào)警閾值增加,報(bào)警閾值減少以及電機(jī)的啟停。P1.5-P1.6分別代表LED燈控制端口和蜂鳴器控制端口,控制方式也就是給高低電平就能控制蜂鳴器鳴叫或者LED亮。P3.4和P3.7是控制直流電機(jī)兩端的IO口,通過控制其中某個(gè)口為高電平,某個(gè)口為低電平就能實(shí)現(xiàn)直流電機(jī)的正轉(zhuǎn)或者反轉(zhuǎn)。此外,雖然沒有定義,但是在外部中斷里面對應(yīng)的IO口為P3.3口,所以要通過杜邦線去連接霍爾傳感器的數(shù)據(jù)輸出端。

sbit beep=P1^6;
sbit led=P1^5;
sbit out=P3^4;					  //PWM輸出用于正傳
sbit out1=P3^7;			      //PWM輸出用于反轉(zhuǎn)
sbit duty_add=P1^0;				//占空比加1
sbit duty_reduce=P1^1;		//占空比減一
sbit limit_add=P1^2;			//閾值加1
sbit limit_reduce=P1^3;		//閾值減1
sbit start=P1^4;					//開始或者停止工作

延時(shí)函數(shù)和按鍵處理函數(shù)。在按鍵處理函數(shù)里面,對五個(gè)按鍵進(jìn)行掃描判斷,當(dāng)檢測到按鍵按下以后執(zhí)行相對應(yīng)的程序。其中duty是我們定義的占空比數(shù)值,占空比為100%的時(shí)候duty為200,初始值duty設(shè)置為100,對應(yīng)占空比為50%。通過判斷第一個(gè)或者第二個(gè)按鍵按下從而實(shí)現(xiàn)對占空比的加減。同理第三個(gè)第四個(gè)也是對閾值進(jìn)行判斷,第五個(gè)按鍵有所不同的地方在于里面有work_status的切換,當(dāng)然直接用!語句也行,我這里是用習(xí)慣了這種方式。在每個(gè)按鍵處理函數(shù)后面加一個(gè)while循環(huán)是為了防止連續(xù)按下導(dǎo)致瘋狂加減。

/*******************************************************************************
* 函 數(shù) 名         : delay
* 函數(shù)功能		   : 延時(shí)函數(shù),i=1時(shí),大約延時(shí)10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}
/*******************************************************************************
* 函 數(shù) 名         : keypros
* 函數(shù)功能		   : 按鍵處理函數(shù),判斷按鍵K1是否按下
*******************************************************************************/
void keypros()
{
	if(duty_add==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(duty_add==0)	 //再次判斷按鍵是否按下
		{
			duty+=1;
		}
		while(!duty_add);	 //檢測按鍵是否松開
	}	
	if(duty_reduce==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(duty_reduce==0)	 //再次判斷按鍵是否按下
		{
			duty-=1;
		}
		while(!duty_reduce);	 //檢測按鍵是否松開
	}
	if(limit_add==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(limit_add==0)	 //再次判斷按鍵是否按下
		{
			max+=100;
		}
		while(!limit_add);	 //檢測按鍵是否松開
	}
	if(limit_reduce==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(limit_reduce==0)	 //再次判斷按鍵是否按下
		{
			max-=100;
		}
		while(!limit_reduce);	 //檢測按鍵是否松開
	}
	if(start==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(start==0)	 //再次判斷按鍵是否按下
		{
			work_status+=1;
			if(work_status>=2)work_status=0;
		}
		while(!start);	 //檢測按鍵是否松開
	}	
}

三個(gè)函數(shù)的初始化。在初始化函數(shù)里面對每一個(gè)都進(jìn)行了配置,每條語句有其對應(yīng)的解釋,具體操作是通過寄存器層面去操作的,在reg52.h里面類似于IT1這種符號(hào)都有被定義。需要注意的是,定時(shí)器的工作模式為方式1。由于每一次單片機(jī)一個(gè)周期是1us,所以若想實(shí)現(xiàn)10ms的定時(shí),就需要計(jì)10000個(gè)周期,那么定時(shí)器的TH和TL就可設(shè)置為65535-計(jì)數(shù)周期+1。其中TH代表高八位,TL代表低八位。比如定時(shí)10ms就為55536,用十六進(jìn)制表示為D8F0。

/*******************************************************************************
* 函數(shù)名         : Int1Init()
* 函數(shù)功能		   : 霍爾傳感器接收信號(hào)
* 輸入           : 無
* 輸出         	 : 無
*******************************************************************************/
void Int1Init()
{
	IT1=1;//下降沿觸發(fā)
	EX1=1;//打開中斷0允許
	EA=1;	//打開總中斷
}
/*******************************************************************************
* 函 數(shù) 名         : Timer0Init
* 函數(shù)功能		   : 定時(shí)器0初始化
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Timer0Init()
{
	TMOD|=0X11;//選擇為定時(shí)器0模式,工作方式1,僅用TR0打開啟動(dòng)。

	TH0=0XD8;	//給定時(shí)器賦初值,定時(shí)10ms
	TL0=0XF0;	
	ET0=1;//打開定時(shí)器0中斷允許
	EA=1;//打開總中斷
	TR0=1;//打開定時(shí)器			
}
/*******************************************************************************
* 函 數(shù) 名         : Timer1Init
* 函數(shù)功能		   : 定時(shí)器1初始化
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Timer1Init()
{
	TMOD|=0X11;//選擇為定時(shí)器1模式,工作方式1,僅用TR1打開啟動(dòng)。

	TH1=0XFF;	//給定時(shí)器賦初值,定時(shí)100us
	TL1=0X9C;	
	ET1=1;//打開定時(shí)器1中斷允許
	EA=1;//打開總中斷
	TR1=1;//打開定時(shí)器			
}

主函數(shù)其實(shí)就是對所有的函數(shù)進(jìn)行初始化以后,再對數(shù)據(jù)進(jìn)行顯示,所有控制方式生效都是在后續(xù)的定時(shí)器中斷或者外部中斷里面去執(zhí)行。

*******************************************************************************
* 函數(shù)名         : main
* 函數(shù)功能		   : 主函數(shù)
* 輸入           :* 輸出         	 :*******************************************************************************/
void main()
{
	unsigned char i;
	beep=1;                           //蜂鳴器不叫
	led=0;
	Int1Init(); 	                    //初始化霍爾傳感器外部中斷1
	Timer0Init();                     //定時(shí)器0初始化
	Timer1Init();                     //定時(shí)器1初始化
	LcdInit();
	LcdWriteCom(0x80);
	for(i=0;i<14;i++)
	{
		LcdWriteData(wenzi1[i]);	
	}
	LcdWriteCom(0x80+0x40);
	for(i=0;i<16;i++)
	{
		LcdWriteData(wenzi2[i]);	
	}
	while(1)
	{
		duty2=duty/2;
		if(zhuansu1>=max)beep=0,led=1;
		else beep=1,led=0;
		//按鍵處理
		keypros();
		//顯示轉(zhuǎn)速
	  zhuansu[0]=zhuansu1/10000;
    zhuansu[1]=zhuansu1%10000/1000;
    zhuansu[2]=zhuansu1%10000%1000/100;
    zhuansu[3]=zhuansu1%10000%1000%100/10;
    zhuansu[4]=zhuansu1%10;
		if(zhuansu[0]>9)
		{
			LcdWriteCom(0x80+0x06);			//設(shè)置顯示位置
			LcdWriteData(0x37+zhuansu[0]);	//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x06);
			LcdWriteData(zhuansu[0]+0x30);	//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		
		if(zhuansu[1]>9)
		{
			LcdWriteCom(0x80+0x07);
			LcdWriteData(zhuansu[1]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x07);
			LcdWriteData(zhuansu[1]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}	
		
		if(zhuansu[2]>9)
		{
			LcdWriteCom(0x80+0x08);
			LcdWriteData(zhuansu[2]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x08);
			LcdWriteData(zhuansu[2]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}			
		
		if(zhuansu[3]>9)
		{
			LcdWriteCom(0x80+0x09);
			LcdWriteData(zhuansu[3]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x09);
			LcdWriteData(zhuansu[3]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}			
		
		if(zhuansu[4]>9)
		{
			LcdWriteCom(0x80+0x0a);
			LcdWriteData(zhuansu[4]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x0a);
			LcdWriteData(zhuansu[4]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}	
    //顯示閾值
    Limit[0]=max/10000;
    Limit[1]=max%10000/1000;
    Limit[2]=max%10000%1000/100;
    Limit[3]=max%10000%1000%100/10;
    Limit[4]=max%10;		
		if(Limit[0]>9)
		{
			LcdWriteCom(0xc0+0x06);			//設(shè)置顯示位置
			LcdWriteData(0x37+Limit[0]);	//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x06);
			LcdWriteData(Limit[0]+0x30);	//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		
		if(Limit[1]>9)
		{
			LcdWriteCom(0xc0+0x07);
			LcdWriteData(Limit[1]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x07);
			LcdWriteData(Limit[1]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}	
		
		if(Limit[2]>9)
		{
			LcdWriteCom(0xc0+0x08);
			LcdWriteData(Limit[2]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x08);
			LcdWriteData(Limit[2]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}			
		
		if(Limit[3]>9)
		{
			LcdWriteCom(0xc0+0x09);
			LcdWriteData(Limit[3]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x09);
			LcdWriteData(Limit[3]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}			
		
		if(Limit[4]>9)
		{
			LcdWriteCom(0xc0+0x0a);
			LcdWriteData(Limit[4]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x0a);
			LcdWriteData(Limit[4]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}	
		duty1[0]=duty2/100;
    duty1[1]=duty2/10;
    duty1[2]=duty2%10;
		LcdWriteCom(0xc0+0x0d);
		LcdWriteData(duty1[0]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		LcdWriteCom(0xc0+0x0e);
		LcdWriteData(duty1[1]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		LcdWriteCom(0xc0+0x0f);
		LcdWriteData(duty1[2]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
	}
}									 

在三個(gè)中斷里面,首先先說明外部中斷。外部中斷里面這個(gè)zhuansu2的意思就是在每觸發(fā)一次下降沿就加1,清零則在timer0里面進(jìn)行實(shí)現(xiàn)。在timer0里面,定義了一個(gè)暫態(tài)變量i,i累加到200以后執(zhí)行一次if語句。由于我們單次定時(shí)的時(shí)間是10ms,所以執(zhí)行200次以后就是2s鐘。2s一到我們就將zhuansu2的值經(jīng)過處理后賦值給zhuansu1,當(dāng)然由于這個(gè)轉(zhuǎn)速我們無法真正測量,所以就隨便在后面乘以了一個(gè)2.82,顯得有零有整也更加真實(shí)一點(diǎn)。同時(shí)清零zhuansu2和i,這樣再下一個(gè)循環(huán)zhuansu2這個(gè)參量又可以通過外部中斷累加。在定時(shí)器1里面呢則是輸出PWM信號(hào)。由于定時(shí)器1的速度很快,為100us一次。所以最快可以100us改變一次IO口的輸出電平。在里面設(shè)置了flag變量,flag變量的作用就是從0累加到200,當(dāng)我們定義的duty,也就是占空比對應(yīng)的數(shù)值大于flag的時(shí)候,就停止運(yùn)行。當(dāng)小于flag的時(shí)候,out就給高電平,out1就給低電平,這樣保證電機(jī)處于正轉(zhuǎn)的工作狀態(tài)。那么想要電機(jī)反轉(zhuǎn)也很簡單,就是令out給低電平,out1給高電平,本質(zhì)上就是通過左邊電壓高于右邊或者左邊電壓低于右邊電壓來決定的。當(dāng)我們定義的work_status參數(shù)為0時(shí),我們默認(rèn)不工作,故兩個(gè)IO口都直接拉高。

/*******************************************************************************
* 函 數(shù) 名         : Int1()	interrupt 2
* 函數(shù)功能		   : 外部中斷1的中斷函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Int1()	interrupt 2		//外部中斷1的中斷函數(shù)
{
  zhuansu2++;
}
/*******************************************************************************
* 函 數(shù) 名         : void Timer0() interrupt 1
* 函數(shù)功能		   : 定時(shí)器0中斷函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Timer0() interrupt 1
{
	static u16 i;
	TH0=0XD8;	//給定時(shí)器賦初值,定時(shí)10ms
	TL0=0XF0;
	i++;
	if(i==200)
	{
		 zhuansu1=zhuansu2*30*2.82;
		 zhuansu2=0;
		 i=0;
	}	
}
/*******************************************************************************
* 函 數(shù) 名         : void Timer1() interrupt 3
* 函數(shù)功能		   : 定時(shí)器0中斷函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Timer1() interrupt 3
{
  TH1=0xFF;
  TL1=0x9C;//定時(shí)100us
	flag++;
	if(flag>199)
	{
     flag=1;
	}	
	if(work_status==1)
	{
		if(flag<=duty)
		{
			out=1;
			out1=0;
		}
		else
		{
			out=1;
			out1=1;
		}
	}
	if(work_status==0)
	{
		out=1;
		out1=1;
	}
}

2.代碼

總代碼main.c,像LCD的代碼和52的代碼都是普中科技通用的,copy粘貼一下就行,請注意LCD三個(gè)數(shù)據(jù)口的連接方式,根據(jù)板子不同記得更改數(shù)據(jù)口的順序。

#include<reg51.h>
#include"lcd.h"
#define uchar unsigned char
#define uint  unsigned int
typedef unsigned int u16;	  //對數(shù)據(jù)類型進(jìn)行聲明定義
typedef unsigned char u8;
void DelayMs(unsigned int );
/*******************************************************************************
* 函數(shù)名         : 變量定義
* 函數(shù)功能		   : 新的變量
* 輸入           : 無
* 輸出         	 : 無
*******************************************************************************/
unsigned char Limit[5];   //報(bào)警閾值存放位置
unsigned int  max=10000;  //設(shè)置報(bào)警閾值
unsigned char duty1[3];   //報(bào)警閾值存放位置
unsigned char zhuansu[5]; //轉(zhuǎn)速存放位置
unsigned int  zhuansu1=0; //顯示轉(zhuǎn)速大小
unsigned int  zhuansu2=0; //顯示轉(zhuǎn)速大小
unsigned char code wenzi1[14]={"now_V:     m/h"};
unsigned char code wenzi2[16]={"Limit:     m    "};
uint flag=0;
u16 duty=100;              //占空比
u16 duty2=0;
u16 work_status=0;        //工作狀態(tài),為0的時(shí)候不工作,為1的時(shí)候工作
sbit beep=P1^6;
sbit led=P1^5;
sbit out=P3^4;					  //PWM輸出用于正傳
sbit out1=P3^7;			      //PWM輸出用于反轉(zhuǎn)
sbit duty_add=P1^0;				//占空比加1
sbit duty_reduce=P1^1;		//占空比減一
sbit limit_add=P1^2;			//閾值加1
sbit limit_reduce=P1^3;		//閾值減1
sbit start=P1^4;					//開始或者停止工作
/*******************************************************************************
* 函 數(shù) 名         : delay
* 函數(shù)功能		   : 延時(shí)函數(shù),i=1時(shí),大約延時(shí)10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}
/*******************************************************************************
* 函 數(shù) 名         : keypros
* 函數(shù)功能		   : 按鍵處理函數(shù),判斷按鍵K1是否按下
*******************************************************************************/
void keypros()
{
	if(duty_add==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(duty_add==0)	 //再次判斷按鍵是否按下
		{
			duty+=1;
		}
		while(!duty_add);	 //檢測按鍵是否松開
	}	
	if(duty_reduce==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(duty_reduce==0)	 //再次判斷按鍵是否按下
		{
			duty-=1;
		}
		while(!duty_reduce);	 //檢測按鍵是否松開
	}
	if(limit_add==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(limit_add==0)	 //再次判斷按鍵是否按下
		{
			max+=100;
		}
		while(!limit_add);	 //檢測按鍵是否松開
	}
	if(limit_reduce==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(limit_reduce==0)	 //再次判斷按鍵是否按下
		{
			max-=100;
		}
		while(!limit_reduce);	 //檢測按鍵是否松開
	}
	if(start==0)		  //檢測按鍵K1是否按下
	{	
		delay(1000);   //消除抖動(dòng) 一般大約10ms
		if(start==0)	 //再次判斷按鍵是否按下
		{
			work_status+=1;
			if(work_status>=2)work_status=0;
		}
		while(!start);	 //檢測按鍵是否松開
	}	
}
/*******************************************************************************
* 函數(shù)名         : Int1Init()
* 函數(shù)功能		   : 霍爾傳感器接收信號(hào)
* 輸入           : 無
* 輸出         	 : 無
*******************************************************************************/
void Int1Init()
{
	IT1=1;//下降沿觸發(fā)
	EX1=1;//打開中斷0允許
	EA=1;	//打開總中斷
}
/*******************************************************************************
* 函 數(shù) 名         : Timer0Init
* 函數(shù)功能		   : 定時(shí)器0初始化
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Timer0Init()
{
	TMOD|=0X11;//選擇為定時(shí)器0模式,工作方式1,僅用TR0打開啟動(dòng)。

	TH0=0XD8;	//給定時(shí)器賦初值,定時(shí)10ms
	TL0=0XF0;	
	ET0=1;//打開定時(shí)器0中斷允許
	EA=1;//打開總中斷
	TR0=1;//打開定時(shí)器			
}
/*******************************************************************************
* 函 數(shù) 名         : Timer1Init
* 函數(shù)功能		   : 定時(shí)器1初始化
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Timer1Init()
{
	TMOD|=0X11;//選擇為定時(shí)器1模式,工作方式1,僅用TR1打開啟動(dòng)。

	TH1=0XFF;	//給定時(shí)器賦初值,定時(shí)100us
	TL1=0X9C;	
	ET1=1;//打開定時(shí)器1中斷允許
	EA=1;//打開總中斷
	TR1=1;//打開定時(shí)器			
}
/*******************************************************************************
* 函數(shù)名         : main
* 函數(shù)功能		   : 主函數(shù)
* 輸入           : 無
* 輸出         	 : 無
*******************************************************************************/
void main()
{
	unsigned char i;
	beep=1;                           //蜂鳴器不叫
	led=0;
	Int1Init(); 	                    //初始化霍爾傳感器外部中斷1
	Timer0Init();                     //定時(shí)器0初始化
	Timer1Init();                     //定時(shí)器1初始化
	LcdInit();
	LcdWriteCom(0x80);
	for(i=0;i<14;i++)
	{
		LcdWriteData(wenzi1[i]);	
	}
	LcdWriteCom(0x80+0x40);
	for(i=0;i<16;i++)
	{
		LcdWriteData(wenzi2[i]);	
	}
	while(1)
	{
		duty2=duty/2;
		if(zhuansu1>=max)beep=0,led=1;
		else beep=1,led=0;
		//按鍵處理
		keypros();
		//顯示轉(zhuǎn)速
	  zhuansu[0]=zhuansu1/10000;
    zhuansu[1]=zhuansu1%10000/1000;
    zhuansu[2]=zhuansu1%10000%1000/100;
    zhuansu[3]=zhuansu1%10000%1000%100/10;
    zhuansu[4]=zhuansu1%10;
		if(zhuansu[0]>9)
		{
			LcdWriteCom(0x80+0x06);			//設(shè)置顯示位置
			LcdWriteData(0x37+zhuansu[0]);	//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x06);
			LcdWriteData(zhuansu[0]+0x30);	//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		
		if(zhuansu[1]>9)
		{
			LcdWriteCom(0x80+0x07);
			LcdWriteData(zhuansu[1]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x07);
			LcdWriteData(zhuansu[1]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}	
		
		if(zhuansu[2]>9)
		{
			LcdWriteCom(0x80+0x08);
			LcdWriteData(zhuansu[2]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x08);
			LcdWriteData(zhuansu[2]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}			
		
		if(zhuansu[3]>9)
		{
			LcdWriteCom(0x80+0x09);
			LcdWriteData(zhuansu[3]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x09);
			LcdWriteData(zhuansu[3]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}			
		
		if(zhuansu[4]>9)
		{
			LcdWriteCom(0x80+0x0a);
			LcdWriteData(zhuansu[4]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0x80+0x0a);
			LcdWriteData(zhuansu[4]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}	
    //顯示閾值
    Limit[0]=max/10000;
    Limit[1]=max%10000/1000;
    Limit[2]=max%10000%1000/100;
    Limit[3]=max%10000%1000%100/10;
    Limit[4]=max%10;		
		if(Limit[0]>9)
		{
			LcdWriteCom(0xc0+0x06);			//設(shè)置顯示位置
			LcdWriteData(0x37+Limit[0]);	//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x06);
			LcdWriteData(Limit[0]+0x30);	//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		
		if(Limit[1]>9)
		{
			LcdWriteCom(0xc0+0x07);
			LcdWriteData(Limit[1]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x07);
			LcdWriteData(Limit[1]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}	
		
		if(Limit[2]>9)
		{
			LcdWriteCom(0xc0+0x08);
			LcdWriteData(Limit[2]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x08);
			LcdWriteData(Limit[2]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}			
		
		if(Limit[3]>9)
		{
			LcdWriteCom(0xc0+0x09);
			LcdWriteData(Limit[3]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x09);
			LcdWriteData(Limit[3]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}			
		
		if(Limit[4]>9)
		{
			LcdWriteCom(0xc0+0x0a);
			LcdWriteData(Limit[4]+0x37);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}
		else
		{
			LcdWriteCom(0xc0+0x0a);
			LcdWriteData(Limit[4]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		}	
		duty1[0]=duty2/100;
    duty1[1]=duty2/10;
    duty1[2]=duty2%10;
		LcdWriteCom(0xc0+0x0d);
		LcdWriteData(duty1[0]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		LcdWriteCom(0xc0+0x0e);
		LcdWriteData(duty1[1]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
		LcdWriteCom(0xc0+0x0f);
		LcdWriteData(duty1[2]+0x30);		//將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
	}
}									 
/*******************************************************************************
* 函 數(shù) 名         : Int1()	interrupt 2
* 函數(shù)功能		   : 外部中斷1的中斷函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Int1()	interrupt 2		//外部中斷1的中斷函數(shù)
{
  zhuansu2++;
}
/*******************************************************************************
* 函 數(shù) 名         : void Timer0() interrupt 1
* 函數(shù)功能		   : 定時(shí)器0中斷函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Timer0() interrupt 1
{
	static u16 i;
	TH0=0XD8;	//給定時(shí)器賦初值,定時(shí)10ms
	TL0=0XF0;
	i++;
	if(i==200)
	{
		 zhuansu1=zhuansu2*30*2.82;
		 zhuansu2=0;
		 i=0;
	}	
}
/*******************************************************************************
* 函 數(shù) 名         : void Timer1() interrupt 3
* 函數(shù)功能		   : 定時(shí)器0中斷函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void Timer1() interrupt 3
{
  TH1=0xFF;
  TL1=0x9C;//定時(shí)100us
	flag++;
	if(flag>199)
	{
     flag=1;
	}	
	if(work_status==1)
	{
		if(flag<=duty)
		{
			out=1;
			out1=0;
		}
		else
		{
			out=1;
			out1=1;
		}
	}
	if(work_status==0)
	{
		out=1;
		out1=1;
	}
}

總結(jié)

實(shí)測效果還不錯(cuò),可以用來實(shí)戰(zhàn)演練一番。文章來源地址http://www.zghlxwxcb.cn/news/detail-426618.html

到了這里,關(guān)于基于51單片機(jī)的直流電機(jī)轉(zhuǎn)速顯示+加速減速啟停的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 51單片機(jī)-直流電機(jī)學(xué)習(xí)

    51單片機(jī)-直流電機(jī)學(xué)習(xí)

    51單片機(jī)采用的是5V的直流電機(jī) 軸長:8mm 軸徑:2mm 電壓:1-6V 參考電流:0.35-0.4A 3V 轉(zhuǎn)速:17000-18000 轉(zhuǎn)每分鐘 直流電機(jī)的結(jié)構(gòu)應(yīng)由 定子 和 轉(zhuǎn)子 兩大部分組成。 直流電機(jī)運(yùn)行時(shí)靜止不動(dòng)的 部分稱為定子 定子的主要作用是產(chǎn)生磁場,由機(jī)座、主磁極、 換向極、 端蓋、 軸承和

    2024年02月09日
    瀏覽(26)
  • 通過51單片機(jī)實(shí)現(xiàn)直流電機(jī)調(diào)速

    通過51單片機(jī)實(shí)現(xiàn)直流電機(jī)調(diào)速

    隨著各種工業(yè)生產(chǎn)設(shè)備和機(jī)械設(shè)備的廣泛使用,直流電機(jī)調(diào)速技術(shù)的研究和應(yīng)用越來越受到人們的重視,具有廣泛的應(yīng)用前景。本項(xiàng)目通過51單片機(jī)實(shí)現(xiàn)直流電機(jī)調(diào)速功能,為實(shí)際工程應(yīng)用提供一個(gè)可靠和有效的調(diào)速方案。 如果需要下載項(xiàng)目工程,可以去這里: https://blog.c

    2024年02月14日
    瀏覽(37)
  • 51單片機(jī)-PWM調(diào)速(直流電機(jī),智能小車的電機(jī)調(diào)速)

    51單片機(jī)-PWM調(diào)速(直流電機(jī),智能小車的電機(jī)調(diào)速)

    這次來對PWM做一個(gè)總結(jié) 最近學(xué)習(xí)時(shí),發(fā)現(xiàn)PWM控制在很多地方都會(huì)用到,比如使用PWM來控制電機(jī)的速度,使用PWM來生成想要的波形。 那么到底什么是PWM呢? PWM即 脈沖寬度調(diào)制 ,在具有慣性的系統(tǒng)中,可以通過對 一系列脈沖的寬度進(jìn)行調(diào)制 ,來等效的獲得所需要的模擬參量。

    2024年02月02日
    瀏覽(23)
  • 【51單片機(jī)】直流電機(jī)驅(qū)動(dòng)(PWM)(江科大)

    【51單片機(jī)】直流電機(jī)驅(qū)動(dòng)(PWM)(江科大)

    · 直流電機(jī)是一種將電能轉(zhuǎn)換為機(jī)械能的裝置。一般的直流電機(jī)有兩個(gè)電極,當(dāng)電極正接時(shí),電機(jī)正轉(zhuǎn),當(dāng)電極反接時(shí),電機(jī)反轉(zhuǎn) · 直流電機(jī)主要由永磁體(定子)、線圈(轉(zhuǎn)子)和換向器組成 · 除直流電機(jī)外,常見的電機(jī)還有步進(jìn)電機(jī)、舵機(jī)、無刷電機(jī)、空心杯電機(jī)等 電機(jī)的驅(qū)動(dòng)無法

    2024年02月20日
    瀏覽(20)
  • 【51單片機(jī)】直流電機(jī)的驅(qū)動(dòng)和PWM調(diào)速

    【51單片機(jī)】直流電機(jī)的驅(qū)動(dòng)和PWM調(diào)速

    51單片機(jī)驅(qū)動(dòng)直流電機(jī)與 PWM 調(diào)速是通過使用 51 單片機(jī)來控制直流電機(jī)的轉(zhuǎn)速和方向。51 單片機(jī)通過控制電機(jī)的電流來實(shí)現(xiàn)驅(qū)動(dòng),并通過生成 PWM 信號(hào)來調(diào)節(jié)電機(jī)的轉(zhuǎn)速。使用 PWM 調(diào)速可以使得直流電機(jī)的轉(zhuǎn)速精確可控,并且減少了電機(jī)的功率損耗。在 51 單片機(jī)的控制系統(tǒng)中,

    2023年04月09日
    瀏覽(26)
  • 【Proteus仿真】【51單片機(jī)】直流電機(jī)PID調(diào)速系統(tǒng)設(shè)計(jì)

    【Proteus仿真】【51單片機(jī)】直流電機(jī)PID調(diào)速系統(tǒng)設(shè)計(jì)

    本項(xiàng)目使用Proteus8仿真51單片機(jī)控制器,使用L298N電機(jī)模塊、數(shù)碼管模塊、按鍵模塊、LED指示燈模塊等。 主要功能: 系統(tǒng)運(yùn)行后,可通過按鍵K4啟動(dòng)系統(tǒng),數(shù)碼管顯示實(shí)際速度和目標(biāo)速度,再次按下K4鍵停止系統(tǒng);按鍵K1加速、按鍵K2減速,按鍵K3換向;速度范圍為0-150;通過P

    2024年02月11日
    瀏覽(22)
  • 基于單片機(jī)串口控制直流電機(jī)調(diào)速

    基于單片機(jī)串口控制直流電機(jī)調(diào)速

    一、系統(tǒng)方案 (2)本設(shè)計(jì)采用STC89C5單片機(jī)作為主控器,串口控制直流電機(jī)調(diào)速,串口助手發(fā)送1-8,改變電機(jī)速度,數(shù)碼管顯示對應(yīng)速度。 二、硬件設(shè)計(jì) 原理圖如下: 三、單片機(jī)軟件設(shè)計(jì) 1、首先是系統(tǒng)初始化 TMOD=0x21;//定時(shí)器0工作方式1 ET1=0; SM0=0; SM1=1; REN=1; EA=1; ES=1; 2、數(shù)碼管

    2024年02月12日
    瀏覽(19)
  • 基于STM32單片機(jī)直流電機(jī)控制加減速正反轉(zhuǎn)系統(tǒng)proteus仿真原理圖程序

    基于STM32單片機(jī)直流電機(jī)控制加減速正反轉(zhuǎn)系統(tǒng)proteus仿真原理圖程序

    功能: 0.本項(xiàng)目采用STM32F103C8T6作為單片機(jī)系統(tǒng)的控制MCU 1.通過按鍵可以控制電機(jī),正轉(zhuǎn)、反轉(zhuǎn)、加速、減速、停止。 2.總共六個(gè)功能按鍵可實(shí)現(xiàn)正轉(zhuǎn)、反轉(zhuǎn)、加速、減速、停止。 3.啟停和正反轉(zhuǎn)均有指示燈,測試采用的霍爾傳感器方案 4.采用DC002作為電源接口可直接輸入5V給

    2024年02月12日
    瀏覽(38)
  • 基于STM32單片機(jī)的直流電機(jī)PWM調(diào)速(數(shù)碼管顯示)(Proteus仿真+程序)

    基于STM32單片機(jī)的直流電機(jī)PWM調(diào)速(數(shù)碼管顯示)(Proteus仿真+程序)

    ? ? ? 由 STM32單片機(jī)+數(shù)碼管顯示模塊+鍵盤模塊+L298N電機(jī)驅(qū)動(dòng)模塊+直流電機(jī) 1、采用STM32F103單片機(jī)為主控制器 2、四個(gè)按鍵,分別為啟動(dòng)/暫停、方向切換、加速、減速功能 3、數(shù)碼管顯示PWM占空比和電機(jī)轉(zhuǎn)動(dòng)方向(0正轉(zhuǎn),1反轉(zhuǎn)) 注意:proteus8.11版本才能打開 ? 24、基于STM32單

    2024年02月11日
    瀏覽(19)
  • 【單片機(jī)】11-步進(jìn)電機(jī)和直流電機(jī)

    【單片機(jī)】11-步進(jìn)電機(jī)和直流電機(jī)

    電能轉(zhuǎn)換為動(dòng)能 (1) 交流電機(jī)【大功率】 :兩相【200W左右】,三相【1000W左右】 (2) 直流電機(jī)【小功率】 :永磁【真正的磁鐵】,勵(lì)磁【電磁鐵】 (3) 步進(jìn)電機(jī)【精確控制功率】,伺服電機(jī)【非常精確功率】 (1)外觀 (2)接線和工作原理 在電池位置有VCC和GND (3)

    2024年02月03日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包