2017-04-18 10:54:58 qq_31546677 阅读数 2693
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6018 人正在学习 去看看 朱有鹏

1.蓝牙串口模块使用SPP-CA模块

蓝牙串口模块就是使用单片机的TX ,RX与蓝牙模块通信,单片机通过TX发送数据给蓝牙模块,然后蓝牙模块在通过蓝牙协议把数据发送出去,蓝牙模块与Android的通信方式使用spp协议。

2.蓝牙通信

蓝牙的通信需要服务端和客户端,客户端搜索蓝牙设备,链接服务端。主要是通过socket通信,相关的知识可以学习了解下socket通信。链接建立起来,通信时数据的读写是通过输入输出流的方式读写。

3.Android蓝牙架构和api说明

查看《Android系统原理及开发要点详解》和《深入理解Android网络编程》里的蓝牙相关章节,2本书里相关的章节有详细的介绍。

4.uuid

Hint: If you are connecting to a Bluetooth serial board then try using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB. However if you are connecting to an Android peer then please generate your own unique UUID.

这是Android官方文档的说明,如果是连接蓝牙串口模块使用通用的uuid 00001101-0000-1000-8000-00805F9B34FB,如果是Android手机间的通信链接,可以使用生成的uuid,客服端和服务端的uuid必须相同

5.下面展示的代码是蓝牙串口控制arduino开发板LED灯的亮灭

MainActivity代码:

package net.flyget.bluetoothhelper;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {
	private static final int REQUEST_ENABLE_BT = 0;
	private static final int REQUEST_CONNECT_DEVICE = 1;
	private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
	private List<Integer> mBuffer;
	private ListView lv;
	List<Map<String, Object>> mData = new ArrayList<Map<String, Object>>();;
	private SimpleAdapter adapter;
	private static final String TAG = "MainActivity";
	private BluetoothAdapter mBluetoothAdapter;
	private ConnectThread mConnectThread;
	public ConnectedThread mConnectedThread;
	private Button mClearBtn, mScanBtn, mSendBtn;
	private EditText mEditText;
	private String mTitle;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mTitle = "Bluetooth Debug Helper";
		setTitle(mTitle);

		mClearBtn = (Button) findViewById(R.id.clearBtn);
		mScanBtn = (Button) findViewById(R.id.scanBtn);
		mSendBtn = (Button) findViewById(R.id.sendBtn);

		mClearBtn.setOnClickListener(this);
		mScanBtn.setOnClickListener(this);
		mSendBtn.setOnClickListener(this);
		lv = (ListView) findViewById(R.id.listview);
		mEditText = (EditText) findViewById(R.id.mEditText);

		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		// If the adapter is null, then Bluetooth is not supported
		if (mBluetoothAdapter == null) {
			Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
			finish();
			return;
		}

		mBuffer = new ArrayList<Integer>();
		adapter = new SimpleAdapter(MainActivity.this, mData, R.layout.list_item, new String[] { "list" },
				new int[] { R.id.tv_item });
		lv.setAdapter(adapter);
	}

	@Override
	public void onStart() {
		super.onStart();
		// If BT is not on, request that it be enabled.
		// setupChat() will then be called during onActivityResult
		if (!mBluetoothAdapter.isEnabled()) {
			Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
			// Otherwise, setup the chat session
		}

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case REQUEST_ENABLE_BT:
			if (resultCode == Activity.RESULT_OK) {
				// Bluetooth is now enabled Launch the DeviceListActivity to see
				// devices and do scan
				Intent serverIntent = new Intent(this, DeviceListActivity.class);
				startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
			} else {
				// User did not enable Bluetooth or an error occured
				Log.d(TAG, "BT not enabled");
				Toast.makeText(this, "BT not enabled", Toast.LENGTH_SHORT).show();
				return;
			}
			break;
		case REQUEST_CONNECT_DEVICE:
			if (resultCode != Activity.RESULT_OK) {
				return;
			} else {
				String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
				// Get the BLuetoothDevice object
				BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
				// Attempt to connect to the device
				connect(device);
			}
			break;
		}
	}

	public void connect(BluetoothDevice device) {
		Log.d(TAG, "connect to: " + device);
		// Start the thread to connect with the given device
		mConnectThread = new ConnectThread(device);
		mConnectThread.start();
	}

	/**
	 * This thread runs while attempting to make an outgoing connection with a
	 * device. It runs straight through; the connection either succeeds or
	 * fails.
	 */
	private class ConnectThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final BluetoothDevice mmDevice;

		public ConnectThread(BluetoothDevice device) {
			mmDevice = device;
			BluetoothSocket tmp = null;

			// Get a BluetoothSocket for a connection with the
			// given BluetoothDevice
			try {
				tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID));
			} catch (IOException e) {
				Log.e(TAG, "create() failed", e);
			}
			mmSocket = tmp;
		}

		public void run() {
			Log.i(TAG, "BEGIN mConnectThread");
			setName("ConnectThread");

			// Always cancel discovery because it will slow down a connection
			mBluetoothAdapter.cancelDiscovery();

			// Make a connection to the BluetoothSocket
			try {
				// This is a blocking call and will only return on a
				// successful connection or an exception
				mmSocket.connect();
			} catch (IOException e) {

				Log.e(TAG, "unable to connect() socket", e);
				// Close the socket
				try {
					mmSocket.close();
				} catch (IOException e2) {
					Log.e(TAG, "unable to close() socket during connection failure", e2);
				}
				return;
			}

			mConnectThread = null;

			// Start the connected thread
			// Start the thread to manage the connection and perform
			// transmissions
			mConnectedThread = new ConnectedThread(mmSocket);
			mConnectedThread.start();

		}

		public void cancel() {
			try {
				mmSocket.close();
			} catch (IOException e) {
				Log.e(TAG, "close() of connect socket failed", e);
			}
		}
	}

	/**
	 * This thread runs during a connection with a remote device. It handles all
	 * incoming and outgoing transmissions.
	 */
	private class ConnectedThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final InputStream mmInStream;
		private final OutputStream mmOutStream;

		public ConnectedThread(BluetoothSocket socket) {
			Log.d(TAG, "create ConnectedThread");
			mmSocket = socket;
			InputStream tmpIn = null;
			OutputStream tmpOut = null;

			// Get the BluetoothSocket input and output streams
			try {
				tmpIn = socket.getInputStream();
				tmpOut = socket.getOutputStream();
			} catch (IOException e) {
				Log.e(TAG, "temp sockets not created", e);
			}

			mmInStream = tmpIn;
			mmOutStream = tmpOut;
		}

		public void run() {
			Log.i(TAG, "BEGIN mConnectedThread");
			byte[] buffer = new byte[256];
			int bytes;

			// Keep listening to the InputStream while connected
			while (true) {
				try {
					// Read from the InputStream
					bytes = mmInStream.read(buffer);
					synchronized (mBuffer) {
						for (int i = 0; i < bytes; i++) {
							mBuffer.add(buffer[i] & 0xFF);
						}
					}
					// mHandler.sendEmptyMessage(MSG_NEW_DATA);
				} catch (IOException e) {
					Log.e(TAG, "disconnected", e);
					break;
				}
			}
		}

		/**
		 * Write to the connected OutStream.
		 * 
		 * @param buffer
		 *            The bytes to write
		 */
		public void write(byte[] buffer) {
			try {
				mmOutStream.write(buffer);
			} catch (IOException e) {
				Log.e(TAG, "Exception during write", e);
			}
		}

		public void cancel() {
			try {
				mmSocket.close();
			} catch (IOException e) {
				Log.e(TAG, "close() of connect socket failed", e);
			}
		}
	}

	private boolean isBackCliecked = false;

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			if (isBackCliecked) {
				this.finish();
			} else {
				isBackCliecked = true;
				Toast t = Toast.makeText(this, "Press \'Back\' again to exit.", Toast.LENGTH_LONG);
				t.setGravity(Gravity.CENTER, 0, 0);
				t.show();
			}
		}
		return true;
	}

	@Override
	public void onClick(View v) {
		isBackCliecked = false;
		if (v == mClearBtn) {
			mBuffer.clear();
			mData.clear();
			adapter.notifyDataSetChanged();
		} else if (v == mScanBtn) {
			if (mConnectThread != null) {
				mConnectThread.cancel();
				mConnectThread = null;
			}
			// if(mConnectedThread != null) {mConnectedThread.cancel();
			// mConnectedThread = null;}
			Intent serverIntent = new Intent(this, DeviceListActivity.class);
			startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
		} else if (v == mSendBtn) {
			String input = mEditText.getText().toString().trim();
			if (input != null && !"".equals(input)) {

				Map<String, Object> item = new HashMap<String, Object>();
				item.put("list", input);
				mData.add(item);

				adapter = new SimpleAdapter(MainActivity.this, mData, R.layout.list_item, new String[] { "list" },
						new int[] { R.id.tv_item });
				lv.setAdapter(adapter);
				try {
					mConnectedThread.write(input.getBytes());
				} catch (Exception e) {
				}
				mEditText.setText("");
			}
		}
	}

	@Override
	protected void onDestroy() {
		if (mConnectThread != null) {
			mConnectThread.cancel();
			mConnectThread = null;
		}
		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}
		super.onDestroy();
	}
}

蓝牙搜索代码:

package net.flyget.bluetoothhelper;

import java.util.Set;

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.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class DeviceListActivity extends Activity {  
    // Debugging  
    private static final String TAG = "DeviceListActivity";  
    private static final boolean D = true;  
  
    // Return Intent extra  
    public static String EXTRA_DEVICE_ADDRESS = "device_address";  
  
    // Member fields  
    private BluetoothAdapter mBtAdapter;  
    private ArrayAdapter<String> mPairedDevicesArrayAdapter;  
    private ArrayAdapter<String> mNewDevicesArrayAdapter;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
  
        // Setup the window  
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  
        setContentView(R.layout.device_list);  
  
        // Set result CANCELED incase the user backs out  
        setResult(Activity.RESULT_CANCELED);  
  
        Log.d(TAG, "onCreate");
        
        // Initialize the button to perform device discovery  
        Button scanButton = (Button) findViewById(R.id.button_scan);  
        scanButton.setOnClickListener(new OnClickListener() {  
            public void onClick(View v) {  
                doDiscovery();  
                v.setVisibility(View.GONE);  
            }  
        });  
  
        // Initialize array adapters. One for already paired devices and  
        // one for newly discovered devices  
        mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);  
        mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);  
  
        // Find and set up the ListView for paired devices  
        ListView pairedListView = (ListView) findViewById(R.id.paired_devices);  
        pairedListView.setAdapter(mPairedDevicesArrayAdapter);  
        pairedListView.setOnItemClickListener(mDeviceClickListener);  
  
        // Find and set up the ListView for newly discovered devices  
        ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);  
        newDevicesListView.setAdapter(mNewDevicesArrayAdapter);  
        newDevicesListView.setOnItemClickListener(mDeviceClickListener);  
  
        // Register for broadcasts when a device is discovered  
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);  
        this.registerReceiver(mReceiver, filter);  
  
        // Register for broadcasts when discovery has finished  
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);  
        this.registerReceiver(mReceiver, filter);  
  
        // Get the local Bluetooth adapter  
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();  
  
        // Get a set of currently paired devices  
        Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();  
  
        // If there are paired devices, add each one to the ArrayAdapter  
        if (pairedDevices.size() > 0) {  
            findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);  
            for (BluetoothDevice device : pairedDevices) {  
                mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());  
            }  
        } else {  
            String noDevices = getResources().getText(R.string.none_paired).toString();  
            mPairedDevicesArrayAdapter.add(noDevices);  
        }  
    }  
  
    @Override  
    protected void onDestroy() {  
        super.onDestroy();  
  
        // Make sure we're not doing discovery anymore  
        if (mBtAdapter != null) {  
            mBtAdapter.cancelDiscovery();  
        }  
  
        // Unregister broadcast listeners  
        this.unregisterReceiver(mReceiver);  
    }  
  
    /** 
     * Start device discover with the BluetoothAdapter 
     */  
    private void doDiscovery() {  
        if (D) Log.d(TAG, "doDiscovery()");  
  
        // Indicate scanning in the title  
        setProgressBarIndeterminateVisibility(true);  
        setTitle(R.string.scanning);  
  
        // Turn on sub-title for new devices  
        findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);  
  
        // If we're already discovering, stop it  
        if (mBtAdapter.isDiscovering()) {  
            mBtAdapter.cancelDiscovery();  
        }  
  
        // Request discover from BluetoothAdapter  
        mBtAdapter.startDiscovery();  
    }  
  
    // The on-click listener for all devices in the ListViews  
    private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {  
        public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {  
            // Cancel discovery because it's costly and we're about to connect  
            mBtAdapter.cancelDiscovery();  
  
            // Get the device MAC address, which is the last 17 chars in the View  
            String info = ((TextView) v).getText().toString();  
            String address = info.substring(info.length() - 17);  
  
            // Create the result Intent and include the MAC address  
            Intent intent = new Intent();  
            intent.putExtra(EXTRA_DEVICE_ADDRESS, address);  
  
            // Set result and finish this Activity  
            setResult(Activity.RESULT_OK, intent);  
            finish();  
        }  
    };  
  
    // The BroadcastReceiver that listens for discovered devices and  
    // changes the title when discovery is finished  
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {  
        @Override  
        public void onReceive(Context context, Intent intent) {  
            String action = intent.getAction();  
  
            // When discovery finds a device  
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {  
                // Get the BluetoothDevice object from the Intent  
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  
                // If it's already paired, skip it, because it's been listed already  
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {  
                    mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());  
                }  
            // When discovery is finished, change the Activity title  
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {  
                setProgressBarIndeterminateVisibility(false);  
                setTitle(R.string.select_device);  
                if (mNewDevicesArrayAdapter.getCount() == 0) {  
                    String noDevices = getResources().getText(R.string.none_found).toString();  
                    mNewDevicesArrayAdapter.add(noDevices);  
                }  
            }  
        }  
    };  
  
}  
arduino:LED灯代码:

char val;
int ledpin=13;
void setup()
{
  Serial.begin(9600);
  pinMode(ledpin,OUTPUT);
}
 
void loop()
{
  val=Serial.read();
  if(val=='o')
  {
    digitalWrite(ledpin,HIGH);
    Serial.println("LED ON!");
  }else if(val=='f'){
  digitalWrite(ledpin,LOW);
Serial.println("LED OFF!");
  }
}
下面是效果图:


6 文章代码中有问题欢迎大家留言指出,如有不对的地方后续继续更新

7 代码下载地址:http://download.csdn.net/detail/qq_31546677/9817466


2015-05-14 17:37:05 cwcwj3069 阅读数 44961
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6018 人正在学习 去看看 朱有鹏
由于项目的需要的Android与蓝牙模块通信,发了时间学习了下,实现了Android的与蓝牙模块的通信

1.蓝牙串口模块使用SPP-CA模块

蓝牙串口模块就是使用单片机的TX,RX与蓝牙模块通信,单片机通过TX发送数据给蓝牙模块,然后蓝牙模块在通过蓝牙协议把数据发送出去,蓝牙模块与Android的通信方式使用spp协议。

2.蓝牙通信

蓝牙的通信需要服务端和客户端,客户端搜索蓝牙设备,链接服务端。主要是通过插座通信,相关的知识可以学习了解下插座通信。链接建立起来,通信时数据的读写是通过输入输出流的方式读写。

3.Android蓝牙架构和API的说明

查看“机器人系统原理及开发要点详解”和“深入理解的Android网络编程”里的蓝牙相关章节,2本书里相关的章节有详细的介绍。

4.uuid

提示:如果要连接到蓝牙串行板,请尝试使用着名的SPP UUID 00001101-0000-1000-8000-00805F9B34FB。但是如果您连接到Android对等体,那么请生成您自己的唯一UUID。

这是Android官方文档的说明,如果是连接蓝牙串口模块使用通用的uuid 00001101-0000-1000-8000-00805F9B34FB,如果是Android手机间的通信链接,可以使用生成的uuid,客服端和服务端的uuid必须相同,下面通过蓝牙串口助手读取回来的UUID,下面是我的蓝牙串口模块的UUID。

下面是读取手机的蓝牙的UUID,可以看到比较多的UUID,有比较多的服务。

另外下面是其他蓝牙设备的UUID,应该是蓝牙4.0的。

代码部分还是比较简单的,下面是Android的蓝牙链接的主要部分代码,也是参考网上的。

包gjz.bluetooth;

导入gjz.bluetooth.R;
导入gjz.bluetooth.Bluetooth.ServerOrCilent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.UUID;
导入android.app.Activity;
导入android.bluetooth.BluetoothAdapter;
导入android.bluetooth.BluetoothDevice;
导入android.bluetooth.BluetoothServerSocket;
导入android.bluetooth.BluetoothSocket;
导入android.content.Context;
导入android.os.Bundle;
导入android.os.Handler;
导入android.os.Message;
导入android.util.Log;
导入android.view.View;
导入android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
导入android.widget.AdapterView;
导入android.widget.Button;
导入android.widget.EditText;
导入android.widget.ListView;
导入android.widget.Toast;
导入android.widget.AdapterView.OnItemClickListener;

public class chatActivity extends Activity implements OnItemClickListener,OnClickListener {
    / **当活动首次创建时调用。* /
 
 private ListView mListView;
 private ArrayList <deviceListItem>列表;
 私人按钮sendButton;
 私人按钮disconnectButton;
 私人EditText editMsgView;
 deviceListAdapter mAdapter;
 上下文mContext;
 
 / *一些常量,代表服务器的名称* /
 public static final String PROTOCOL_SCHEME_L2CAP =“btl2cap”;
 public static final String PROTOCOL_SCHEME_RFCOMM =“btspp”;
 public static final String PROTOCOL_SCHEME_BT_OBEX =“btgoep”;
 public static final String PROTOCOL_SCHEME_TCP_OBEX =“tcpobex”;
 
 private BluetoothServerSocket mserverSocket = null;
 private ServerThread startServerThread = null;
 private clientThread clientConnectThread = null;
 private BluetoothSocket socket = null;
 private BluetoothDevice device = null;
 private readThread mreadThread = null ;; 
 private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.chat);
        mContext = this
        在里面();
    }
   
 private void init(){    
  list = new ArrayList <deviceListItem>();
  mAdapter = new deviceListAdapter(this,list);
  mListView =(ListView)findViewById(R.id.list);
  mListView.setAdapter(mAdapter);
  mListView.setOnItemClickListener(本);
  mListView.setFastScrollEnabled(真);
  editMsgView =(EditText)findViewById(R.id.MessageText); 
  editMsgView.clearFocus();
  
  sendButton =(Button)findViewById(R.id.btn_msg_send);
  sendButton.setOnClickListener(new OnClickListener(){
   @ Override
   public void onClick(View arg0){
    // TODO自动生成的方法存根
    String msgText = editMsgView.getText()。toString();
    if(msgText.length()> 0) {
     sendMessageHandle(msgText); 
     editMsgView.setText(“”);
     editMsgView.clearFocus();
     //关闭InputMethodManager
     InputMethodManager imm =(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
     imm.hideSoftInputFromWindow(editMsgView.getWindowToken(),0);
    } else
    Toast.makeText(mContext,“发送内容不能为空!”,Toast.LENGTH_SHORT).show();
   }
  });
  
  disconnectButton =(Button)findViewById(R.id.btn_disconnect);
  disconnectButton.setOnClickListener(new OnClickListener(){
   @ Override
   public void onClick(View arg0){
    // TODO自动生成的方法存根
          if(Bluetooth.serviceOrCilent == ServerOrCilent.CILENT)
    {
           shutdownClient();
    }
    else if(Bluetooth.serviceOrCilent == ServerOrCilent.SERVICE)
    {
     shutdownServer();
    }
    Bluetooth.isOpen = false;
    Bluetooth.serviceOrCilent = ServerOrCilent.NONE;
    Toast.makeText(mContext,“已断开连接!”,Toast.LENGTH_SHORT).show();
   }
  });  
 }   

    private Handler LinkDetectedHandler = new Handler(){
        @
        Override public void handleMessage(Message msg){
         //Toast.makeText(mContext,(String)msg.obj,Toast.LENGTH_SHORT).show();
         if(msg.what == 1)
         {
          list.add(new deviceListItem((String)msg.obj,true));
         }
         else
         {
          list.add(new deviceListItem((String)msg.obj,false));
         }
   mAdapter.notifyDataSetChanged();
   mListView.setSelection(list.size() - 1);
        }
       
    };   
   
    @Override
    public synchronized void onPause(){
        super.onPause();
    }
    @Override
    public synchronized void onResume(){
        super.onResume();
        if(Bluetooth.isOpen)
        {
         Toast.makeText(mContext,“连接已经打开,可以通信,如果要再建立连接,请先断开!”,Toast.LENGTH_SHORT).show();
         返回;
        }
        if(Bluetooth.serviceOrCilent == ServerOrCilent.CILENT)
        {
   String address = Bluetooth.BlueToothAddress;
   if(!address.equals(“null”))
   {
    device = mBluetoothAdapter.getRemoteDevice(address); 
    clientConnectThread = new clientThread();
    clientConnectThread.start();
    Bluetooth.isOpen = true;
   }
   else
   {
    Toast.makeText(mContext,“address is null!”,Toast.LENGTH_SHORT).show();
   }
        }
        else if(Bluetooth.serviceOrCilent == ServerOrCilent.SERVICE)
        {                
         startServerThread = new ServerThread();
         startServerThread.start();
         Bluetooth.isOpen = true;
        }
    }
 //开启客户端
 私有类clientThread extends Thread {   
  public void run(){
   try {
    //创建一个Socket连接:只需要服务器在注册时的UUID号
    // socket = device.createRfcommSocketToServiceRecord(BluetoothProtocols.OBEX_OBJECT_PUSH_PROTOCOL_UUID);
    socket = device.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));
    //连接
    消息msg2 = new Message();
    msg2.obj =“请稍候,正在连接服务器:”+ Bluetooth.BlueToothAddress;
    msg2.what = 0;
    LinkDetectedHandler.sendMessage(MSG2);
    
    socket.connect();
    
    消息msg = new Message();
    msg.obj =“已经连接上服务端!可以发送信息”。
    msg.what = 0;
    LinkDetectedHandler.sendMessage(MSG);
    //启动接受数据
    mreadThread = new readThread();
    mreadThread.start();
   }
   catch(IOException e)
   {
    Log.e(“connect”,“”,e);
    消息msg = new Message();
    msg.obj =“连接服务端异常!断开连接重新试一试”。
    msg.what = 0;
    LinkDetectedHandler.sendMessage(MSG);
   }
  }
 };

 //开启服务器
 私有类ServerThread extends Thread {
  public void run(){
     
   try {
    / *创建一个蓝牙服务器
     *参数分别:服务器名称,UUID * / 
    mserverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
      UUID.fromString(“00001101-0000 -1000-8000-00805F9B34FB“));  
    
    Log.d(“server”,“wait cilent connect ...”);
    
    消息msg = new Message();
    msg.obj =“请稍候,正在等待客户端的连接...”;
    msg.what = 0;
    LinkDetectedHandler.sendMessage(MSG);
    
    / *接受客户端的连接请求* /
    socket = mserverSocket.accept();
    Log.d(“server”,“accept success!”);
    
    消息msg2 = new Message();
    String info =“客户端已经连接上!可以发送信息”。
    msg2.obj = info;
    msg.what = 0;
    LinkDetectedHandler.sendMessage(MSG2);
    //启动接受数据
    mreadThread = new readThread();
    mreadThread.start();
   } catch(IOException e){
    // TODO自动生成的catch块
    e.printStackTrace();
   }
  }
 };

 / *停止服务器* /
 private void shutdownServer(){
  new Thread(){
   public void run(){
    if(startServerThread!= null)
    {
     startServerThread.interrupt();
     startServerThread = null;
    }
    if(mreadThread!= null)
    {
     mreadThread.interrupt();
     mreadThread = null;
    }    
    try {     
     if(socket!= null)
     {
      socket.close();
      socket = null;
     }
     if(mserverSocket!= null)
     {
      mserverSocket.close(); / *关闭服务器* /
      mserverSocket = null;
     }
    } catch(IOException e){
     Log.e(“server”,“mserverSocket.close()”,e);
    }
   };
  }。开始();
 }
 / *停止客户端连接* /
 private void shutdownClient(){
  new Thread(){
   public void run(){
    if(clientConnectThread!= null)
    {
     clientConnectThread.interrupt();
     clientConnectThread = null;
    }
    if(mreadThread!= null)
    {
     mreadThread.interrupt();
     mreadThread = null;
    }
    if(socket!= null){
     try {
      socket.close();
     } catch(IOException e){
      // TODO自动生成的catch块
      e.printStackTrace();
     }
     socket = null;
    }
   };
  }。开始();
 }
 //发送数据
 private void sendMessageHandle(String msg)
 {  
  if(socket == null)
  {
   Toast.makeText(mContext,“没有连接”,Toast.LENGTH_SHORT).show();
   返回;
  }
  try {    
   OutputStream os = socket.getOutputStream();
   os.write(msg.getBytes());
  } catch(IOException e){
   // TODO自动生成的catch块
   e.printStackTrace();
  }   
  list.add(new deviceListItem(msg,false));
  mAdapter.notifyDataSetChanged();
  mListView.setSelection(list.size() - 1);
 }
 //读取数据
    private class readThread extends Thread {
        public void run(){
         
            byte [] buffer = new byte [1024];
            int字节;
            InputStream mmInStream = null;
           
   尝试{
    mmInStream = socket.getInputStream();
   } catch(IOException e1){
    // TODO自动生成的catch块
    e1.printStackTrace();
   } 
            while(true){
                try {
                    //从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 =新字符串(buf_data);
      消息msg = new Message();
      msg.obj = s;
      msg.what = 1;
      LinkDetectedHandler.sendMessage(MSG);
                    }
                } catch(IOException e){
                 try {
      mmInStream.close();
     } catch(IOException e1){
      // TODO自动生成的catch块
      e1.printStackTrace();
     }
                    休息
                }
            }
        }
    }
    @Override
    protected void onDestroy(){
        super.onDestroy();

        if(Bluetooth.serviceOrCilent == ServerOrCilent.CILENT)
  {
         shutdownClient();
  }
  else if(Bluetooth.serviceOrCilent == ServerOrCilent.SERVICE)
  {
   shutdownServer();
  }
        Bluetooth.isOpen = false;
  Bluetooth.serviceOrCilent = ServerOrCilent.NONE;
    }
 public class SiriListItem {
  String message;
  boolean isSiri;

  public SiriListItem(String msg,boolean siri){
   message = msg;
   isSiri = siri
  }
 }
 @覆盖
 公共无效onItemClick(适配器视图<?>为arg0,查看ARG1,INT ARG2,长ARG3){
  // TODO自动生成方法存根
 }
 @覆盖
 公共无效的onClick(查看为arg0){
  // TODO自动生成方法stub
 } 
 public class deviceListItem {
  String message;
  boolean isSiri;

  public deviceListItem(String msg,boolean siri){
   message = msg;
   isSiri = siri
  }
 }
}

下面是实现的效果。

1.Android手机通信

一台手机作为服务端,等待客服端链接。

另一台手机作为客户端,链接服务端,链接成功,发送数据

2.Android和蓝牙模块的通信

蓝牙模块作为服务器端,安卓手机作为客户端,链接蓝牙模块。

蓝牙模块通过串口线链接PC,通过串口工具接收Android手机端发送数据,Android手机端链接成功信息连接<< A0:E4:53:18:BB:42 CONNETED,链接成功发送信息hellokitty mina123456789,Android链接断开信息DISC:SUCCESS + READY + PAIRABLE

 

看到不少朋友需要源码:找了电脑上源码

下面是源码下载地址:

http://download.csdn.net/detail/cwcwj3069/9876795


2019-12-02 20:48:41 tyfwin 阅读数 124
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6018 人正在学习 去看看 朱有鹏

51单片机AD转换、串口蓝牙通讯、labview上位机显示

功能:单片机模拟数字转化,将数字信号通过蓝牙或者串口传输给电脑,电脑上labview显示出一个图表。

我这里实际使用是探测光信号强弱的:

 光信号——>光电探测器——>单片机电压转化为数字信号(AD转化)——>单片机通过串口发送出——>labview接收显示

 

单片机采用非常简单,别人常说它垃圾,可能确实有点垃圾,但是我却很喜欢的stc12c5a60s2,自带AD转化,有2个串口美滋滋,引脚图如下:

我使用P1.1口作为模拟信号输入,P1.3作为串口把数据实时传输出去。

voltagetemp_int=(int)(voltagetemp*1000);
voltagetemp_a = voltagetemp_int /100;
voltagetemp_b = voltagetemp_int %100;
UartSendChar('l');
UartSendChar('m');
UartSendChar(voltagetemp_a);
UartSendChar(voltagetemp_b);
UartSendChar('n');
UartSendChar('o');

根据上面代码,可以知道,传出去的数据,自己为了弄一个校验识别,先发送字符l和m,再发送真实数据,再发送字符n和o表示这一次数据发送结束。模拟信号电压真实值在0-5v之间,这里为了精度高一点显示,先乘以1000,再把高2位和低2位分别取出来,分别发送出去。

 

还是以前本科时候写的主要代码C语言,拿过来改改用,或许不是很规范。问题很大。懒得改了。

完事之后文件夹如下。

 

主函数代码:ceshi.c


#include <12c5a60s2.h>

#include "intrins.h"

#include <stc12delay.h>

#include <ADchange.h>

#include  <math.h>

#include  <uart.h>

int light=0;

uint scan_num=0;

float voltagetemp=0;

int  voltagetemp_int=0;

int  voltagetemp_a=0;

int  voltagetemp_b=0;

int t_int=0;

void main()

{

UartInit();

AD_init();

    while(1)

   {

scan_num++;

 if(scan_num>30)

 {

    scan_num=0;

AD_get(1);

light=initvoltage1;delay(1);

    voltagetemp=light/1024.0*5;

    voltagetemp_int=(int)(voltagetemp*1000);

    voltagetemp_a = voltagetemp_int /100;

voltagetemp_b = voltagetemp_int %100;

// UartSendChar(voltagetemp_int);

    UartSendChar('l');

UartSendChar('m');

UartSendChar(voltagetemp_a);

UartSendChar(voltagetemp_b);

UartSendChar('n');

UartSendChar('o');

 }

}

}

————

ADchange.h内容如下:

idata uint initvoltage1;

void AD_init()

{

P1ASF=0x03;  //P1  0 1 口作为模拟功能AD使用

ADC_RES=0;   //清零转换结果寄存器高8位

ADC_RESL=0; //清零转换结果寄存器低2位

ADC_CONTR=0x80;//开启AD电源  

delay(1);   //等待1ms,让AD电源稳定

}



void AD_get(char channel)  //我这里只能取0 和 1 通道

{  

ADC_CONTR=0x88|channel;    //开启AD转换1000 1000 自定通道 即POWER SPEED1 SPEED0 ADC_FLAG  ADC_START CHS2 CHS1 CHS0

_nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器

while(!(ADC_CONTR&0x10));    //等待转换完成

ADC_CONTR&=0xe7;      //关闭AD转换,ADC_FLAG位由软件清0

initvoltage1=ADC_RES*4+ADC_RESL;

//voltagetemp=initvoltage1/1024.0*5;

//FtoS(voltagetemp);

//return str;   //返回AD转换完成的10位数据(16进制)

}

 

————

stc12delay.h内容如下:

 #ifndef __STC12DELAY_H__

#define __STC12DELAY_H__



#define uchar unsigned char

#define uint unsigned int





/*****相关宏定义***/

    /* exact-width signed integer types */

typedef   signed          char int8_t;

typedef   signed short     int int16_t;

typedef   signed           int int32_t;

typedef   signed       long int int64_t;



    /* exact-width unsigned integer types */

typedef unsigned          char uint8_t;

typedef unsigned short     int uint16_t;

typedef unsigned           int uint32_t;

typedef unsigned       long int uint64_t;





////11.0592    1T

void delay01ms() //@11.0592MHz

{

unsigned char i, j;



_nop_();

i = 11;

j = 190;

do

{

while (--j);

} while (--i);

}



 //延时n ms

void delaynms(unsigned int n)

{   unsigned int i;

for(i=0;i<n;i++)

delay01ms();

}

//也是延时 n  ms

void delay(unsigned int n)

{   unsigned int i;

for(i=0;i<n;i++)

delay01ms();

}



////11.0592    1T

void delay1ms12(void)   //误差 -0.018084490741us

{

    unsigned char a,b,c;

    for(c=8;c>0;c--)

        for(b=197;b>0;b--)

            for(a=2;a>0;a--);

}



void delaynms12 (unsigned int n)

{   unsigned int i;

for(i=0;i<n;i++)

delay1ms12();

}



#endif


 

 

————

uart.h内容如下:

  


void UartInit();

void UartSendChar(unsigned char ch); //向外发送字节

void UartSendStr(unsigned char *pStr); //向外发送字符串



void UartInit()

{

//串口2,用于舵机控制器

//串口1,用于接收上位机发出指令

     S2CON = 0x50; // SCON: serail mode 1, 8-bit UART  定时器1作为波特率的发生器

 SCON = 0x50;

 AUXR=0X15;

 BRT=(int)(256-((11059200/9600)/32));

 EA = 1;

 ES = 1;

}



//串口2有关

void UartSendChar(unsigned char ch)   //向外发送字节

{

    S2BUF = ch;

    while(!(S2CON&S2TI));

    S2CON&=~S2TI;

}

void UartSendStr(uchar *pStr)     //向外发送字符串

{

    while(*pStr != 0)

     {

        S2BUF = *pStr++;

        while(!(S2CON&S2TI));

     S2CON&=~S2TI;

     }

}  

把生成的hex文件下载到单片机之后,单片机就不停的向串口发送:l,m,数据1,数据2,n,o,l,m,数据1,数据2,n,o, l,m,数据1,数据2,n,o, ……

 

好,然后是labview做的上位机界面的接收,显示。

 

先看界面情况:

 

然后看前面板程序:

 

先配置串口(和单片机内配置保持一致就行了),电脑上就可以选择串口号,包括蓝牙也可以直接选择电脑蓝牙对应的串口号:

 

再经过一个while循环,循环内进行主要数据的接受和处理。先visa读取数据,这里每次读取10个数据,一边直接显示在缓存区,同时下面接一根线将其转化为图标。

 

 

下面将visa读取的数据实际上是一个字符类型的,转化为字节数组。

下面接for循环,来解析分别把这个10个元素的一维数组内的数据索引出来。

 

 

索引数组就是脚本语言中的a[5],把a数组中第6个元素取出来。

下面就分别把这个数组中,a[i],a[i+1],a[i+2],a[i+3]这4个元素分别拿出来。i是遍历的从0-9。

然后判断,如果满足a[i] =109,a[i+3]=110,(109和110分别是asc的字符mn) 那么 把a[i+1]和a[i+2]这2真实数据拿出来进行一个类型转换,转化为真实的电压数据显示出来即可。

 

完整的labview代码如下:

 

Over~

 

 

2018-05-19 16:09:54 qq_38410730 阅读数 120180
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6018 人正在学习 去看看 朱有鹏

HC-05蓝牙串口通信模块应该是使用最广泛的一种蓝牙模块之一了。为什么呢?

因为HC05模块是一款高性能主从一体蓝牙串口模块,可以不用知道太多蓝牙相关知识就可以很好的上手。说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就可以了,实现了所谓的透明传输。

但是就是这么一个很常见的模块,网上很多的博客写的都是错的,或者都是很不详细的。

所以本文就介绍一下这款蓝牙通信模块的使用,包括蓝牙模块的调试、手机与蓝牙模块之间的传输、手机蓝牙控制STM32单片机,应该是逐渐深入的一个过程。但是这仅仅是使用,以后有时间应该会对蓝牙有一个稍微深度的学习,而不能仅仅是浮于表面,只会用。

 

模块名称:HC-05蓝牙串口通信模块

参考资料:HC-05蓝牙串口通信模块官方资料包

知识储备:【STM32】串口通信基本原理(超基础、详细版)

其他模块:USB转TTL模块、手机蓝牙串口助手app

手机蓝牙串口助手软件,可以点击链接下载:蓝牙串口。因为这是我见过所有手机端界面最好看的了,其他的界面都有点太糟糕了。

 

蓝牙模块的调试

准备工作

USB转TTL模块与HC-05蓝牙模块的接线:

两模块共地,两模块共VCC(VCC取5V);蓝牙模块的RX接转换模块的TX,蓝牙模块的TX接转换模块的RX。如下图所示:

这个时候就要将转换模块连接到电脑上,然后利用串口调试助手进行蓝牙模块的调试。

附可能会用到的驱动:链接:https://pan.baidu.com/s/1bpYLfCr 密码:yabv

蓝牙模块的调试

HC-05蓝牙串口通讯模块具有两种工作模式:命令响应工作模式和自动连接工作模式。在自动连接工作模式下模块又可分为主(Master)、从(Slave)和回环(Loopback)三种工作角色。

  • 当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;
  • 当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT 指令,为模块设定控制参数或发布控制命令。

怎么进入命令响应工作模式?

进入命令响应工作模式有两种方法:

  • 模块上电,未配对情况下就是AT模式,波特率为模块本身的波特率,默认:9600,发送一次AT指令时需要置高一次PIO11;
  • PIO11 置高电平后,再给模块上电,此时模块进入AT 模式,波特率固定为:38400,可以直接发送AT指令。

什么叫做置高一次PIO11?

在蓝牙模块中有一个小按键,按一下就置高一次PIO11。也就是说,第一种方法需要每发送一次AT指令按一次;而第二种方式是长按的过程中上电,之后就无需再管了,直接发送AT命令即可。

需要注意一下,两种进入命令响应工作模式的方式使用的波特率是不一样的,建议使用第二种方式。

怎么区分进了命令响应工作模式呢?

在蓝牙模块上有灯,当灯快闪的时候,就是自动连接工作模式;当灯慢闪的时候,就是命令响应工作模式。

AT命令

进入到命令响应工作模式之后,就可以使用串口调试助手进行蓝牙调试了。

首先有一点,AT指令不区分大小写,均以回车、换行结尾。下面介绍常用的AT指令:

常用AT指令
指令名 响应 含义
AT OK 测试指令
AT+RESET OK 模块复位
AT+VERSION? +VERSION:<Param> OK 获得软件版本号
AT+ORGL OK 恢复默认状态
AT+ADDR? +ADDR:<Param> OK 获得蓝牙模块地址
AT+NAME=<Param> OK 设置设备名称
AT+NAME? +NAME:<Param> OK 获得设备名称
AT+PSWD=<Param> OK 设置模块密码
AT+PSWD? +PSWD:<Param> OK 获得模块密码
AT+UART=<Param1>,<Param2>,<Param3> OK 设置串口参数
AT+UART? +UART:<Param1>,<Param2>,<Param3> OK 获得串口参数

对于AT指令,有几点注意:

  • AT+NAME?:获得设备名称,这个AT指令有很大可能性是没有返回的,因为我也看到了很多的例子……,但是其他的指令都是没有问题的,直接设置设备名称就行了;
  • AT+UART?:获得串口参数,串口的参数一共有三个,波特率、停止位、检验位。其取值如下:
串口参数
参数名称 取值
波特率

2400、4800、9600、19200、38400、5760、

115200、230400、460800、921600、1382400

停止位

0:1位

1:2位

校验位 0:NONE  1:Odd  2:Even

其默认值为:9600,0,0。

例子:

本文中,蓝牙串口的波特率设置成115200。之后的内容,就会采用这个波特率来进行通讯了。

 

手机与蓝牙模块之间的传输

直接将蓝牙模块与转换模块连接,再讲其连接到电脑上,蓝牙模块直接进入自动连接工作模式。

此时手机打开蓝牙串口调试应用,用其来连接蓝牙模块。手机蓝牙串口助手软件,可以点击链接下载:蓝牙串口。万分推荐这款,因为界面脱离了那种黑不溜秋的感觉,比较简洁、清爽。

这个软件的使用:点击界面右下角蓝牙的标志,选择蓝牙进行连接。

然后在电脑上的调试助手和手机的蓝牙串口调试应用之间就可以相互传输了,比如:

可以清楚的看到:电脑向手机发送了“hello you”,手机向电脑发送了“hello world”。

 

手机蓝牙控制STM32单片机

之前的两个例子都是相比较而言比较简单的,这个例子将会涉及到程序的内容了。

实现功能:手机通过蓝牙,向STM32单片机发送消息,STM32接收到消息之后原封不动的返回给手机。当然如果掌握了这个例子,也可以修改成,手机发送特定的消息,然后,STM32单片机做出相对应的动作。比如:点亮LED等、发动电机等等。

连接说明

使用USART1进行试验,也就是说STM32选取PA9、PA10来和HC-05进行连接。同时手机通过蓝牙来和HC-05进行连接。

原理就是:手机通过蓝牙传输到HC-05上,再通过串口通信和STM32通信;而之前一般都是电脑上通过USB线转串口的方式,通过串口和STM32通信。本质上没有区别的。

这个时候就应该更加深刻地体会到了本文开篇的一句话:说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就可以了,实现了所谓的透明传输。蓝牙的相关一切都被封装起来了,都不需要接触到。

STM32控制程序

#include "stm32f10x.h"

 void My_USART1_Init(void)  
{  
    GPIO_InitTypeDef GPIO_InitStrue;  
    USART_InitTypeDef USART_InitStrue;  
    NVIC_InitTypeDef NVIC_InitStrue;  
      
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIO端口使能  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口端口使能  
      
    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;  
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;  
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;  
    GPIO_Init(GPIOA,&GPIO_InitStrue);  
      
    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;  
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;  
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;  
    GPIO_Init(GPIOA,&GPIO_InitStrue);  
      
    USART_InitStrue.USART_BaudRate=115200;  
    USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  
    USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;  
    USART_InitStrue.USART_Parity=USART_Parity_No;  
    USART_InitStrue.USART_StopBits=USART_StopBits_1;  
    USART_InitStrue.USART_WordLength=USART_WordLength_8b;  
      
    USART_Init(USART1,&USART_InitStrue);
      
    USART_Cmd(USART1,ENABLE);//使能串口1  
      
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启接收中断  
      
    NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;  
    NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;  
    NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;  
    NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;  
    NVIC_Init(&NVIC_InitStrue);  
      
}  
  
void USART1_IRQHandler(void)  
{  
    u8 res;  
     if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  
 {  
     res= USART_ReceiveData(USART1); 	 
     USART_SendData(USART1,res);     
  }  
}  
   
 int main(void)  
 {    
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
    My_USART1_Init();  
     while(1);  
       
 } 

这段程序和【STM32】串口相关配置寄存器、库函数(UART一般步骤)中的程序一模一样,几乎没有什么改动。

区别就是,在UART实验中,USART1是和USB转串口模块连接在一起的,然后与电脑上的串口调试助手进行通信;现在改成USART1是和蓝牙模块连接在一起的,然后和手机上的蓝牙串口调试助手进行通信。

 

2018-05-02 22:40:08 dok12 阅读数 854
  • 串口通信和RS485-第1季第13部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第13个课程,主要讲解了串行通信UART及其扩展RS485。本课程很重要,因为串口通信是我们接触的早也简单的通信方式,是后续继续学习SPI、I2C甚至USB、网络通信等的基础,大家务必认证对待完全掌握。

    6018 人正在学习 去看看 朱有鹏

将编写好的程序烧录,烧录工具ISP,注意烧录时候蓝牙模块与单片机的P30,P31接口的杜邦线要取下来,烧录结束之后再插上杜邦线,不过这时候的TX,RX端的杜邦线必须对调。即TX ->p30,RX->P31

手机下载蓝牙串口APP,选择第一个安装

安装成功之后打开蓝牙连接HC06

设置好APP,如图,选择数据格式16进制

开始发送,接收到了数字8,同时单片机P0口流水灯按照预定计划显示。表明通讯成功

没有更多推荐了,返回首页