?? 新建 文本文檔.txt
字號:
用S51單片機控制驅動芯片L298程序(C語言) 有六個端口,輸入端口分別為P1.0,P1.1,P1.2,P1.3,P1.4,P1.5.
六個輸出端口分別為P0.0,P0.1,P0.2,P0.3,P2.4,P2.5.
其中P0.0,P0.2,P2.5輸出高低電平.P0.1,P0.3,P2.4輸出PWM脈沖信號.
程序要求 只要P1.0-P1.5中任一個為"1",則P0.0,P0.2輸出高電平;
當P1.2或P1.3為"1",P0.1,P0.3輸出占空比相同的PWM信號;
當P1.1為"1"時,P0.1的PWM信號的占空比大于P0.3的PWM信號的占空比;
當P1.0為"1"時,P0.1的PWM信號的占空比大于P0.3的PWM信號的占空比;
當P1.4為"1"時,P0.3的PWM信號的占空比大于P0.1的PWM信號的占空比;
當P1.5為"1"時,P0.3的PWM信號占空比大于P0.1的PWM信號占空比;
當P1.0-P1.5全為"0"時,P0.0,P0.2輸出低電平,P2.5輸出高電平,P2.4先輸出占空比為2:1的PWM脈沖信號,5秒后輸出占空比為1:2的PWM脈沖信號.
#include <AT89X52.h> sbit door_light=P2^5; // 門燈
sbit up_light=P2^6; // 上行顯示燈
sbit down_light=P2^7; // 下行顯示燈
sbit LED_D=P2^0; // 接 LED數碼管
sbit LED_C=P2^1;
sbit LED_B=P2^2;
sbit LED_A=P2^3;
unsigned int direct; // 全局變量
direct.floor.currentfloor unsigned int floor; unsigned int currentfloor; // 電機驅動函數定義
sbit MA=P1^0;
sbit MB=P1^1;
sbit MC=P1^2;
sbit MD=P1^3;
static unsigned int count; //計數
static int step_index; //步進索引數,值為0-7
static bit turn; //步進電機轉動方向
static int speedlevel; //步進電機轉速參數,數值越大速度越慢,最小值為1,速度最快
static int spcount; //步進電機轉速參數計數
unsigned int c=150; // 定時器時間常數
T=c*16+24 us
void delay(unsigned int N)
{ int i; for(i=0;i<N;i++); }
void system_init(void )
{ up_light=1; down_light=1;
door_light=1; P0=0xff; currentfloor=floor=direct=0;
step_index = 0; spcount = 0; MA=MB=MC=MD=1; TMOD = 0x11; //設定時器0和1為16位模式1
ET0 = 1; //定時器0中斷允許
TR0=0; //定時器0計數停止
TH0 = (65536-c)/256; TL0 = (65536-c)%256; turn = 1; IT0=1; //選擇INT0為脈沖觸發方式
IT1=1; //選擇INT1為脈沖觸發方式 EX0=1; //外部中斷0允許
EX1=1; //外部中斷1允許 EA=1; //系統中斷允許 speedlevel=1; }
void led(unsigned int n) { switch(n)
{ case 0:LED_D=0;LED_C=0;LED_B=0;
LED_A=1;break; case 1:LED_D=0;LED_C=0;
LED_B=1;LED_A=0;break; case 2:LED_D=0;LED_C=0;
LED_B=1;LED_A=1;break; case 3:LED_D=0;LED_C=1;
LED_B=0;LED_A=0;break; } }
void gorun() //步進電機驅動主函數
{ switch(step_index)
{ case 0: //A MA = 0; MB = 1;
MC = 1; MD = 1; break; case 1: //AB
MA = 0; MB = 0; MC = 1; MD = 1; break;
case 2: //B MA = 1; MB = 0; MC = 1; MD = 1; break;
case 3: //BC MA = 1; MB = 0; MC = 0; MD = 1; break;
case 4: //C MA = 1; MB = 1; MC = 0; MD = 1; break;
case 5: //CD MA = 1; MB = 1; MC = 0; MD = 0; break;
case 6: //D MA = 1; MB = 1; MC = 1; MD = 0; break;
case 7: //DA MA = 0; MB = 1; MC = 1; MD = 0; break; }
if(turn==0) { step_index++; if(step_index>7) step_index=0; }
if(turn==1) { step_index--; if(step_index<0) step_index=7; } }
void INT0_interrupt() interrupt 0 // 紅外線中斷 { if(direct==0) currentfloor=currentfloor;
if(direct==1) currentfloor=currentfloor+1;
if(direct==2) currentfloor=currentfloor-1;
led(currentfloor); if(direct!=0)//由while改過來的 { if(currentfloor==floor)
{ ET0=EX0=0; // 關調用電梯的中斷 TR0=0; // 定時器0計時停止,便于不調用gorun //
up_light=1; // down_light=1; door_light=0; // 門燈亮
delay(65535); delay(65535); delay(65535); door_light=1;
ET0=EX0=1; TR0=1; } // TR0 = 1; //開始計數 speedlevel = 1; } }
void timer0_int(void) interrupt 1 //定時器0中斷處理
{ TH0 = (65536-c)/256; TL0 = (65536-c)%256; count++; spcount--;
/* if(currentfloor==floor||direct==0) { TR0 = 0; // 關計數器計數,便于不調用gorun MA=MB=MC=MD=1; return; }*/
if(direct==0) { up_light=1; down_light=1; } if(direct==1)
{ turn=0; up_light=0; down_light=1; } if(direct==2) { turn=1; up_light=1; down_light=0; }
if(spcount<=0) { spcount = speedlevel; gorun(); } } void INT1_interrupt() interrupt 2 // 讀乙單片機發來的中斷
{ unsigned char direct_floor,x,y; //高四位 direct ,低四位
floor P0=0xff; direct_floor=P0; x=direct_floor&0xf0; y=direct_floor&0x0f; switch(x)
{ case 0x00:direct=0;break; case 0x10:direct=1;break; case 0x20:direct=2;break; }
switch(y) { case 0x00:floor=0;break; case 0x01:floor=1;break; case 0x02:floor=2;break; case 0x03:floor=3;break; } }
void main(void) { system_init(); direct=floor=1; TR0=1; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -