#include<reg51.h>
#include<intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
unsigned char pwm_M1_val ;//M1电机占空比值 取值范围0-255,0最快
unsigned char pwm_M2_val;//M2电机占空比值 取值范围0-255 ,0最快
unsigned char pwm_M3_val;//M3电机占空比值 取值范围0-255,0最快
unsigned char pwm_M4_val;//M4电机占空比值 取值范围0-255 ,0最快
unsigned char pwm_t;//周期
sbit led_right=P1^1; // 定义右路寻迹为P1.1
sbit led_middle=P1^2; // 定义中路寻迹为P1.2
sbit led_left=P1^3; // 定义左路寻迹为P1.3
sbit PWM2A=P1^4;//定义M1电机为P1.4的I/O口,即为小车右边第一个电机
sbit PWM2B=P1^5;//定义M2电机为P1.5的I/O口,即为小车左边第一个电机
sbit PWM0B=P1^6;//定义M3电机为P1.6的I/O口,即为小车左边第二个电机
sbit PWM0A=P1^7;//定义M4电机为P1.7的I/O口,即为小车右边第二个电机
sbit SER =P2^5;//定义74hc595芯片 DS脚数据线
sbit RCK =P2^6;//定义 LATCH脚 输出存储器锁存时钟线
sbit SCK =P2^7;//定义输入时钟线
void delay(unsigned int z)//毫秒级延时
{
unsigned int x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void HC595SendData(u8 SendVal)
{
u8 i;
for(i=0;i<8;i=i++)
{
SER=SendVal&0x80;//1000 0000 1000 0000
SendVal=SendVal<<1;//0000 0000 0000 0000 每次取1位左移
SCK=0; //先将串行时钟输入端SH_CP置成低电平
_nop_();
_nop_(); //两个时钟周期
SCK=1; //数据在串行时钟输入端SH_CP的上升沿输入到移位寄存器
}
RCK=0; //锁存
_nop_();
_nop_();
RCK=1; //移位寄存器上升沿时,数据进入存储寄存器
}
void forward() //小车前进
{
PWM2A=1; //M1电机使能
PWM2B=1; //M2电机使能
PWM0B=1; //M3电机使能
PWM0A=1; //M4电机使能
HC595SendData(0x95);//1001 0101 M1,M2反转 M3,M4正转,小车前进
delay(3000) ;
}
void left_run() //小车左转
{
PWM2A=1; //M1电机使能
PWM2B=1; //M2电机使能
PWM0B=1; //M3电机使能
PWM0A=1; //M4电机使能
HC595SendData(0x95);//0000 0101 右侧电机前进,左侧电机不动
delay(3000) ;
}
void right_run() //小车右转
{
PWM2A=1; //M1电机使能
PWM2B=1; //M2电机使能
PWM0B=1; //M3电机使能
PWM0A=1; //M4电机使能
HC595SendData(0x95);//1001 0000 左侧电机前进,右侧电机不动
delay(3000) ;
}
void turn_back() //小车后退
{
PWM2A=1; //M1电机使能
PWM2B=1; //M2电机使能
PWM0B=1; //M3电机使能
PWM0A=1; //M4电机使能
HC595SendData(0x6a);//0110 1010 左侧电机前进,右侧电机后退
delay(3000) ;
}
void stop() //小车停止
{
PWM2A=0; //M1电机不使能
PWM2B=0; //M2电机不使能
PWM0B=0; //M3电机不使能
PWM0A=0; //M4电机不使能
delay(3000) ;
}
//定时器0中断
void timer0() interrupt 1
{
pwm_t++;//周期计时加
if(pwm_t == 255)
pwm_t=PWM2A=PWM2B=PWM0A=PWM0B=0;
if(pwm_M1_val == pwm_t)//M1电机占空比
PWM2A = 1;
if(pwm_M2_val == pwm_t)//M2电机占空比
PWM2B = 1;
if(pwm_M3_val == pwm_t)//M3电机占空比
PWM0B = 1;
if(pwm_M4_val == pwm_t)//M4电机占空比
PWM0A = 1;
}
void main()
{
TMOD |= 0x02;//定时器工作方式2,8位自动重装模块
TH0 = 220;
TL0 = 220;//11.0592M晶振下占空比最大比值是256,输出100HZ
TR0 = 1;//启动定时器0
ET0 = 1;//允许定时器0中断
EA = 1;//总中断允许
while(1)
{ //没有检测到黑线,小车不动
if(led_right==1&&led_middle==1&&led_left==1) //没有检测到黑线
{
stop() ;//调用小车停止函数
}
else
{
if(led_right==0&&led_middle==0&&led_left==0) //左边检测到黑线
{
forward();//前进
}
if(led_right==0&&led_middle==1&&led_left==1) //右边检测到黑线
{
right_run();//右转
}
if(led_right==1&&led_middle==1&&led_left==0) //左边检测到黑线
{
left_run();//左转
}
}
}
}
|