📄 新建 文本文档.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 + -