欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標(biāo)題:
Smart_car4紅外避障+超聲波跟隨設(shè)計(jì)源代碼
[打印本頁(yè)]
作者:
QXDBOY
時(shí)間:
2018-6-1 17:05
標(biāo)題:
Smart_car4紅外避障+超聲波跟隨設(shè)計(jì)源代碼
這是我上個(gè)月做的單片機(jī)智能小車(chē),目前可實(shí)現(xiàn)紅外避障和藍(lán)牙遙控。保證原創(chuàng),請(qǐng)多多指教。
0.png
(9.36 KB, 下載次數(shù): 31)
下載附件
2018-6-2 01:40 上傳
單片機(jī)源程序如下:
#include<reg52.h>
#include<C52_car.h>
#include <intrins.h>//包含_nop_指令的頭文件
#define MAIN_Fosc 11059200UL //宏定義主時(shí)鐘HZ
#define PCF8591_ADDR 0x90 //PCF8591地址
#define DACOUT_EN 0x40 //DAC輸出使能
typedef unsigned char uchar;
typedef unsigned int uint;
unsigned char pwm_left_val = 0;//左電機(jī)占空比值 取值范圍0-80,0最快
unsigned char pwm_right_val = 0;//右電機(jī)占空比值取值范圍0-80 ,0最快
unsigned char pwm_t = 0;//周期
unsigned char control=0X01;//車(chē)運(yùn)動(dòng)控制全局變量,默認(rèn)開(kāi)機(jī)為停車(chē)狀態(tài)
unsigned int time = 0;//傳輸時(shí)間
unsigned long S = 0;//距離
unsigned char count=0;
unsigned char SEH_count; //舵機(jī)朝向前面
#define LCD1602_DB P0 //LCD1602數(shù)據(jù)總線(xiàn)
uchar Control_mode = 0;
uchar AD_Value; //存儲(chǔ)AD轉(zhuǎn)換回的數(shù)字量
sbit LCD1602_RS = P3^5; //RS端
sbit LCD1602_RW = P3^6; //RW端
sbit LCD1602_EN = P3^4; //EN端
sbit DU = P2^6;//
sbit WE = P2^7;//數(shù)碼管位選段選用于關(guān)閉數(shù)碼管顯示
void delay(unsigned int z)//毫秒級(jí)延時(shí)
{
unsigned int x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void Delay10us(unsigned char i) //10us延時(shí)函數(shù) 啟動(dòng)超聲波模塊時(shí)使用
{
unsigned char j;
do{
j = 10;
do{
_nop_();
}while(--j);
}while(--i);
}
/*====================================
函數(shù):void Delay5us()
描述:12T 51單片機(jī)5微秒延時(shí)函數(shù)自適應(yīng)時(shí)鐘(11.0592M,12M,22.1184M)
====================================*/
void Delay5us()
{
#if MAIN_Fosc == 11059200
_nop_();
#elif MAIN_Fosc == 12000000
_nop_();
#elif MAIN_Fosc == 22118400
_nop_(); _nop_(); _nop_();
#endif
}
/*小車(chē)前進(jìn)*/
void forward()
{
left_motor_go; //左電機(jī)前進(jìn)
right_motor_go; //右電機(jī)前進(jìn)
}
/*小車(chē)左轉(zhuǎn)*/
void left_run()
{
left_motor_stops; //左電機(jī)停止
right_motor_go; //右電機(jī)前進(jìn)
}
/*小車(chē)右轉(zhuǎn)*/
void right_run()
{
right_motor_stops;//右電機(jī)停止
left_motor_go; //左電機(jī)前進(jìn)
}
/*PWM控制使能 小車(chē)后退*/
void backward()
{
left_motor_back; //左電機(jī)后退
right_motor_back; //右電機(jī)后退
}
void stop()
{
left_motor_stops; //左電機(jī)后退
right_motor_stops; //右電機(jī)后退
}
void Init(void)
{
EA = 1; //開(kāi)總中斷
PT0 = 1;
IT0 = 0; //邊沿觸發(fā)方式
IT1 = 0; //邊沿觸發(fā)方式
SCON |= 0x50; // SCON: 模式1, 8-bit UART, 使能接收
T2CON |= 0x34; //設(shè)置定時(shí)器2為串口波特率發(fā)生器并啟動(dòng)定時(shí)器2
TL2 = RCAP2L = (65536-(FOSC/32/BAUD)); //設(shè)置波特率
TH2 = RCAP2H = (65536-(FOSC/32/BAUD)) >> 8;
ES= 1; //打開(kāi)串口中斷
TMOD |= 0x01; //定時(shí)器0,工作模式1,16位定時(shí)模式
TH0 = 0;
TL0 = 0; //T0,16位定時(shí)計(jì)數(shù)用于記錄ECHO高電平時(shí)間
TR0 = 1; //啟動(dòng)定時(shí)器0
ET0 = 1; //允許定時(shí)器0中斷
TMOD |= 0x10; //定時(shí)器1,16位定時(shí)模式。
TH1 = 0xff; //配置定時(shí)器0初值,溢出時(shí)間為0.1ms
TL1 = 0xa3;
TR1 = 1; //啟動(dòng)定時(shí)器1
ET1 = 1; //允許T1中斷
}
void StartModule() //啟動(dòng)超聲波模塊
{
TX=1; //啟動(dòng)一次模塊
Delay10us(2);
TX=0;
}
/*計(jì)算超聲波所測(cè)距離并顯示*/
void Conut()
{
time=TH0*256+TL0;
TH0 = 0;
TL0 = 0;
S=(float)(time*1.085)*0.17; //算出來(lái)是MM
if(S>=7000) //超出測(cè)量范圍
{
stop();
beep = 0;
delay(1000);
beep = 1;
}
}
/*====================================
函數(shù):void SEH_count_0()
描述:舵機(jī)在左側(cè)時(shí)指令
====================================*/
void SEH_count_5()
{
StartModule(); //啟動(dòng)模塊測(cè)距
while(!RX); //當(dāng)RX(ECHO信號(hào)回響)為零時(shí)等待
TR0 = 1; //開(kāi)啟計(jì)數(shù)
while(RX) ; //當(dāng)RX為1計(jì)數(shù)并等待
TR0 = 0; //關(guān)閉計(jì)數(shù)
Conut(); //計(jì)算距離
if(S > 170 && S <850 )//設(shè)置隨動(dòng)距離(單位毫米)
{
left_run();
}
}
/*====================================
函數(shù):void SEH_count_10()
描述:舵機(jī)在中間時(shí)指令
====================================*/
void SEH_count_10()
{
StartModule(); //啟動(dòng)模塊測(cè)距
while(!RX); //當(dāng)RX(ECHO信號(hào)回響)為零時(shí)等待
TR0 = 1; //開(kāi)啟計(jì)數(shù)
while(RX) ; //當(dāng)RX為1計(jì)數(shù)并等待
TR0 = 0; //關(guān)閉計(jì)數(shù)
Conut(); //計(jì)算距離
if(S > 170 && S <850 )//設(shè)置隨動(dòng)距離(單位毫米)
{
forward();
}
}
/*====================================
函數(shù):void SEH_count_20()
描述:舵機(jī)在右側(cè)時(shí)指令
====================================*/
void SEH_count_15()
{
StartModule(); //啟動(dòng)模塊測(cè)距
while(!RX); //當(dāng)RX(ECHO信號(hào)回響)為零時(shí)等待
TR0 = 1; //開(kāi)啟計(jì)數(shù)
while(RX) ; //當(dāng)RX為1計(jì)數(shù)并等待
TR0 = 0; //關(guān)閉計(jì)數(shù)
Conut(); //計(jì)算距離
if(S > 150 && S <850 )//設(shè)置隨動(dòng)距離(單位毫米)
{
right_run();
}
}
/*====================================
函數(shù):I2C_init()
描述:I2C總線(xiàn)初始化
====================================*/
void I2C_init()
{
SDA = 1; //數(shù)據(jù)總線(xiàn)高
_nop_();
SCL = 1; //時(shí)鐘總線(xiàn)高
_nop_();
}
/*====================================
函數(shù):I2C_Start()
描述:I2C起始信號(hào)
====================================*/
void I2C_Start()
{
SCL = 1;
_nop_();
SDA = 1;
Delay5us();
SDA = 0;
Delay5us();
}
/*====================================
函數(shù):I2C_Stop()
描述:I2C停止信號(hào)
====================================*/
void I2C_Stop()
{
SDA = 0;
_nop_();
SCL = 1;
Delay5us();
SDA = 1;
Delay5us();
}
/*====================================
函數(shù):Master_ACK(bit i)
參數(shù):i 為0時(shí)發(fā)送非應(yīng)答 為1時(shí)發(fā)送應(yīng)答
描述:I2C主機(jī)發(fā)送應(yīng)答
====================================*/
void Master_ACK(bit i)
{
SCL = 0; // 拉低時(shí)鐘總線(xiàn)允許SDA數(shù)據(jù)總線(xiàn)上的數(shù)據(jù)變化
_nop_(); // 讓總線(xiàn)穩(wěn)定
if (i) //如果i = 1 那么拉低數(shù)據(jù)總線(xiàn) 表示主機(jī)應(yīng)答
{
SDA = 0;
}
else
{
SDA = 1; //發(fā)送非應(yīng)答
}
_nop_();//讓總線(xiàn)穩(wěn)定
SCL = 1;//拉高時(shí)鐘總線(xiàn) 讓從機(jī)從SDA線(xiàn)上讀走 主機(jī)的應(yīng)答信號(hào)
_nop_();
SCL = 0;//拉低時(shí)鐘總線(xiàn), 占用總線(xiàn)繼續(xù)通信
_nop_();
SDA = 1;//釋放SDA數(shù)據(jù)總線(xiàn)。
_nop_();
}
/*====================================
函數(shù):Test_ACK()
返回:0為非應(yīng)答 1為應(yīng)答
描述:I2C檢測(cè)從機(jī)應(yīng)答
====================================*/
bit Test_ACK() // 檢測(cè)從機(jī)應(yīng)答
{
SCL = 1;//時(shí)鐘總線(xiàn)為高電平期間可以讀取從機(jī)應(yīng)答信號(hào)
Delay5us();
if (SDA)
{
SCL = 0;
I2C_Stop();
return(0);
}
else
{
SCL = 0;
return(1);
}
}
/*====================================
函數(shù):I2C_send_byte(uchar byte)
參數(shù):byte 要發(fā)送的字節(jié)
描述:I2C發(fā)送一個(gè)字節(jié)
====================================*/
void I2C_send_byte(uchar byte)
{
uchar i;
for(i = 0 ; i < 8 ; i++)
{
SCL = 0;
_nop_();
if (byte & 0x80) //
{
SDA = 1;
_nop_();
}
else
{
SDA = 0;
_nop_();
}
SCL = 1;
_nop_();
byte <<= 1;
}
SCL = 0;
_nop_();
SDA = 1;
_nop_();
}
/*====================================
函數(shù):I2C_read_byte()
返回:讀取的字節(jié)
描述:I2C讀一個(gè)字節(jié)
====================================*/
uchar I2C_read_byte()
{
uchar i, dat;
SCL = 0 ;
_nop_();
SDA = 1;
_nop_();
for(i = 0 ; i < 8 ; i++)
{
SCL = 1;
_nop_();
dat <<= 1;
if (SDA)
{
dat |= 0x01;
}
_nop_();
SCL = 0;
_nop_();
}
return(dat);
}
/*讀AD數(shù)據(jù)*/
bit ADC_Read(uchar CON)
{
I2C_Start();
I2C_send_byte(PCF8591_ADDR+0);
if (!Test_ACK())
{
return(0);
}
I2C_send_byte(CON);
Master_ACK(0);
I2C_Start();
I2C_send_byte(PCF8591_ADDR+1);
if (!Test_ACK())
{
return(0);
}
AD_Value = I2C_read_byte();
Master_ACK(0);
I2C_Stop();
return(1);
}
/*=================================================
*函數(shù)名稱(chēng):Read_Busy
*函數(shù)功能:判斷1602液晶忙,并等待
=================================================*/
void Read_Busy()
{
uchar busy;
LCD1602_DB = 0xff;//復(fù)位數(shù)據(jù)總線(xiàn)
LCD1602_RS = 0; //拉低RS
LCD1602_RW = 1; //拉高RW讀
do
{
LCD1602_EN = 1;//使能EN
busy = LCD1602_DB;//讀回?cái)?shù)據(jù)
LCD1602_EN = 0; //拉低使能以便于下一次產(chǎn)生上升沿
}while(busy & 0x80); //判斷狀態(tài)字BIT7位是否為1,為1則表示忙,程序等待
}
/*=================================================
*函數(shù)名稱(chēng):LCD1602_Write_Cmd
*函數(shù)功能:寫(xiě)LCD1602命令
*調(diào)用:Read_Busy();
*輸入:cmd:要寫(xiě)的命令
=================================================*/
void LCD1602_Write_Cmd(uchar cmd)
{
Read_Busy(); //判斷忙,忙則等待
LCD1602_RS = 0;
LCD1602_RW = 0; //拉低RS、RW操作時(shí)序情況1602課件下中文使用說(shuō)明基本操作時(shí)序章節(jié)
LCD1602_DB = cmd;//寫(xiě)入命令
LCD1602_EN = 1; //拉高使能端 數(shù)據(jù)被傳輸?shù)絃CD1602內(nèi)
LCD1602_EN = 0; //拉低使能以便于下一次產(chǎn)生上升沿
}
/*=================================================
*函數(shù)名稱(chēng):LCD1602_Write_Dat
*函數(shù)功能:寫(xiě)LCD1602數(shù)據(jù)
*調(diào)用:Read_Busy();
*輸入:dat:需要寫(xiě)入的數(shù)據(jù)
=================================================*/
void LCD1602_Write_Dat(uchar dat)
{
Read_Busy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
/*=================================================
*函數(shù)名稱(chēng):LCD1602_Dis_Str
*函數(shù)功能:在指定位置顯示字符串
*調(diào)用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
*輸入:x:要顯示的橫坐標(biāo)取值0-40,y:要顯示的行坐標(biāo)取值0-1(0為第一行,1為第二行)
*str:需要顯示的字符串
=================================================*/
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
if(y) x |= 0x40;
x |= 0x80;
LCD1602_Write_Cmd(x);
while(*str != '\0')
{
LCD1602_Write_Dat(*str++);
}
}
/*=================================================
*函數(shù)名稱(chēng):Init_LCD1602
*函數(shù)功能:1602初始化
*調(diào)用: LCD1602_Write_Cmd();
=================================================*/
void Init_LCD1602()
{
LCD1602_Write_Cmd(0x38); // 設(shè)置16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
LCD1602_Write_Cmd(0x0c); //開(kāi)顯示
LCD1602_Write_Cmd(0x06); //讀寫(xiě)一字節(jié)后地址指針加1
LCD1602_Write_Cmd(0x01); //清除顯示
}
/*=================================================
*函數(shù)名稱(chēng):Dispaly_LCD1602
*函數(shù)功能:1602顯示字符
*調(diào)用: LCD1602_Write_Cmd();
=================================================*/
void Dispaly_LCD1602()
{
int LCD_CK=0;
uchar Str_1[] = {"Welcome to use"};
uchar Str_2[] = {"Pick a pattern"};
uchar Str_3[] = {"S2 -> automatic"};
uchar Str_4[] = {"S3 -> bluetooth"};
Init_LCD1602();//1602初始化
for(;;) //死循環(huán)
{
if(LCD_CK == 0)
{
LCD1602_Dis_Str(0, 0, &Str_1[0]); //顯示字符串
LCD1602_Dis_Str(0, 1, &Str_2[0]); //顯示字符串
delay(10);
}
if(LCD_CK == 20000)
{
LCD1602_Dis_Str(0, 0, &Str_3[0]); //顯示字符串
LCD1602_Dis_Str(0, 1, &Str_4[0]); //顯示字符串
delay(10);
}/**/
if(key_s2 == 0)// 實(shí)時(shí)檢測(cè)S2按鍵是否被按下
{
delay(5); //軟件消抖
if(key_s2 == 0)//再檢測(cè)S2是否被按下
{
while(!key_s2);//松手檢測(cè)
delay(50);//50毫秒延時(shí)
Control_mode = 0;
break; //退出FOR死循環(huán)
}
}
if(key_s3 == 0)// 實(shí)時(shí)檢測(cè)S3按鍵是否被按下
{
delay(5); //軟件消抖
if(key_s3 == 0)//再檢測(cè)S3是否被按下
{
while(!key_s3);//松手檢測(cè)
delay(50);//50毫秒延時(shí)
Control_mode = 1;
break; //退出FOR死循環(huán)
}
}
if(LCD_CK <= 40000) LCD_CK++;
if(LCD_CK >= 40000) LCD_CK = 0;
}
}
void main()
{
DU = 0;
WE = 0;
EN2 = EN1 =1;
SEH_count = 10;
Dispaly_LCD1602();
I2C_init();//I2C初始化
LCD1602_Write_Cmd(0x08); //關(guān)閉1602顯示
Init();//定時(shí)器、串口初始化Init();//定時(shí)器、串口初始化
beep = 0;
delay(200);//延時(shí)1秒
beep = 1;
while(1)
{
if(Control_mode == 1)
{
EX0 = 0; //關(guān)閉外部中斷1
EX1 = 0; //關(guān)閉外部中斷2
while(1)
{
if(control>0X07)//如果成立,則表示接收的命令不在運(yùn)行命令內(nèi)
{
stop(); // 停車(chē)
}
switch(control)
{
case 0X02: forward(); break;//前進(jìn)
case 0X03: backward(); break;//后退
case 0X04: left_run(); break;//左轉(zhuǎn)
case 0X05: right_run(); break;//右轉(zhuǎn)
case 0X01: stop(); break;//停車(chē)
case 0X08: beep = 0; break;//鳴笛
case 0X09: beep = 1; break;//停止鳴笛
case 0X0B: SEH_count = 10; break;//SEH_COUNT: 10:0.5+1(0.1*10T)=1.5ms->90°舵機(jī)角度
case 0X0A: Control_mode = 0;break;
}
break;
}
}
if(Control_mode == 0)
{
EX0 = 1; //打開(kāi)外部中斷1
EX1 = 1; //打開(kāi)外部中斷2
for (;;)
{
SEH_count = 12;
delay(300);
ADC_Read(0x03);//體感模塊,當(dāng)檢測(cè)到人體收輸出3.3高電平
if(AD_Value > 100) SEH_count_10();
SEH_count = 6;
delay(300);
ADC_Read(0x03);//體感模塊,當(dāng)檢測(cè)到人體收輸出3.3高電平
if(AD_Value > 100) SEH_count_5();//大于3.1V表示感應(yīng)到了人體,小車(chē)行進(jìn)
SEH_count = 12;
delay(300);
ADC_Read(0x03);//體感模塊,當(dāng)檢測(cè)到人體收輸出3.3高電平
if(AD_Value > 100) SEH_count_10();
SEH_count = 18;
delay(300);
ADC_Read(0x03);//體感模塊,當(dāng)檢測(cè)到人體收輸出3.3高電平
if(AD_Value > 150) SEH_count_15();
if(control == 0X0C)
{
Control_mode = 1;
break;
}
}
}
}
}
void int0() interrupt 0
{
EX0 = 0;
delay(10);
if(left_led2 == 0)
{
backward();
delay(500);
key_s3 = 1;
right_run();
delay(700);
forward();
delay(500);
stop();
}
EX0 = 1;
}
//定時(shí)器0中斷
void timer0() interrupt 1
{
/* pwm_t++;//周期計(jì)時(shí)加
if(pwm_t == 120)
pwm_t = EN1 = EN2 = 0;
if(pwm_left_val == pwm_t)//左電機(jī)占空比
EN1 = 1;
if(pwm_right_val == pwm_t)//右電機(jī)占空比
EN2 = 1;
*/
}
void int1() interrupt 2
{
EX1 = 0;
delay(10);
if(right_led2 == 0)
{
backward();
delay(500);
key_s3 = 1;
left_run();
delay(700);
forward();
delay(500);
stop();
}
EX1 = 1;
}
//定時(shí)器1中斷
void timer1() interrupt 3 //T1中斷用來(lái)計(jì)數(shù)器溢出
{
TR1 = 0; //關(guān)閉定時(shí)器1
TH1 = 0xff; //重裝初值0.1ms
TL1 = 0xa3;
//舵機(jī)1
if(count <= SEH_count) //控制占空比左右
{
//如果count的計(jì)數(shù)小于(5-25)也就是0.5ms-2.5ms則這段小t周期持續(xù)高電平。產(chǎn)生方波
Servo = 1;
}
else
{
Servo = 0;
}
count++;
if (count >= 200) //T = 20ms則定時(shí)器計(jì)數(shù)變量清0
{
count = 0;
}
TR1 = 1; //開(kāi)啟定時(shí)器1
}
/******************************************************************/
/* 串口中斷程序*/
/******************************************************************/
void UART_SER () interrupt 4
{
unsigned char n; //定義臨時(shí)變量
if(RI) //判斷是接收中斷產(chǎn)生
{
RI=0; //標(biāo)志位清零
n=SBUF; //讀入緩沖區(qū)的值
control=n;
/* if((n >= 51) && (n <= 150))//左電機(jī)調(diào)速0~100個(gè)檔位 手機(jī)端軟件進(jìn)行調(diào)節(jié)
pwm_left_val = 0.8-((n-50)*0.8);
if((n >= 151) && (n <= 250)) //右電機(jī)調(diào)速0~100個(gè)檔位 手機(jī)端軟件進(jìn)行調(diào)節(jié)
pwm_right_val = 0.8-((n-150)*0.8);*/
if((n >= 51) && (n <= 150))//左電機(jī)調(diào)速0~100個(gè)檔位 手機(jī)端軟件進(jìn)行調(diào)節(jié)
pwm_left_val = 1.7-((n-50)*1.7);
if((n >= 151) && (n <= 250)) //右電機(jī)調(diào)速0~100個(gè)檔位 手機(jī)端軟件進(jìn)行調(diào)節(jié)
pwm_right_val = 1.7-((n-150)*1.7);
}
}
復(fù)制代碼
所有資料51hei提供下載:
Smart_car4 紅外避障&超聲波跟隨.rar
(56.44 KB, 下載次數(shù): 25)
2018-6-1 17:04 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1