目录
设备:单片机(以STC89C52RC为例),HC-06 , 串口下载器
前期准备:
开发环境:
设备:单片机(以STC89C52RC为例),HC-06 , 串口下载器
IDE:AndroidStudio , keil4
工具:串口调试助手 , stc-isp
关于AndroidStudio(AS)安装的教程网上很多 不多说
keil4/keil5 大家也能找到很多教程 跳过
设备测试:
将HC-06模块与下载器模块相连接,连接电脑(杜邦线丢了先不上图)
RXD 与 TXD相连接, GND与GND 连接, UCC 与 5v 连接
安装CH340驱动 CH341SER.zip - 蓝奏云
1.按win+r 输入 devmgmt.msc 打开设备管理器
2.开启 串口 子目录 查看CH340是否正常(无感叹号)
3. 如果出错 删掉重复的端口 (COM3这样的) ,重新拔插,安装驱动
4.打开串口调试助手2.2 端口选择CH340的端口 文本形势发送 AT 若正常则返回OK
5.通过 AT指令修改值 : 特别是名称 和 波特率
上述无异常则设备正常
安卓端开发:
创建个空项目,然后做个自己喜欢的
UI界面:
最右上角有个Design Split Code 点Code 输入代码
代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@mipmap/background" />
<SeekBar
android:id="@+id/bar_left"
android:layout_width="250dp"
android:layout_height="60dp"
android:background="@mipmap/bar_background"
android:max="40"
android:progress="20"
android:progressDrawable="@android:drawable/divider_horizontal_dim_dark"
android:rotation="270"
android:thumb="@mipmap/bar_dot"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.504" />
<SeekBar
android:id="@+id/bar_right"
android:layout_width="250dp"
android:layout_height="60dp"
android:background="@mipmap/bar_background"
android:max="40"
android:progress="20"
android:progressDrawable="@android:drawable/divider_horizontal_dim_dark"
android:rotation="270"
android:thumb="@mipmap/bar_dot"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.498" />
<TableRow
android:id="@+id/tableRow"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="100dp"
android:layout_marginBottom="50dp"
android:background="#aa777777"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/bar_right"
app:layout_constraintStart_toEndOf="@+id/bar_left"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:background="#aa777777"
android:gravity="center_vertical"
android:orientation="horizontal"
android:outlineProvider="none"
android:overScrollMode="ifContentScrolls"
android:scrollbars="horizontal"
app:layout_constraintBottom_toTopOf="@+id/tableRow"
app:layout_constraintEnd_toStartOf="@+id/bar_right"
app:layout_constraintStart_toEndOf="@+id/bar_left"
app:layout_constraintTop_toTopOf="@+id/imageView"
app:layout_constraintVertical_bias="0.65999997">
<Switch
android:id="@+id/switch_hctr"
android:layout_width="85dp"
android:layout_height="wrap_content"
android:layout_weight="20"
android:text="手控"
android:textColor="#EEEEEE"
tools:ignore="TouchTargetSizeCheck,VisualLintButtonSize" />
<Switch
android:id="@+id/switch_srt"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_weight="20"
android:text="循迹"
android:textColor="#EEEEEE"
tools:ignore="TouchTargetSizeCheck,VisualLintButtonSize" />
<Switch
android:id="@+id/switch_stp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="20"
android:checked="true"
android:text="停止"
android:textColor="#EEEEEE"
tools:ignore="TouchTargetSizeCheck,VisualLintButtonSize" />
<Switch
android:id="@+id/switch_etd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="20"
android:text="没想好"
android:textColor="#EEEEEE"
tools:ignore="TouchTargetSizeCheck,VisualLintButtonSize" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bluetooth_cont"
android:layout_width="450dp"
android:layout_height="0dp"
android:layout_marginStart="-400dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ListView
android:id="@+id/bluetooth_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="50dp"
android:background="#9500BCD4"
android:paddingStart="10dp"
android:paddingTop="10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</ListView>
<ImageButton
android:id="@+id/bluetooth_btn"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/bluetooth"
tools:ignore="SpeakableTextPresentCheck" />
<ImageButton
android:id="@+id/bluetooth_connect"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="@+id/bluetooth_list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bluetooth_list"
app:layout_constraintTop_toBottomOf="@+id/bluetooth_btn"
app:layout_constraintVertical_bias="0.3"
app:srcCompat="@mipmap/connect"
tools:ignore="SpeakableTextPresentCheck" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
可以直接抄
MainActivity 代码(绑定点事件罢了 直接抄!!!!!(我是自己写的啊))
package com.alray.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private final int REQ_PERMISSION_CODE = 1;
// 蓝牙权限列表
public ArrayList<String> requestList = new ArrayList<>();
private IntentFilter foundFilter;
private Context mContext;
private Bluetooth bluetoothController;
ArrayList<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>();
private Toast mToast;
private Activity ac;
// 蓝牙状态改变广播
private BroadcastReceiver receiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
switch (state){
case BluetoothAdapter.STATE_OFF:
showToast("STATE_OFF");
break;
case BluetoothAdapter.STATE_ON:
showToast("STATE_ON");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
showToast("STATE_TURNING_OFF");
break;
case BluetoothAdapter.STATE_TURNING_ON:
showToast("STATE_TURNING_ON");
break;
default:
unregisterReceiver(this);
break;
}
}
};
//蓝牙搜索广播
private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver()
{
@SuppressLint("MissingPermission")
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
String s;
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
getPermision();
if (device.getBondState() == 12) {
s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
bluetoothController.Connect(device);
connectedDevices.add(device);
}
else if (device.getBondState() == 10){
s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n";
} else{
s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n";
}
if (!deviceName.contains(s)) {
deviceName.add(s);//将搜索到的蓝牙名称和地址添加到列表。
arrayList.add(device.getAddress());//将搜索到的蓝牙地址添加到列表。
adapter1.notifyDataSetChanged();//更新
}
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
unregisterReceiver(this);
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
}
}
};
ArrayAdapter adapter1;
//定义一个列表,存蓝牙设备的地址。
public ArrayList<String> arrayList = new ArrayList<>();
//定义一个列表,存蓝牙设备地址,用于显示。
public ArrayList<String> deviceName = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
bluetoothController = new Bluetooth();
bluetoothController.setAc(this);
// 蓝牙状态改变信息
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
// 注册广播
registerReceiver(receiver, filter);
//搜索蓝牙的广播
foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
foundFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
ac = this;
ord();
}
private void unpairDevice(BluetoothDevice device){
try {
Method m = device.getClass()
.getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void ord() {
SeekBar bar_left = (SeekBar) findViewById(R.id.bar_left);
SeekBar bar_right = (SeekBar) findViewById(R.id.bar_right);
bar_left.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
bluetoothController.sendMessageHandle(String.format("L%02d\r\n",seekBar.getProgress()));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
seekBar.setProgress(20);
}
});
bar_right.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
bluetoothController.sendMessageHandle(String.format("R%02d\r\n",seekBar.getProgress()));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
seekBar.setProgress(20);
}
});
Switch switch_hctr = (Switch) findViewById(R.id.switch_hctr);
Switch switch_srt = (Switch) findViewById(R.id.switch_srt);
Switch switch_stp = (Switch) findViewById(R.id.switch_stp);
switch_stp.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
switch_hctr.setChecked(false);
switch_srt.setChecked(false);
bluetoothController.sendMessageHandle("OP\r\n");
} else {
if (switch_hctr.isChecked() || switch_srt.isChecked())
return;
switch_stp.setChecked(true);
}
}
});
switch_srt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
switch_hctr.setChecked(false);
switch_stp.setChecked(false);
bluetoothController.sendMessageHandle("OS\r\n");
} else {
if (switch_hctr.isChecked() || switch_stp.isChecked())
return;
switch_srt.setChecked(true);
}
}
});
switch_hctr.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
switch_stp.setChecked(false);
switch_srt.setChecked(false);
bluetoothController.sendMessageHandle("OH\r\n");
} else {
if (switch_stp.isChecked() || switch_srt.isChecked())
return;
switch_hctr.setChecked(true);
}
}
});
ImageButton bluetooth_connect = (ImageButton)findViewById(R.id.bluetooth_connect);
ImageButton bluetooth_btn = (ImageButton) findViewById(R.id.bluetooth_btn);
ConstraintLayout bluetooth_cont = (ConstraintLayout) findViewById(R.id.bluetooth_cont);
ListView bluetooth_List = (ListView) findViewById(R.id.bluetooth_list);
int marginStart = ((ConstraintLayout.LayoutParams) (bluetooth_cont.getLayoutParams())).getMarginStart();
bluetooth_btn.setOnClickListener(new View.OnClickListener() {
@SuppressLint("MissingPermission")
@Override
public void onClick(View v) {
ConstraintLayout.LayoutParams lp = (ConstraintLayout.LayoutParams) (bluetooth_cont.getLayoutParams());
if (lp.getMarginStart() == 0) {
lp.setMarginStart(marginStart);
bluetoothController.cancelSearch();
}
else {
lp.setMarginStart(0);
getPermision();
bluetoothController.turnOnBlueTooth(ac,1);
// 初始化各列表
arrayList.clear();
deviceName.clear();
adapter1.notifyDataSetChanged();
getPermision();
for (BluetoothDevice device: connectedDevices) {
String s;
s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
if (deviceName.contains(s))
deviceName.remove(s);
s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已连接" + "\n";
deviceName.add(s);//将搜索到的蓝牙名称和地址添加到列表。
arrayList.add(device.getAddress());//将搜索到的蓝牙地址添加到列表。
adapter1.notifyDataSetChanged();//更新
}
registerReceiver(bluetoothReceiver, foundFilter);
// 开始搜索
bluetoothController.findDevice();
}
bluetooth_cont.setLayoutParams(lp);
}
});
bluetooth_connect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (BluetoothDevice device:connectedDevices) {
bluetoothController.Connect(device);
}
}
});
adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, deviceName);
bluetooth_List.setAdapter(adapter1);
bluetooth_List.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@SuppressLint("MissingPermission")
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CharSequence content = ((TextView) view).getText();
String con = content.toString();
String[] conArray = con.split("\n");
String rightStr = conArray[1].substring(5, conArray[1].length());
BluetoothDevice device = bluetoothController.find_device(rightStr);
getPermision();
if (device.getBondState() == 10) {
String s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";
deviceName.remove(s);
if(device.createBond()) {
s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
connectedDevices.add(device);
}
deviceName.add(s);
adapter1.notifyDataSetChanged();
} else {
String s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
if (deviceName.contains(s2)) {
unpairDevice(device);
connectedDevices.remove(device);
deviceName.remove(s2);
s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";
deviceName.add(s2);
adapter1.notifyDataSetChanged();
}
s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已连接" + "\n";
if (deviceName.contains(s2)) {
unpairDevice(device);
connectedDevices.remove(device);
deviceName.remove(s2);
s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";
deviceName.add(s2);
adapter1.notifyDataSetChanged();
}
}
}
});
}
/**
* 动态申请权限
*/
public void getPermision(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
requestList.add(Manifest.permission.BLUETOOTH_SCAN);
requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
requestList.add(Manifest.permission.BLUETOOTH);
}
if(requestList.size() != 0){
ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);
}
}
public void showToast(String text){
// 若Toast控件未初始化
if( mToast == null){
// 则初始化
mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
}
// 否则
else{
// 修改显示文本
mToast.setText(text);
}
// 显示
mToast.show();
}
}
其中的Bluetooth类为自定义类,自己新建个文件放进去
package com.alray.myapplication;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.ArrayMap;
import android.util.Log;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.UUID;
@SuppressLint("MissingPermission")
public class Bluetooth {
private static final int REQ_PERMISSION_CODE = 1;
private BluetoothAdapter mAdapter;
private BluetoothSocket bluetoothSocket;
// 延时创建Toast类,
private Toast mToast;
private BTclient bTclient = new BTclient();
private Activity ac;
private Context context;
public ArrayList<String> requestList = new ArrayList<>();
public readThread readthread = new readThread();
public Byte[] rdbuffer;
// 活动间消息传递
public BTclient mClient = new BTclient();
private class BTclient extends Thread{
private void connectDevice(BluetoothDevice device){
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
bluetoothSocket.connect();
readthread.start();
showToast("蓝牙连接成功");
}
catch (IOException e)
{
showToast("蓝牙连接失败");
}
}
private void disconnectDevice(BluetoothDevice device) {
try {
readthread.interrupt();
bluetoothSocket.close();
showToast("蓝牙断开");
} catch (Exception e) {
e.printStackTrace();
}
}
}
void Connect(BluetoothDevice device)
{
bTclient.connectDevice(device);
}
void setAc(Activity a)
{
ac = a;
}
void setCont(Context t){
context = t;
}
public void sendMessageHandle(String msg)
{
if (bluetoothSocket == null)
{
return;
}
try {
OutputStream os = bluetoothSocket.getOutputStream();
os.write(msg.getBytes()); //发送出去的值为:msg
} catch (IOException e) {
e.printStackTrace();
}
}
//读取数据
private class readThread extends Thread {
private static final String TAG = "";
public void run() {
super.run();
byte[] buffer = new byte[1024];
int bytes;
InputStream mmInStream = null;
try {
mmInStream = bluetoothSocket.getInputStream();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while (true) {
try {
// Read from the InputStream
if ((bytes = mmInStream.read(buffer)) > 0) {
byte[] buf_data = new byte[bytes];
for (int i = 0; i < bytes; i++) {
buf_data[i] = buffer[i];
}
String s = new String(buf_data);//接收的值inputstream 为 s
}
} catch (IOException e) {
try {
mmInStream.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
}
}
}
}
public Bluetooth() {
mAdapter = BluetoothAdapter.getDefaultAdapter();
}
public boolean isSupportBlueTooth() {
// 若支持蓝牙,则本地适配器不为null
if (mAdapter != null) {
return true;
}
// 否则不支持
else {
return false;
}
}
public boolean getBlueToothStatus() {
// 断言,为了避免mAdapter为null导致return出错
assert (mAdapter != null);
// 蓝牙状态
return mAdapter.isEnabled();
}
public boolean turnOnBlueTooth(Activity activity, int requestCode) {
if (!mAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(intent, requestCode);
return true;
}
return false;
}
public void turnOffBlueTooth() {
if (mAdapter.isEnabled()) {
mAdapter.disable();
}
}
public void enableVisibly(Context context) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
context.startActivity(discoverableIntent);
}
public boolean findDevice() {
assert (mAdapter != null);
if (mAdapter.isDiscovering()) {
mAdapter.cancelDiscovery();
return false;
} else {
return mAdapter.startDiscovery();
}
}
public BluetoothDevice find_device(String addr){
return mAdapter.getRemoteDevice(addr);
}
public ArrayList<BluetoothDevice> getBondedDeviceList() {
return new ArrayList<BluetoothDevice>(mAdapter.getBondedDevices());
}
public void cancelSearch() {
mAdapter.cancelDiscovery();
}
public void showToast(String text){
if( mToast == null){
mToast = Toast.makeText(ac, text, Toast.LENGTH_SHORT);
}
else{
mToast.setText(text);
}
mToast.show();
}
}
发送信息代码为 bluetoothController.sendMessageHandle
小技巧:按下ctrl+f 快速搜索(基本上适用于各种应用)
应用测试:
测试前记得给位置权限,不然会连不上
安卓真机测试(不要用模拟器,没蓝牙),先开usb调试
如果你是安卓衍生系统,简单说不是苹果不是鸿蒙,那么,恭喜你,找根线连上去,选择文件传输,特别好用,如果你是鸿蒙(同样适用于安卓),先连接,选择文件传输:
1.找到adb(安装sdk的目录/platform-tools)
2.在终端中打开
3.在终端中输入.\adb tcpip 8888
4.如果说no device啥的,重新拔插,然后迅雷不及掩耳之势在输入一遍(小知识:按上键!)
5.直到出来很像成功了的提示
6.查看你手机的IP,输入 .\adb connect (ip地址):8888 比如 192.168.1.104:8888;
7.开跑
小车开发:
串口通讯:
单片机通过Timer2 来进行串口通讯的波特率发生器
于是在初始化代码中:
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //串口方式1, 8-n-1, 允许接收.
TMOD&=0x0F; //计时器1 重置
TMOD|=0X20; //计时器1 模式2
TL1= 0xFa; //计时器1 1ms 设置
TH1 = 0xFa; //
ET1= 0; //计时器1中断关闭
TR1 = 1; //计时器1开启
ES = 1; //串口中断.
EA = 1; //开总中断
串口通讯代码:
void UART_Interrupt(void) interrupt 4
{
if(RI) //如果接收到
{
RI = 0; //手动清零接收中断标志位
*pMsg = SBUF; //接收字符
TI = 0;
if(*pMsg == 0x0A)
{
pMsg = msg;
switch(msg[0])
{
case 'O':
flag = msg[1];
break;
case 'L':
lv = (msg[1] - '0')*10 + msg[2] - '0';
break;
case 'R':
rv = (msg[1] - '0')*10 + msg[2] - '0';
break;
}
}
else
{
pMsg++;
}
}
if(TI)
TI = 0;
}
我们同时还需要一个计时器来进行PWM调速
选用计时器0
TH0= 0XFc; //1ms定时
TL0= 0X18; //
ET0 = 1; //计时器0中断允许
TR0 = 1; //计时器0开始
//EA = 1;
代码:
void timer0()interrupt 1 using 2
{
TH0= 0XFc; //1ms定时
TL0= 0X18;
time++;
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
记住 所有的函数 名字不重要 重要的是interupt n 也就是中断等级
/******************************************************************/
/* 右电机调速 */
void pwm_out_right_moto(void)
{
if(Right_moto_stop)
{
if(pwm_val_right<=push_val_right)
{
Right_moto_pwm=1;
// Right_moto_pwm1=1;
}
else
{
Right_moto_pwm=0;
// Right_moto_pwm1=0;
}
if(pwm_val_right>=20)
pwm_val_right=0;
}
else
{
Right_moto_pwm=0;
// Right_moto_pwm1=0;
}
}
/* 左电机调速 */
/*调节push_val_left的值改变电机转速,占空比 */
void pwm_out_left_moto(void)
{
if(Left_moto_stop)
{
if(pwm_val_left<=push_val_left)
{
Left_moto_pwm=1;
// Left_moto_pwm1=1;
}
else
{
Left_moto_pwm=0;
// Left_moto_pwm1=0;
}
if(pwm_val_left>=20)
pwm_val_left=0;
}
else
{
Left_moto_pwm=0;
// Left_moto_pwm1=0;
}
}
最后的,为了使用PWM调速 拔掉电机驱动模块上的ENA 和 ENB 的键帽