日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀]一、整體框架: (1)設計功能: ①能完成多方向行走以及其他的自定義的動作。(前進,后撤,左右轉(zhuǎn),避障); ②可自動避障; ③通過手機藍牙下令他的下一步動作。

 一、整體框架:

(1)設計功能:

①能完成多方向行走以及其他的自定義的動作。(前進,后撤,左右轉(zhuǎn),避障);

②可自動避障;

③通過手機藍牙下令他的下一步動作。

(2)功能框架:

 


 

(3)使用器材:

①STC89C52單片機、74LS04(反相器);

②藍牙串口通信模塊;

③超聲波測距模塊;

④9G舵機18個;

⑤PVC線槽若干(模具);

⑥PCB轉(zhuǎn)印板;

⑦螺絲螺母若干。

⑦keil3軟件

二、工作原理:

(1)藍牙串口通訊模塊:

藍牙串口通訊模塊接收手機藍牙軟件發(fā)送字符串信號,單片機通過串口通訊協(xié)議處理藍牙模塊接收到的信息,再根據(jù)信息的內(nèi)容來判斷機器人將進行的下一步行動。

(2)超聲波測距模塊:

超聲波模塊向某一方向發(fā)射超聲波,在發(fā)射時刻的同時開始計時(傳出低電平),超聲波在空氣中傳播,途中碰到障礙物就立即返回來,超聲波接收器收到反射波就立即停止計時(回到高電平),根據(jù)低電平的長短來計算測量距離。(超聲波在空氣中的傳播速度為340m/s,根據(jù)計時器記錄的時間t,就可以計算出發(fā)射點距障礙物的距離(s),即:s=340t/2)

(3)舵機控制:

控制電路板接受來自信號線的控制信號,控制電機轉(zhuǎn)動,電機帶動一系列齒輪組,減速后傳動至輸出舵盤。舵機的輸出軸和位置反饋電位計是相連的,舵盤轉(zhuǎn)動的同時,帶動位置反饋電位計,電位計將輸出一個電壓信號到控制電路板,進行反饋,然后控制電路板根據(jù)所在位置決定電機轉(zhuǎn)動的方向和速度,從而達到目標停止。舵機的控制信號周期為20MS的脈寬調(diào)制(PWM)信號,其中脈沖寬度從0.5-2.5MS,相對應的舵盤位置為0-180度,呈線性變化。也就是說,給他提供一定的脈寬,它的輸出軸就會保持一定對應角度上,無論外界轉(zhuǎn)矩怎么改變,直到給它提供一個另外寬度的脈沖信號,它才會改變輸出角度到新的對應位置上。

在我們的作品中,18路舵機分成2組,分別用一個內(nèi)部定時器來控制,產(chǎn)生對應舵機的PWM信號(首先定時器1生成第一個舵機的脈寬,再生成第二個舵機的,到第9個舵機為止,然后定時器2以同樣方式生成剩余的9個舵機的PWM信號,以此往復)。

三、制作過程:

(1)仿真原理圖:

 


 

(2)PCB制作:

 


 

(3)硬件搭建:

《a》肢體制作:

材料:PVC線槽,PVC板

①模型制作:(純手工割出來的)

 


 

②舵機改造:

 


 

③整體:

 


 

四、調(diào)試以及問題解決:

①結(jié)構(gòu)問題:

我們認為,整體的外形結(jié)構(gòu)是決定作品成敗的關(guān)鍵。經(jīng)過多種材料的試驗,最終我們選擇了容易裁剪、硬度基本滿足的PVC線槽來改裝拼接肢體,軀體使用更厚的塑料板。經(jīng)歷一周的純手工加工改造后,完成了整個模型的制作。

②供電問題:

由于我們使用的是9G舵機,性能較差,扭力不夠,無法支撐起我們設計的電源與穩(wěn)壓模塊,最后放棄了內(nèi)嵌的電源,使用實驗室的可調(diào)電源箱通過電線來供電,無法獨立開來也是我們的唯一遺憾。

③機器抖動問題

由于89C52只有6個內(nèi)部中斷,遠遠無法滿足18個舵機的控制,并且其他功能模塊也要使用到內(nèi)部中斷。所以我們將18路舵機分成了2組,初始時一個接一個舵機(每個舵機20ms周期)來發(fā)送PWM,但這也產(chǎn)生了發(fā)送一次18路PWM的總周期長度太大(18*20=360ms),足以產(chǎn)生被人眼所察覺的抖動。經(jīng)過反復研究,讓當前舵機的PWM信號在上一個PWM信號的低電平處開始產(chǎn)生高電平(在上一個PWM的高電平結(jié)束后)如下圖,大大縮短了18路舵機一次動作的總周期長度(經(jīng)過18路后,總周期長度為一個PWM的周期長度約20ms),使抖動無法被人眼所觀察。

代碼挺多,給出主要的舵機控制代碼,代碼看不懂沒關(guān)系,后面有解釋:

#include《reg52.h》

#include《intrins.h》

#include《dongzuo.h》

#define ucharunsigned char

#define uintunsigned int

//PWM

sbit PWM0 = P1^0;

sbit PWM1 = P1^1;

sbit PWM2 = P1^2;

sbit PWM3 = P1^3;

sbit PWM4 = P1^4;

sbit PWM5 = P1^5;

sbit PWM6 = P3^4;

sbit PWM7 = P3^5;

sbit PWM8 = P3^6;

sbit PWM9 = P3^7;

sbit PWM10 = P2^0;

sbit PWM11 = P2^1;

sbit PWM12 = P2^2;

sbit PWM13 = P2^3;

sbit PWM14 = P2^4;

sbit PWM15 = P2^5;

sbit PWM16 = P2^6;

sbit PWM17 = P2^7;

//超聲波測距

sfr T2MOD = 0XC9; //定時器2模式控制寄存器地址

sbit Trig =P3^2;

sbit Echo =P3^3;

unsigned intdistance;

uchar DZCS =0x11; //控制動作

uchar buf;

uchar sd=3;

bit flag=0; //是否發(fā)送字符

bit CSB =0; //超聲波啟動控制位

bit HZ=0; //后退后左轉(zhuǎn)控制位

uchar PWMscan =0;

uchar PWMscan1 =0;

uchar PWMval[]={//初始姿態(tài)

0xf8,0x8f,0xf7,0x05,0xf9,0x8c,/*5*/ 0xfa,0x0d,0xf8,0x0b,0xf9,0x67,/*b*/ 0xfa,0xd4,0xf7,0x94,0xf9,0xcb,/*11*/

0xfa,0xad,0xfc,0xdd,0xfb,0x58,/*17*/ 0xfa,0xe9,0xfc,0xfc,0xfb,0x39,/*1d*/ 0xfc,0x18,0xfc,0xca,0xfb,0x00/*23*/

};

void delay(uint a)

{

uchar j;

for(a;a》0;a--)

for(j=0;j《112;j++)

;

}

void task00()

{

if(PWMscan==1) //第1路PWM。

{

PWM0=1;

TH0=PWMval[0];

TL0=PWMval[1];

}

else if(PWMscan==2) //第2路PWM。

{

PWM0=0;

PWM1=1;

TH0=PWMval[2];

TL0=PWMval[3];

}

else if(PWMscan==3) //第3路PWM。

{

PWM1=0;

PWM2=1;

TH0=PWMval[4];

TL0=PWMval[5];

}

else if(PWMscan==4) //第4路PWM。

{

PWM2=0;

PWM3=1;

TH0=PWMval[6];

TL0=PWMval[7];

}

else if(PWMscan==5) //第5路PWM。

{

PWM3=0;

PWM4=1;

TH0=PWMval[8];

TL0=PWMval[9];

}

else if(PWMscan==6) //第6路PWM。

{

PWM4=0;

PWM5=1;

TH0=PWMval[10];

TL0=PWMval[11];

}

else if(PWMscan==7) //第7路PWM。

{

PWM5=0;

PWM6=1;

TH0=PWMval[12];

TL0=PWMval[13];

}

else if(PWMscan==8) //第8路PWM。

{

PWM6=0;

PWM7=1;

TH0=PWMval[14];

TL0=PWMval[15];

}

else if(PWMscan==9) //第9路PWM。

{

PWM7=0;

PWM8=1;

TH0=PWMval[16];

TL0=PWMval[17];

}

else if(PWMscan==10) //給一定低電平,將周期拉長

{

PWM8=0;

TH0=0xFF;

TL0=0xd2;

PWMscan=0;

TR0 = 0; //關(guān)定時器0,開定時器1

TR1 = 1;

}

PWMscan++;

}

void task01()

{

if(PWMscan1==1) //第10路PWM。

{

PWM9=1;

TH1=PWMval[18];

TL1=PWMval[19];

}

else if(PWMscan1==2) //第11路PWM。

{

PWM9=0;

PWM10=1;

TH1=PWMval[20];

TL1=PWMval[21];

}

else if(PWMscan1==3) //第12路PWM。

{

PWM10=0;

PWM11=1;

TH1=PWMval[22];

TL1=PWMval[23];

}

else if(PWMscan1==4) //第13路PWM。

{

PWM11=0;

PWM12=1;

TH1=PWMval[24];

TL1=PWMval[25];

}

else if(PWMscan1==5) //第14路PWM。

{

PWM12=0;

PWM13=1;

TH1=PWMval[26];

TL1=PWMval[27];

}

else if(PWMscan1==6) //第15路PWM。

{

PWM13=0;

PWM14=1;

TH1=PWMval[28];

TL1=PWMval[29];

}

else if(PWMscan1==7) //第16路PWM。

{

PWM14=0;

PWM15=1;

TH1=PWMval[30];

TL1=PWMval[31];

}

else if(PWMscan1==8) //第17路PWM。

{

PWM15=0;

PWM16=1;

TH1=PWMval[32];

TL1=PWMval[33];

}

else if(PWMscan1==9) //第18路PWM。

{

PWM16=0;

PWM17=1;

TH1=PWMval[34];

TL1=PWMval[35];

}

else if(PWMscan1==10) //給一定低電平,將周期拉長

{

PWM17=0;

TH1=0xFf;//b1 //這是一個大概的值,由于每一組的PWMval的總和(PWMval中定時器的間隔的總和就是一個周期)不一致,

//所以會導致周期不一定是20ms,但大概可以控制在20ms左右,也是因為周期的不固定,所以才需要

TL1=0xd2;//e0 //調(diào)整每一個舵機的實際的占空比。

PWMscan1=0;

TR0 = 1;//開定時器0

TR1 = 0;//關(guān)定時器1

}

PWMscan1++;

}

void TImer0()interrupt 1

{

task00();//控制前9路PWM

}

void TImer1()interrupt 3

{

task01();//控制后9路PWM

}

在實際過程中,或許是由于舵機的質(zhì)量問題,又或者是其他問題,舵機的角度控制總是難以運用原理上的公式來控制角度,都是實際操作,手動調(diào)整高電平的寬度,當達到合適的值的時候,然后再把相應的代碼記錄下來。

單片機的高電平寬度是通過定時器的兩個寄存器控制的,所以操作舵機的轉(zhuǎn)動就變成操作定時器的寄存器,再具體一點就是要得到TH、TL兩個值。(定時器高低位的差值對應高電平的寬度)

在代碼上,在控制第幾路舵機的時候,TH、TL的值已經(jīng)定死了為哪一個PWMval[?],比如第18路:

TH1=PWMval[34];

TL1=PWMval[35];

這將決定此時第18路舵機的轉(zhuǎn)動角度是多少,那么怎么控制下一次該舵機的轉(zhuǎn)動角度呢?答案很簡單,就是把PWMval[34];PWMval[35];的值修改一下就可以了,其他的舵機同樣是這個道理。所以,機器人的一個姿態(tài)就可以變?yōu)檫@樣:機器人姿態(tài)→18路舵機的角度→18個TH、TL的值→一個36個元素的數(shù)組PWMval的值。

所以,一個動作姿態(tài)就可以用這樣一個函數(shù)來確定:

void DZ(ucharPWM[])//動作

{

uchar i;

for(i=0;i《36;i++)

PWMval[i]=PWM[i];

}

明白了這個之后,就是對每一個姿態(tài)收集數(shù)據(jù)了,在制作過程,我是把TH和TL的兩個值顯示在數(shù)碼管上,然后記錄下來的。

后面又加入了藍牙控制模塊,超聲波測距,發(fā)現(xiàn)51單片機的定時器不太夠用,改成了52系列的單片機,還一個定時器即用藍牙模塊,又用超聲波測距,現(xiàn)在想來真佩服自己。給出控制代碼,大家自行研究:

//***************************中斷初始化**************************

void Init()

{

TMOD |= 0x11;//定時器0、1

ET0 = 1;//使能定時器0中斷

TR0 = 1;//開啟定時器0,定時器1中斷在定時器0開始后才打開

ET1 = 1;//使能定時器1中斷

IT1 = 0;//外部中斷1,低電平觸發(fā) (邊沿高變低)

EX1 = 1;//開外部中斷1

//定時器2用于波特率的產(chǎn)生

SCON=0x50;

PCON=0x00;

RCAP2H=0xFF;

RCAP2L=0xDC;//設置波特率為9600

T2CON=0x34;//將定時器2設置為波特率發(fā)生器(接收和發(fā)送都用TImer2) //此處包括啟動T2

ES=1; //串口中斷

EA = 1;//開總中斷

}

void TImer0()interrupt 1

{

task00();//控制前9路PWM

}

void timer1()interrupt 3

{

task01();//控制后9路PWM

}

void serial() interrupt 4

{

EA=0; //其余中斷全停

if(RI)

{

RI=0; //清除串行接受標志位

flag=1;

buf=SBUF; //從串口緩沖區(qū)取得數(shù)據(jù) (i-0x30)將ASCLL碼轉(zhuǎn)換成數(shù)字

switch(buf)

{

case 0x00: DZCS=0x00;break; //向前走

case 0x01: DZCS=0x01;break; //向后走

case 0x02: DZCS=0x02;break; //左轉(zhuǎn)

case 0x03: DZCS=0x03;break; //右轉(zhuǎn)

case 0x04: DZCS=0x04;break; //橫著左

case 0x05: DZCS=0x05;break; //橫著右

case 0x06: DZCS=0x06;break; //揮爪子

case 0x07: sd++;break; //減速,其實就是每個姿態(tài)中的延時不一樣

case 0x08: sd--;break; //加速

case 0xff: CSB=!CSB;break; //啟動關(guān)閉超聲波壁障

default:

DZCS=0x11;break; //

}

}

EA = 1; //打開總中斷

}

void start()// 超聲波測距啟動函數(shù)

{

uchar i;

Trig=1;

for(i=0;i《20;i++)

{

_nop_();

}

Trig=0;

}

void count()// 超聲波測距函數(shù)

{

unsigned int time,timeH,timeL;

timeH=TH1;

timeL=TL1;

time=timeH*256+timeL;

distance=time*1.7/100;

}

void Inter()interrupt 2//外部中斷1在次完成測距以及相應的后續(xù)操作

{

EA =0;

ET0=0; //關(guān)定時器中斷0

TH1=0;

TL1=0;

TR1 =1; //檢測到距離開啟定時器1

while(!Echo); //當echo為零時等待,中斷flag跳出等待

TR1 =0; //關(guān)閉定時器1

count(); //計算距離

if(((10《distance)&&(distance《30))||HZ) //當距離小于5cm時,變換動作哦(在中斷中變換平面感應

{

DZCS=0x02; //向左

HZ=0;

}

if(distance《10) //當距離小于10cm時,變換動作哦(在中斷中變換曲面感應

{

DZCS=0x01; //后退

HZ=1; //后退后左轉(zhuǎn)標志

}

if(distance》30) //當距離小于40cm時,變換動作哦(在中斷中變換

{

DZCS=0x00; //向前

HZ=0;

}

TR1=1;

ET0=1;

EA = 1;

}

void main()

{

Init();

while(1)

{

uchar DZCST;//,i;

if(CSB)

start();

if(DZCST!=DZCS)//動作發(fā)生改變,則回到平衡

DZ(PH1);

if(sd==0)

sd=1;

switch(DZCS)

{

case0x00:DZXQ(sd);break;

case0x01:DZXH(sd);break;

case0x02:DZXZ(sd);break;

case0x03:DZXY(sd);break;

case0x04:DZHZZ(sd);break;

case0x05:DZHZY(sd);break;

case0x06:DZZZ(sd);break;

default:

DZ(PH1);

}

DZCST=DZCS;

}

}

『本文轉(zhuǎn)載自網(wǎng)絡,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系刪除』

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

中國北京(2025年9月10日)—— 業(yè)界領先的半導體器件供應商兆易創(chuàng)新GigaDevice(股票代碼 603986)亮相于深圳國際會展中心舉辦的第26屆中國國際光電博覽會(展位號:12C12),全面展示GD25 SPI...

關(guān)鍵字: 光通信 MCU Flash

瑞典烏普薩拉,2025年9月4日 — 全球領先的嵌入式系統(tǒng)開發(fā)軟件解決方案供應商IAR宣布,瑞薩最新推出的具備量產(chǎn)條件的RH850/U2A MCAL(微控制器抽象層)軟件包,已全面支持IAR的RH850工具鏈(v2.21...

關(guān)鍵字: MCU ADAS 電動汽車

本屆年會將在上海(11月13-14日)、北京(11月19-20日)和深圳(11月27-28日)舉行,面向嵌入式設計工程師推出25門技術(shù)課程

關(guān)鍵字: 嵌入式 MCU 模擬

中國北京(2025年9月2日)—— 業(yè)界領先的半導體器件供應商兆易創(chuàng)新GigaDevice(股票代碼 603986)受邀出席2025智能汽車基礎軟件生態(tài)大會暨第四屆中國汽車芯片大會,并與國內(nèi)領先的AUTOSAR車用操作系...

關(guān)鍵字: 汽車電子 MCU 智能汽車

2025年8月26日,?Elexcon深圳國際電子展?在?深圳會展中心(福田)1號館?(展臺號:1L30)盛大舉行。作為全球電子產(chǎn)業(yè)鏈的重要盛會,展會匯聚創(chuàng)新技術(shù)與行業(yè)解決方案。米爾電子MYIR攜RZ系列核心板、開發(fā)板等...

關(guān)鍵字: 核心板 開發(fā)板 MCU

針對HMI應用所需的段碼式LCD和電容式觸控進行優(yōu)化,為電磁爐提供精準控制;支持通過雙區(qū)閃存實現(xiàn)便捷、安全的OTA

關(guān)鍵字: MCU 智能家電 電磁爐

聚焦工業(yè)4.0及能源管理應用對主控MCU的高性能需求,極海正式發(fā)布APM32F425/427系列高性能拓展型MCU,集合運算性能、ADC性能、Flash控制器性能與通信接口四大維度革新,進一步增強了EMC性能,重新定義C...

關(guān)鍵字: MCU 工業(yè)應用 極海

MarketsandMarkets預測,到2027年,全球嵌入式AI市場規(guī)模將超過200億美元,年復合增長率高達30%。這一增長背后,是對高算力、低功耗、實時性和安全性的迫切需求,以及技術(shù)碎片化與跨界融合的復雜挑戰(zhàn)。在這...

關(guān)鍵字: Renesas AI 瑞薩電子 嵌入式AI MCU MPU

全新產(chǎn)品滿足DLMS Suite2表計應用安全法規(guī),提供豐富的通信選項、電容式觸摸界面,以及支持軟件更新的雙區(qū)閃存

關(guān)鍵字: MCU 閃存 恒溫器

由于邊緣AI是指在邊緣設備上部署和運行AI模型,而不是將數(shù)據(jù)傳輸?shù)街醒敕掌鬟M行處理。這種方式具有低延遲、高響應速度、保護隱私和降低數(shù)據(jù)傳輸成本等優(yōu)勢。微控制器(MCU)作為電子設備的主控制芯片,在邊緣AI的發(fā)展中扮演著...

關(guān)鍵字: MCU AI
關(guān)閉