該程序是基于“4_PWM的實現(xiàn)”中的程序改編的。代碼如下:
- void Change_PWM(int duty1,int duty2,int duty3,int duty4)
- {
- SCB->AIRCR=0x05AF00;// 中斷優(yōu)先級分組 搶占:響應(yīng)=3:1
- RCC->AHB1ENR|=(1<<2);// 打開GPIOC時鐘
- GPIOC->MODER|=0x000AA000;// pc6789第二功能,推挽輸出
- GPIOC->OSPEEDR|=0x000FF000;//輸出速度為100m
- GPIOC->PUPDR|=0x00055000;//上拉
-
- GPIOC->AFR[0]|=0x22000000;//pc6789的第二功能為AF2
- GPIOC->AFR[1]|=0x00000022;
-
- RCC->APB1ENR|=(1<<1);//打開TIM3時鐘
- TIM3->PSC=83;//對84M時鐘進(jìn)行84分頻,使得計數(shù)頻率為1M
- TIM3->ARR=10000;//周期為10ms
- TIM3->EGR|=1;//產(chǎn)生一次更新時間
-
- TIM3->CCMR1|=0x6060;//PWM模式1
- TIM3->CCMR2|=0x6060;//PWM模式2
-
- TIM3->CCR1=duty1;//1路PWM
- TIM3->CCR2=duty2;//2路PWM
- TIM3->CCR3=duty3;//3路PWM
- TIM3->CCR4=duty4;//4路PWM
-
- TIM3->CCER|=0x1111;//使能比較輸出
-
- TIM3->CCMR1|=0x0808;//啟動預(yù)裝載
- TIM3->CCMR2|=0x8080;
-
- TIM3->CR1|=1;//開始計時
- }
復(fù)制代碼
4.1.4 設(shè)置電機(jī)轉(zhuǎn)向程序改程序?qū)㈦姍C(jī)驅(qū)動模塊的8個輸入端口接到了主控板的8個GPIO口,通過推挽輸出,從而控制電機(jī)的轉(zhuǎn)向,代碼如下:
- void Direction(int direction)
- {
- SysTick_Config(SystemCoreClock / 1000); //時鐘中斷設(shè)為1ms
- RCC->AHB1ENR |= 0x00000005; //使能GPIOA和GPIOD時鐘
- RCC->APB2ENR |= (1<<14); //使能syscfg時鐘
- if(direction==0)
- {
- GPIOA->MODER &= 0xffff0000; //設(shè)置PA0,1,2,3為輸出
- GPIOA->MODER |= 0x00005555;
- GPIOA->OTYPER &= 0xFFFFff00; //設(shè)置PA0,1,2,3為推挽輸出
- GPIOA->OSPEEDR &= 0xffff0000; //設(shè)置PA0,1,2,3的輸出速度為100M
- GPIOA->OSPEEDR |= 0x0000ffff;
- SYSCFG->CMPCR = 0x00000001; //使用IO補(bǔ)償單元
- GPIOA->PUPDR &= 0xffffff00; //設(shè)置PA0,1,2,3無上拉,無下拉
- GPIOA->BSRRH = 0x00ff; //復(fù)位GPIOA_BSRRH寄存器
- GPIOA->BSRRL = 0x0055;
- }
- else
- {
- GPIOA->MODER &= 0xffff0000; //設(shè)置PA0,1,2,3為輸出
- GPIOA->MODER |= 0x0000005555;
- GPIOA->OTYPER &= 0xFFFFff00; //設(shè)置PA0,1,2,3為推挽輸出
- GPIOA->OSPEEDR &= 0xffff0000; //設(shè)置PA0,1,2,3的輸出速度為100M
- GPIOA->OSPEEDR |= 0x0000ffff;
- SYSCFG->CMPCR = 0x00000001; //使用IO補(bǔ)償單元
- GPIOA->PUPDR &= 0xffffff00; //設(shè)置PA0,1,2,3無上拉,無下拉
- GPIOA->BSRRH = 0x00ff; //復(fù)位GPIOA_BSRRH寄存器
- GPIOA->BSRRL = 0x00AA;
- }
- }
復(fù)制代碼
4.2 android客戶端程序設(shè)計4.2.1 控制界面的布局控制界面主要運(yùn)用了線性布局、相對布局和表格布局。整體采用線性布局,局部采用相對布局,而控制按鈕采用了表格布局。控制界面的布局如圖4.1所示:
圖4.1 控制界面的布局
4.2.2 布局的代碼如下:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout
android:id = "@+id/container"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id= "@+id/edit_bottombar"
android:layout_alignParentBottom = "true">
<Button android:id="@+id/btn_disconnect"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft ="true"
android:text="斷開"/>
<Button android:id="@+id/btn_msg_send"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_alignParentRight ="true"
android:text="發(fā)送"/>
<EditText
android:id="@+id/MessageText"
android:layout_width="98dp"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/btn_disconnect"
android:hint="說點什么呢?"
android:textSize="15dip"
/>
</RelativeLayout>
<ListView
android:id="@+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/edit_bottombar"
android:layout_below="@id/container"
android:layout_weight="1.0"
android:divider="#ffc6c6c6"
android:scrollingCache="false"
android:visibility="visible" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:visibility="invisible" />
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:text="start"
android:width="120px" />
</TableRow>
<TableRow
android:id="@+id/tableRow2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" >
<Button
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:text="left"
android:width="120px" />
<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stop"
android:width="120px" />
<Button
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="right"
android:width="120px" />
</TableRow>
<TableRow
android:id="@+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:visibility="invisible" />
<Button
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Back" />
</TableRow>
</TableLayout>
</RelativeLayout>
</LinearLayout>
4.2.3 android客戶端的界面如圖4.2所示:圖4.2 android控制界面
4.2.4 發(fā)送按鈕的代碼sendButton= (Button)findViewById(R.id.btn_msg_send);
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
String msgText =editMsgView.getText().toString();//獲取編輯框內(nèi)的內(nèi)容
if (msgText.length()>0) {
sendMessageHandle(msgText);//發(fā)送編輯框的內(nèi)容給串口
editMsgView.setText("");//清空編輯框
editMsgView.clearFocus();
//close InputMethodManager
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editMsgView.getWindowToken(), 0);
}
else
Toast.makeText(mContext, "發(fā)送內(nèi)容不能為空!", Toast.LENGTH_SHORT).show();
}
});
4.2.5 控制按鈕的代碼以左轉(zhuǎn)按鈕為例:
sendButton= (Button)findViewById(R.id.left);
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
String msgText ="1"; // 發(fā)送左轉(zhuǎn)命令“l(fā)”
if (msgText.length()>0) {
sendMessageHandle(msgText);//發(fā)送“l(fā)”給串口
editMsgView.setText("");//清空編輯框
editMsgView.clearFocus();
//close InputMethodManager
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editMsgView.getWindowToken(), 0);
}
else
Toast.makeText(mContext, "發(fā)送內(nèi)容不能為空!", Toast.LENGTH_SHORT).show();
}
});
1. 系統(tǒng)創(chuàng)新自從有了智能手機(jī),機(jī)器人的應(yīng)用也就多了一個新的方向:手機(jī)控制機(jī)器人。2005年日本第二大電信運(yùn)營商KDDI和機(jī)械制造商IBee KK聯(lián)合推出了第一款手機(jī)控制機(jī)器人。當(dāng)然了,想要操縱這種機(jī)器人,你首先需要使用KDDI網(wǎng)絡(luò),并且用戶的手機(jī)上,本身還需要帶有藍(lán)牙功能,然后再通過KDDI提供BREW方式下載機(jī)器人的驅(qū)動程式和控制系統(tǒng)。不過這種機(jī)器人的價格卻相對高昂,預(yù)售市價約合人民幣15000元。隨著Android系統(tǒng)技術(shù)的普及,可以做個基于Android的客戶端,在小車上裝個接收藍(lán)牙信號的FBT藍(lán)牙接收模塊,然后就可以通過客戶端發(fā)送藍(lán)牙信號,來對藍(lán)牙小車進(jìn)行控制控制,其接收可達(dá)15米,完全能適應(yīng)對小車的要求。其中這個FBT藍(lán)牙接收模塊是低耗能,這樣就把更多的能量用在小車的驅(qū)動上。
小車需要很大的馬力和很好的靈活性以應(yīng)對不同的地形。這輛車的車輪使用四驅(qū)的直流電機(jī)來驅(qū)動的,用PWM波來控制小車的速度,可以很方便的更改其速度,有主控板通過推挽輸出來控制電機(jī)的翻轉(zhuǎn)以讓車子進(jìn)行后退的速度。這樣就可以勝任對小車的要求。
2. 評測與結(jié)論首先,給電源模塊上12v的電源,然后打開電機(jī)驅(qū)動模塊開關(guān),同時將主控板的供電端連接到電源管理模塊。然后,在android手機(jī)上安裝“藍(lán)牙通信”應(yīng)用程序后,打開該APP,然后選擇“允許打開藍(lán)牙”。點擊設(shè)備列表中的“開始搜索按鈕”,在設(shè)備列表中選擇藍(lán)牙模塊的名字進(jìn)行連接。
完成上述工作以后,就可以在手機(jī)上通過按下“start”、“l(fā)eft”、“stop”、“right”、“back”通過藍(lán)牙給小車發(fā)送“前進(jìn)”、“左轉(zhuǎn)”、“停止”、“右轉(zhuǎn)”、“后退”5個命令。小車可以解析命令輕松進(jìn)行前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)和停止。
附錄圖6-1 作品成果1
圖6-2 作品成果2
全部資料51hei下載地址:
硬件設(shè)計及文檔.zip
(1.87 MB, 下載次數(shù): 119)
2018-6-8 17:10 上傳
點擊文件名下載附件
軟件源代碼及文檔.rar
(639.46 KB, 下載次數(shù): 126)
2018-6-9 04:04 上傳
點擊文件名下載附件
基于stm32f4的藍(lán)牙控制小車_論文.doc
(399 KB, 下載次數(shù): 83)
2018-6-8 17:10 上傳
點擊文件名下載附件