/****************************************************************************
硬件連接
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();
}
}
|