直流電機控制Keil c51源代碼
//-----------------------函數(shù)聲明,變量定義------------------------
#include
#include
#include
//-----------------------定義管腳----------------------------------
sbit PWM=P1^0; //PWM波形輸出
sbit DR=P1^1;//方向控制
#define timer_da
#define PWM_T 100 //定義PWM的周期T為10ms
unsigned char PWM_t; //PWM_t為脈沖寬度(0~100)時間為0~10ms
unsigned char PWM_count;//輸出PWM周期計數(shù)
unsigned char time_count; //定時計數(shù)
bit direction; //方向標(biāo)志位
//-----------------------------------------------------------------
// 函數(shù)名稱:timer_init
// 函數(shù)功能:初始化設(shè)施定時器
//-----------------------------------------------------------------
void timer_init()
{
TMOD=0x22; /*定時器1為工作模式2(8位自動重裝),0為模式2(8位自動重裝) */
PCON=0x00;
TF0=0;
TH0=timer_da
TL0=TH0;
ET0=1;
TR0=1; //開始計數(shù)
EA=1;//中斷允許
}
//-----------------------------------------------------------------
// 函數(shù)名稱:setting_PWM
// 函數(shù)功能:設(shè)置PWM的脈沖寬度和設(shè)定方向
//-----------------------------------------------------------------
void setting_PWM()
{
if(PWM_count==0) //初始設(shè)置
{
PWM_t=20;
direction=1;
}
}
//-----------------------------------------------------------------
// 函數(shù)名稱:IntTimer0
// 函數(shù)功能:定時器中斷處理程序
//-----------------------------------------------------------------
void IntTimer0() interrupt 1
{
time_count++;
DR=direction;
if(time_count>=PWM_T)
{
time_count=0;
PWM_count++;
setting_PWM(); //每輸出一個PWM波調(diào)用一次
}
if(time_count
else
PWM=0;
}
//-----------------------------------------------------------------
// 函數(shù)名稱:main
// 用戶主函數(shù)
// 函數(shù)功能:主函數(shù)
//-----------------------------------------------------------------
void main()
{
timer_init();
setting_PWM();
}
//=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=
直流電機閉環(huán)控制Keil c51源代碼
//-----------------------函數(shù)聲明,變量定義------------------------
#include
sbit INT_0 =P3^2; // 將p3.2外部中斷0
sbit pulse_A=P1^2; // P1.2為脈沖A輸入
sbit PWM=P1^0; //PWM波形輸出
sbit DR=P1^1; //方向控制
//-----------------------預(yù)定義值----------------------------------
#define PWM_T 1800 //定義PWM的周期T為18ms
#define Ts 1000 //定義光電編碼器采樣時間為10ms
#define timer_da
//-----------------------預(yù)設(shè)定值----------------------------------
bit direction; //方向標(biāo)志位 用戶設(shè)定
unsigned char R; //需要得到的直流電機轉(zhuǎn)速 用戶設(shè)定
//-----------------------實際運行狀態(tài)------------------------------
bit real_direction; //電機實際運行方向
unsigned char Rr; //直流電機實際轉(zhuǎn)速
//-----------------------計算所得補償狀態(tài)--------------------------
bit compensate_polarity; //補償極性
unsigned char dR; //轉(zhuǎn)速補償
//-----------------------經(jīng)補償后得到的脈寬------------------------
unsigned char PWM_t; //PWM_t為脈沖寬度(320~400)時間為3.2~4.0ms
unsigned char PWM_count; //輸出PWM周期計數(shù)
//-----------------------各中間計數(shù)值------------------------------
unsigned char pulseB_count; //脈沖計數(shù)
unsigned char time0_count; //定時計數(shù)
unsigned char time1_count; //定時計數(shù)
//-----------------------------------------------------------------
// 函數(shù)名稱:timer_init
// 函數(shù)功能:初始化設(shè)置定時器
//-----------------------------------------------------------------
void timer_init()
{
TMOD=0x22; /*定時器1為工作模式2(8位自動重裝),0為模式2(8位自動重裝) */
PCON=0x00;
TF0=0;
TH0=timer_da
TL0=TH0;
TH1=timer_da
TL1=TH0;
ET0=1; //定時器0中斷允許
TR0=1; //定時器0開始計數(shù)
ET1=1; //定時器1中斷允許
TR1=1; //定時器1開始計數(shù)
EA=1; //中斷允許
}
//-----------------------------------------------------------------
// 函數(shù)名稱: INT0_init()
// 函數(shù)功能: 初始化設(shè)置
// 設(shè)定INT0的工作方式
//-----------------------------------------------------------------
void INT0_init(void )
{
pulseB_count=0; //脈沖計數(shù)器清零
IT0=1; //選擇INT0為沿觸發(fā)方式
EX0=1; //外部中斷允許
EA=1; //系統(tǒng)中斷允許
}
//-----------------------------------------------------------------
// 函數(shù)名稱:setting_PWM
// 函數(shù)功能:設(shè)置PWM的脈沖寬度和設(shè)定方向
//-----------------------------------------------------------------
void setting_PWM()
{
// direction=1; //設(shè)定轉(zhuǎn)動方向
// R=540; //設(shè)定轉(zhuǎn)速
// dR=0; //轉(zhuǎn)速補償為零
// calculate_PWM_t(); //重新計算脈寬
}
//-----------------------------------------------------------------
// 函數(shù)名稱: calculate_PWM_t
// 入口參數(shù): R需要得到的直流電機轉(zhuǎn)速,dR轉(zhuǎn)速補償
// 出口參數(shù): PWM_t為脈沖寬度(320~400)時間為3.2~4.0ms
// 函數(shù)功能: 計算脈沖寬度,PWM_t=R/150;
//-----------------------------------------------------------------
void calculate_PWM_t()
{
if(compensate_polarity==1) //正補償
PWM_t=(R+dR)/150;
else
PWM_t=(R-dR)/150; //負(fù)修正
}
//-----------------------------------------------------------------
// 函數(shù)名稱: calculate_Rr
// 入口參數(shù): pulseB_count脈沖計數(shù)
// 出口參數(shù): Rr直流電機實際轉(zhuǎn)速
// 函數(shù)功能: 計算實際轉(zhuǎn)速
//-----------------------------------------------------------------
void calculate_Rr()
{
Rr=pulseB_count/6;
}
//-----------------------------------------------------------------
// 函數(shù)名稱: compensate_dR
// 入口參數(shù): Rr直流電機實際轉(zhuǎn)速
// R需要得到的直流電機轉(zhuǎn)速
// 出口參數(shù): dR轉(zhuǎn)速補償
// 函數(shù)功能: 計算實際補償值和補償極性 ,根據(jù)不同的補償算法重新設(shè)計
//-----------------------------------------------------------------
void compensate_Rr()
{
Rr=1;
if(Rr>R)
compensate_polarity=0; //補償極性
else
compensate_polarity=1;
}
//-----------------------------------------------------------------
// 函數(shù)名稱: INT0_intrupt
// 函數(shù)功能: 外部中斷0處理程序
//-----------------------------------------------------------------
void INT0_intrupt() interrupt 0 using 1
{
pulseB_count++;
if(pulse_A==0)
{
real_direction=1; //若P1.2為低電平,則電機為正轉(zhuǎn),計數(shù)器N的值加1
}
else //若為高電平,則電機為反轉(zhuǎn),計數(shù)器N值減l。
{
real_direction=1;
}
}
//-----------------------------------------------------------------
// 函數(shù)名稱:IntTimer0
// 函數(shù)功能:定時器中斷處理程序
//-----------------------------------------------------------------
void IntTimer0() interrupt 1
{
time0_count++;
DR=direction;
if(time0_count>=PWM_T)
{
time0_count=0;
PWM_count++;
setting_PWM(); //每輸出一個PWM波調(diào)用一次
}
if(time0_count
else
PWM=0;
}
//-----------------------------------------------------------------
// 函數(shù)名稱:IntTimer1
// 函數(shù)功能:定時器中斷處理程序
//-----------------------------------------------------------------
void IntTimer1() interrupt 3
{
time1_count++;
if(time1_count==1)
{
INT0_init(); //初始化外部中斷設(shè)置
}
if(time1_count>=Ts)
{
time1_count=0; //一個補償周期結(jié)束,計數(shù)器清零
calculate_Rr(); //計算實際轉(zhuǎn)速
compensate_Rr(); //計算實際補償值和補償極性
calculate_PWM_t(); //重新計算脈寬
}
}
//-----------------------------------------------------------------
// 函數(shù)名稱:main
// 用戶主函數(shù)
// 函數(shù)功能:主函數(shù)
//-----------------------------------------------------------------
void main()
{
direction=1; //設(shè)定轉(zhuǎn)動方向
R=540; //設(shè)定轉(zhuǎn)速
dR=0; //轉(zhuǎn)速補償為零
calculate_PWM_t(); //重新計算脈寬
timer_init();
}
評論