?? 實驗5.c
字號:
//---------------------------------------------------------------------------------------
// 步進電機、直流電機控制板程Version1.1。
// 編寫開始日期:2008年1月27日
// 2008.1.30 改進版本1.1,改變測速方法:測霍爾元件若干次觸發的時間
// 程序中測速、步進電機精確調速、直流電機PWM精確控制等都合用一個T1計時器
// ,100us自動重裝。
//
// 測速方法:用T0作計數器,每計4個脈沖(霍爾),就讀一下T1中斷次數計時器
// count_pulse_time,這個值就是轉盤旋轉一周所花的時間。由于采用100us為最小時間
// 單位。速度測量具有一定的誤差。
//
// 步進電機精確控制速度方法:主要是精確控制每步走的時間。同樣利用T1的100us
// 定時器。根據設定的轉速,可求得每步所需要的時間間隔stepping_interval,
// 100us計數器采用count_stepping_interval,當count_stepping_interval計到
// stepping_interval值時,步進電機走一步。
//
// 2008.4.5修改:四個磁鋼改為一個磁鋼,計數只記一次。
// 2008.4.7修改:PWM用一個字節,從0-99,周期改為10ms
// 2008.4.12修改:測速用INT1中斷,計兩次中斷的時間,不用T0引腳
//---------------------------------------------------------------------------------------
//-------------------------------------變量定義------------------------------------------
#include "string.h"
#include "stdio.h"
#include "reg52.h"
sbit _A=0x90; //步進電機4相控制引腳
sbit _B=0x91;
sbit _C=0x92;
sbit _D=0x93;
sbit DC_MOTOR=0x96; //直流電機控制引腳
sbit clk0=0x97; //硬件環形分配器時鐘控制引腳
sbit DIR=0xb2; //硬件環形分配器方向控制引腳
unsigned char cmd;
// cmd為PC機通過串口發給控制板的命令值,后續PC可能再發1-2字節數據或控制板返回2字節數據:n1,n2
// cmd=0; PC機無命令
// cmd=0xc0; PC機要求軟件環形分配步進電機,以轉速(n1n2)運行,3字節命令。
// cmd=0xc1; PC機要求硬件環形分配步進電機,以轉速(n1n2)運行,3字節命令。
// cmd=0xc2; PC機要求直流電機以PWM=n1運行,n1為占空比百分數1-100.
// cmd=0xc3; PC機要求測電機轉速,控制板返回轉速(n1n2).
// cmd=0xc4;
// cmd=0xc5; PC機要求步進電機停止。
unsigned char step_index=0; //步進電機軟件分配表的索引值:0-7
unsigned int speed=0; //一秒內霍爾觸發計數次數,除4乘60即為轉速
unsigned int count_4pulse_time=0; //定時器T1中斷次數計時器,計4個T0脈沖(轉一圈)花了多少個100us.
//----步進電機精確調速所需變量-----------
unsigned int stepping_interval; //步進電機在用T0中斷精確定速時,每步時間間隔(即合計每步有多少個100us)
unsigned int count_stepping_time;//定時器T1中斷次數計數器,為計到stepping_interval值所設的計數器
bit stepping_by_T0=0; //用定時器T1調速步進電機標記:=1確認,=0取消
//----直流電機PWM精確調速----------------
unsigned int PWM=0; //直流電機脈寬調制系數(1到99)10^-1,精確到1%
//例如PWM=21表示21%
unsigned int count_DC_MOTOR_time;
//定時器T1中斷次數計數器,為計到PWM值所設的計數器
//----三種步進電機工作方式軟件分配表-----
unsigned char code step_tab0[8]={0x8,0x4,0x2,0x1,0x8,0x4,0x2,0x1};//4相單4拍
unsigned char code step_tab1[8]={0xc,0x6,0x3,0x9,0xc,0x6,0x3,0x9};//4相雙4拍
unsigned char code step_tab2[8]={0x8,0xc,0x4,0x6,0x2,0x3,0x1,0x9};//4相8拍
//-----LCD16液晶顯示控制引腳定義---------
sbit E=0xb4;
sbit RS=0xb7;
sbit RW=0xb6;
sfr lcd_dat_port=0x80; //lcd數據口
unsigned char lcd_buf[17];
unsigned int count_display; //液晶顯示刷新計時
//------按鍵端口定義---------------------
sfr key_port=0xa0; //P2口接鍵盤
unsigned char code key_index[16]={0xdb,0xee,0xde,0xbe, //0,1,2,3
0x7e,0xed,0xdd,0xbd, //4,5,6,7
0x7d,0xeb,0xbb,0x7b, //8,9,上,下
0xe7,0xd7,0xb7,0x77};//左,右,功能,確認
//------菜單變量定義--------------------
unsigned char menu_level=0; //菜單級別,0為沒選擇
unsigned char choice=0; //選擇項,0為沒選擇;
// 1為測速;
// 2為設定步進電機轉速;
// 3為設定PWM值
//-----------------------------變量定義結束------------------------------------------------
/*----------------- 約延時100us --------------------*/
delay(unsigned char dy)
{
unsigned char ii;
while(--dy)
for(ii=0;ii<24;ii++) ;
}
/*----------------步進電機環形分配驅動程序---------------*/
void step(bit direction)
{unsigned char state;
if (direction==1)
{if (++step_index>7) step_index=0;} //正轉
else
{if (--step_index<0) step_index=7;} //反轉
state=step_tab0[step_index];
//根據開關狀態決定使用硬件環形分配還是軟件環形分配
clk0=~clk0; //使用硬件環形分配器情況
_A=state & 0x8; //實用軟件環形分配器情況
_B=state & 0x4;
_C=state & 0x2;
_D=state & 0x1;
}
/*----------------------步進電機軟件延時的升速------------------------
void accelerating()
{
unsigned char i;
for(i=0;i<200;i++)
{step(1);
delay(240-i);
}
while(1)
{step(1);
delay(30); //最高速約可到20
}
}*/
/*------------------- 步進電機軟件延時調速------------------
void stepping(bit direction,unsigned char dy)
//direction為方向=0或=1; dy為每步延時時間從0-255
{
while(1)
{step(direction);
delay(dy); //最高速約可到20
}
}*/
//----------- T0、T1初始化設置,--------------------------
//2008.4.12日,將T0中斷改為INT1中斷
//功能: 設置T1定時100us,T0作計數(計霍爾脈沖數)測轉速
void set_T0T1() //測步進電機轉速時, T1作為定時器計100us時間
{ //T0計4個霍爾脈沖,察看需要的時間
TMOD=0x22; //T1:定時方式2,8位自動重裝定時器;T0:計數方式1,8自動重裝計數器.
TH1=256-184; //22.1184MHz晶振,184個機器周期約為100微秒(99.83us)
TL1=256-184;
TH0=256-56; //T0用來計20us,
TL0=256-56;
IT1=1; //INT1為邊沿觸發上升沿方式
EA=1;ET1=1;EX1=1;ET0=1; //開定時器T0中斷,改為INT1中斷
TR0=1;
TR1=1; //T0開始計數,T1開始計時
count_4pulse_time=0; //定時器T0累計數清零
}
//--------------步進電機定時器精確調速--------------------
//功能: 根據指定速度計算每步以100us為單位的時間間隔
void stepping_int(unsigned int stepping_speed_int) //speed_int是轉速:r/min
{
float stepping_speed; //為了減少計算帶來的誤差,先用浮點數進行計算
stepping_speed=stepping_speed_int;
stepping_speed=60/(stepping_speed*48);//得到每步秒數
stepping_speed=stepping_speed*10000; //得到每步百微秒數
stepping_interval=stepping_speed;
//set_T0T1(); //設置T1,T0: T1定時器作定時100us并控制步進電機,
// T0作計數以測定直流電機或步進電機轉速
stepping_by_T0=1;
}
/*--------------------直流電機PWM調速程序1-------------------
void pwm(unsigned char percent)//percent為占空比百分比從1到100
{ unsigned int i,j;
j=10*percent;
while(1)
{
DC_MOTOR=1;
for(i=0;i<j;i++);
DC_MOTOR=0;
for(i=0;i<1000-j;i++);
}
}*/
//------定時器T0計20us,用于產生PWM波---------------
void Timer0() interrupt 1 using 2 //每個脈沖進入1次中斷
{
count_DC_MOTOR_time++; //直流電機的PWM控制計時
if (count_DC_MOTOR_time>PWM)
{
DC_MOTOR=0;
if (count_DC_MOTOR_time>500) count_DC_MOTOR_time=0;
}
else DC_MOTOR=1;
}
//---------用INT1中斷計4個脈沖的中斷程序,測量步進電機及測直流電機轉速-------
void INT1_measurement() interrupt 2 //每個脈沖進入1次中斷
{ unsigned long long_speed; //為減少計算誤差,先用浮點數運算
long_speed=count_4pulse_time;
count_4pulse_time=0; //重新開始計數
long_speed=600000L/long_speed; //將計100us數的值轉換為每分轉的圈數
speed=long_speed;
}
//-------定時器T1的100us中斷程序,控制步進電機轉速并為步進/直流電機測速計時----
void Timer1() interrupt 3
{
count_4pulse_time++; //為步進電機或直流電機測速計時,4個脈沖一個周期=n個100us
count_stepping_time++; //為控制步進電機轉速計時,計每步是否達到預定速度要求的間隔時
count_display++;
if (count_4pulse_time>5000)
{
count_4pulse_time=0;
speed=0;
}
if ((stepping_by_T0==1)&&(count_stepping_time>=stepping_interval))
{ //控制步進電機速度
count_stepping_time=0;
step(1);
}
}
//---------------- 初始化串口 ---------------------------
void ini_com()
{
SM0=0;SM1=1;REN=1; //串口設定:方式1,即8位可變波特率,接收使能
T2CON=0x34; //用T2作為波特率發生器
RCAP2H=0xff;TH2=0xff;
RCAP2L=0xdc;TL2=0xdc; //0xdc=波特率19200 0xfa=115200
}
//----------------- 串口接收一字節 ----------------------
unsigned char receipt_byte()
{
unsigned int i=0;
while(RI==0 && i<1000) i++;
RI=0;
return(SBUF);
}
//----------------- 串口發送一字節 ----------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -