/****************************************************************************
硬件连接
P1_6 接驱动模块ENA 使能端,输入PWM信号调节速度
P1_7 接驱动模块ENB 使能端,输入PWM信号调节速度
P3_4 P3_5 接IN1 IN2 当 P3_4=1,P3_5=0; 时左电机正转 驱动蓝色输出端OUT1 OUT2接左电机
P3_4 P3_5 接IN1 IN2 当 P3_4=0,P3_5=1; 时左电机反转
P3_6 P3_7 接IN3 IN4 当 P3_6=1,P3_7=0; 时右电机正转 驱动蓝色输出端OUT3 OUT4接右电机
P3_6 P3_7 接IN3 IN4 当 P3_6=0,P3_7=1; 时右电机反转
P1_0接四路寻迹模块接口第一路输出信号即中控板上面标记为OUT1
P1_1接四路寻迹模块接口第二路输出信号即中控板上面标记为OUT2
P1_2接四路寻迹模块接口第三路输出信号即中控板上面标记为OUT3
P1_3接四路寻迹模块接口第四路输出信号即中控板上面标记为OUT4
四路寻迹传感器有信号(白线)为0 没有信号(黑线)为1
四路寻迹传感器电源+5V GND 取自于单片机板靠近液晶调节对比度的电源输出接口
关于单片机电源:本店驱动模块内带LDO稳压芯片,当电池输入最低的电压6V时候可以输出稳定的5V
分别在针脚标+5 与GND 。这个电源可以作为单片机系统的供电电源。
****************************************************************************/
#include<AT89x51.H>
#include<intrins.h>
#define Left_moto_pwm P1_0 //接驱动模块ENA 使能端,输入PWM信号调节速度
#define Right_moto_pwm P1_1 //接驱动模块ENB
#define Left_moto_go {P3_4=0,P3_5=1;} //P3_4 P3_5 接IN1 IN2 当 P3_4=0,P3_5=1; 时左电机前进
#define Left_moto_back {P3_4=1,P3_5=0;} //P3_4 P3_5 接IN1 IN2 当 P3_4=1,P3_5=0; 时左电机后退
#define Right_moto_go {P3_6=0,P3_7=1;} //P3_6 P3_7 接IN1 IN2 当 P3_6=0,P3_7=1; 时右电机前转
#define Right_moto_back {P3_6=1,P3_7=0;} //P3_6 P3_7 接IN1 IN2 当 P3_6=1,P3_7=0; 时右电
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P0
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
#define uchar unsigned char
#define uint unsigned int
uchar display[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uchar display2[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char code ASCII[12] = {'0','1','2','3','4','5','6','7','8','9'};//字库
uchar code cdis3[ ] = {"TIME: "};
uchar code cdis4[ ] = {"Distants: cm"};
unsigned char pwm_val_left =0;//变量定义
unsigned char push_val_left =0;// 左电机占空比N/10
unsigned char pwm_val_right =0;
unsigned char push_val_right=0;// 右电机占空比N/10
bit Right_moto_stop=1;
bit Left_moto_stop =1;
unsigned int time=0;
unsigned char count1=0; //计左电机码盘脉冲值
unsigned char count2=0; //计右电机码盘脉冲值
unsigned char disbuff[5]={0}; //显示缓存
unsigned char route=0;
unsigned char route1=0;
unsigned char route2=0;
unsigned char cir=0;
unsigned char cir1=0;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
void delay1(int ms)
{
unsigned char n;
while(ms--)
{
for(n = 0; n<250; n++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
void Delay(uint num)//延时函数
{
while( --num );
}
/****************************LCD1602************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
// LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
void lcd_wcmd(uchar cmd)
{
// while(lcd_busy());
LCD_RS = 0;
// LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
Delay(10);
}
void lcd_wdat(uchar dat)
{
// while(lcd_busy());
LCD_RS = 1;
// LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
Delay(10);
}
void lcd_init()
{
LCD_RW = 0;
delay1(15);
lcd_wcmd(0x01); //清除LCD的显示内容
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay1(5);
lcd_wcmd(0x38);
delay1(5);
lcd_wcmd(0x38);
delay1(5);
lcd_wcmd(0x0c); //开显示,不显示光标
delay1(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay1(5);
}
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //数据指针=80+地址变量
}
void play()
{
uchar i;
for(i=0;i<6;i++)
{
display2[i]=display[i]+0x30;
}
/* for(j=0;j<2;j++)
{
disbuff[j]=disbuff[j]+0x80;
} */
display2[7]=display[6]/10+0x30; //时单位数据处理
display2[6]=display[6]%10+0x30;
lcd_pos(0x45);
// lcd_wdat(display2[7]); //显示时
// lcd_wdat(display2[6]);
// lcd_wdat(0x3a); //显示':'
lcd_wdat(display2[5]); //显示分
lcd_wdat(display2[4]);
lcd_wdat(0x3a); //显示':'
lcd_wdat(display2[3]); //显示秒
lcd_wdat(display2[2]);
lcd_wdat(0x3a); //显示':'
lcd_wdat(display2[1]); //显示毫秒
lcd_wdat(display2[0]);
lcd_pos(0x09);
lcd_wdat(ASCII[disbuff[3]]);
lcd_wdat(ASCII[disbuff[2]]);
// lcd_wdat(0x2E); //显示'.'
lcd_wdat(ASCII[disbuff[1]]);
lcd_wdat(ASCII[disbuff[0]]);
}
/************************************************************************/
void run(void) //前进函数
{
push_val_left =10; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
push_val_right =10; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
Left_moto_go ; //左电机前进
Right_moto_go ; //右电机前进
}
/************************************************************************/
/* PWM调制电机转速 */
/************************************************************************/
/* 左电机调速 */
/*调节push_val_left的值改变电机转速,占空比 */
void pwm_out_left_moto(void)
{
if(Left_moto_stop)
{
if(pwm_val_left<=push_val_left)
Left_moto_pwm=1;
else
Left_moto_pwm=0;
if(pwm_val_left>=10)
pwm_val_left=0;
}
else Left_moto_pwm=0;
}
/******************************************************************/
/* 右电机调速 */
void pwm_out_right_moto(void)
{
if(Right_moto_stop)
{
if(pwm_val_right<=push_val_right)
Right_moto_pwm=1;
else
Right_moto_pwm=0;
if(pwm_val_right>=10)
pwm_val_right=0;
}
else Right_moto_pwm=0;
}
/***************************************************/
///*TIMER0中断服务子函数产生PWM信号 */
/* void timer0()interrupt 2 using 0
{
TH1=0xdc; //1Ms定时 0XF8
TL1=0x00; //0X30
time++;
display[0]++; //0.01S
if(display[0]==10)
{
display[0]=0;
display[1]++; //0.1S
}
if(display[1]==10)
{
display[1]=0;
display[2]++; //秒个位
}
if(display[2]==10)
{
display[2]=0;
display[3]++; //秒十位
}
if(display[3]==6)
{
display[3]=0;
display[4]++; //分个位
}
if(display[4]==10)
{
display[4]=0;
display[5]++; //分十位
}
if(display[5]==6)
{
display[5]=0;
display[6]++; //时
}
if(display[6]==24)
{
display[6]=0;
}
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
} */
/***************************************************/
void Time0(void) interrupt 1 using 1
{
TH0=0xdc; //10ms定时 0xdc
TL0=0x00;
display[0]++; //0.01S
if(display[0]==10)
{
display[0]=0;
display[1]++; //0.1S
}
if(display[1]==10)
{
display[1]=0;
display[2]++; //秒个位
}
if(display[2]==10)
{
display[2]=0;
display[3]++; //秒十位
}
if(display[3]==6)
{
display[3]=0;
display[4]++; //分个位
}
if(display[4]==10)
{
display[4]=0;
display[5]++; //分十位
}
if(display[5]==6)
{
display[5]=0;
display[6]++; //时
}
if(display[6]==24)
{
display[6]=0;
}
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
/***********************测速**************************/
void intersvr1(void) interrupt 0 using 2
{
count1++;
if(count1>=20) //计到20归零 一圈
{
count1=0;
cir++;
route=16*cir;
if(cir>6)
{
cir= 0;
}
}
/* if(route1>9)
{
route1=0;
route2++;
} */
// disbuff[3]=route2;
disbuff[2]=route1%10;
disbuff[1]=route/10%10;
disbuff[0]route%10=; //
}
/**************************************************/
void main(void)
{
uchar m;
TMOD=0X01; //设置定时器0为工作方式1
TR0= 1; //启动定时器0
ET0= 1; //开启定时器0中断
EA = 1; //开总中断
// TR1= 1;
// ET1= 1;
EX0=1; //开启外部中断0
IT0=1; //下降沿有效
// IE0=0; //清中断标志位
//IE1=0;
lcd_init();
lcd_pos(0x40);
for(m=0;m<16;m++)
lcd_wdat(cdis3[m]);
lcd_pos(0x00); //设置显示位置为第一行
for(m=0;m<16;m++)
lcd_wdat(cdis4[m]); //显示字符
while(1) /*无限循环*/
{
run();
play();
}
}
|