日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

s5p4418 android 驱动 hal 应用之led 串口 rs485 can总线应用(app 有源码)

發布時間:2024/9/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 s5p4418 android 驱动 hal 应用之led 串口 rs485 can总线应用(app 有源码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇是繼上篇的jni層后的app應用層。

由于app相對比較大,說起來也比較麻煩,這里就用一個串口來說明即可,實際上也就串口最具代表性,這個明白了,其他都不是問題。

串口涉及的java文件如下圖紅色圈所示:


具體的代碼下面一一貼出來,撿重要的說明:

MainActivity.java:

package com.example.realarmapp;import realarm.can.RealarmCanActivity; import realarm.serial.RealarmUartActivity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {private Button btnLED, btnUART, btnRS485, btnCAN;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btnLED = (Button) findViewById(R.id.btnLED);btnUART = (Button) findViewById(R.id.btnUART);btnRS485 = (Button) findViewById(R.id.btnRS485);btnCAN = (Button) findViewById(R.id.btnCAN);btnLED.setOnClickListener(this);btnUART.setOnClickListener(this);btnRS485.setOnClickListener(this);btnCAN.setOnClickListener(this);}@Overridepublic void onClick(View v) {if(v.equals(btnLED)){Intent i = new Intent(MainActivity.this, RealarmLedActivity.class);startActivity(i);}else if(v.equals(btnUART)) {Intent i = new Intent(MainActivity.this, RealarmUartActivity.class);startActivity(i);}else if(v.equals(btnRS485)) {Intent i = new Intent(MainActivity.this, RealarmUartActivity.class);startActivity(i);}else if(v.equals(btnCAN)) {Intent i = new Intent(MainActivity.this, RealarmCanActivity.class);startActivity(i);}}} 這個文件是主activity文件,沒什么好說的,就是四個按鈕執行不同的功能。

HardwareControl.java:

package realarm.hardware;

package realarm.hardware;import java.io.FileDescriptor;public class HardwareControl {public native int LedSetState(int ledNum,int ledState);public native static FileDescriptor OpenSerialPort(String path, int baudrate,int flags);public native static void CloseSerialPort();public native static void InitCan(int baudrate);public native static int OpenCan();public native static int CanWrite(int canId,String data);public native static CanFrame CanRead(CanFrame mcanFrame, int time);public native static void CloseCan();static {System.loadLibrary("RealarmHardwareJni");}}

該文件是聲明native接口,并加載libRealarmHardwareJNI.so庫。

MyApplication.java:

package realarm.serial;import java.io.File; import java.io.IOException; import java.security.InvalidParameterException;import realarm.serial.utils.SerialPort; import realarm.serial.utils.SerialPortFinder;import android.app.Application; import android.content.SharedPreferences; import realarm.hardware.HardwareControl; public class MyApplication extends Application {public SerialPortFinder mSerialPortFinder = new SerialPortFinder();private SerialPort mSerialPort = null;public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {if (mSerialPort == null) {/* Read serial port parameters */SharedPreferences sp = getSharedPreferences("android_serialport_api.sample_preferences", MODE_PRIVATE);String path = sp.getString("DEVICE", "/dev/ttyAMA4");int baudrate = Integer.decode(sp.getString("BAUDRATE", "115200"));/* Check parameters */if ( (path.length() == 0) || (baudrate == -1)) {throw new InvalidParameterException();}/* Open the serial port */mSerialPort = new SerialPort(new File(path), baudrate, 0);}return mSerialPort;}public SerialPort getSerialPort(String path, String baudrate, int flag) throws NumberFormatException, SecurityException, IOException{if (mSerialPort == null) {/* Open the serial port */mSerialPort = new SerialPort(new File(path), Integer.decode(baudrate), flag);} return mSerialPort;}public void closeSerialPort() {if (mSerialPort != null) {HardwareControl.CloseSerialPort();mSerialPort = null;}} } 該文件實現串口的創建和關閉方法。
SerialPort.java:

package realarm.serial.utils;import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;import android.util.Log; import realarm.hardware.HardwareControl; public class SerialPort {private static final String TAG = "SerialPort";/** Do not remove or rename the field mFd: it is used by native method* close();*/private FileDescriptor mFd;private FileInputStream mFileInputStream;private FileOutputStream mFileOutputStream;public SerialPort(File device, int baudrate, int flags)throws SecurityException, IOException {/* Check access permission */if (!device.canRead() || !device.canWrite()) {try {/* Missing read/write permission, trying to chmod the file */Process su;su = Runtime.getRuntime().exec("/system/xbin/su");String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"+ "exit\n";su.getOutputStream().write(cmd.getBytes());if ((su.waitFor() != 0) || !device.canRead()|| !device.canWrite()) {throw new SecurityException();}} catch (Exception e) {e.printStackTrace();throw new SecurityException();}}mFd = HardwareControl.OpenSerialPort(device.getAbsolutePath(), baudrate, flags);if (mFd == null) {Log.e(TAG, "native open returns null");throw new IOException();}mFileInputStream = new FileInputStream(mFd);mFileOutputStream = new FileOutputStream(mFd);}// Getters and setterspublic InputStream getInputStream() {return mFileInputStream;}public OutputStream getOutputStream() {return mFileOutputStream;} } 該文件實現串口的打開、數據輸入、數據輸出的方法。

SerialPortFinder.java:

package realarm.serial.utils;import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; import java.util.Iterator; import java.util.Vector;import android.util.Log;public class SerialPortFinder {private static final String TAG = "SerialPort";private Vector<Driver> mDrivers = null;public class Driver {public Driver(String name, String root) {mDriverName = name;mDeviceRoot = root;}private String mDriverName;private String mDeviceRoot;Vector<File> mDevices = null;public Vector<File> getDevices() {if (mDevices == null) {mDevices = new Vector<File>();File dev = new File("/dev");File[] files = dev.listFiles();int i;for (i = 0; i < files.length; i++) {if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) {Log.d(TAG, "Found new device: " + files[i]);mDevices.add(files[i]);}}}return mDevices;}public String getName() {return mDriverName;}}Vector<Driver> getDrivers() throws IOException {if (mDrivers == null) {mDrivers = new Vector<Driver>();LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers"));String l;while ((l = r.readLine()) != null) {// Issue 3:// Since driver name may contain spaces, we do not extract// driver name with split()String drivername = l.substring(0, 0x15).trim();String[] w = l.split(" +");if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) {Log.d(TAG, "Found new driver " + drivername + " on "+ w[w.length - 4]);mDrivers.add(new Driver(drivername, w[w.length - 4]));}}r.close();}return mDrivers;}public String[] getAllDevices() {Vector<String> devices = new Vector<String>();// Parse each driverIterator<Driver> itdriv;try {itdriv = getDrivers().iterator();while (itdriv.hasNext()) {Driver driver = itdriv.next();Iterator<File> itdev = driver.getDevices().iterator();while (itdev.hasNext()) {String device = itdev.next().getName();String value = String.format("%s (%s)", device,driver.getName());devices.add(value);}}} catch (IOException e) {e.printStackTrace();}return devices.toArray(new String[devices.size()]);}public String[] getAllDevicesPath() {Vector<String> devices = new Vector<String>();// Parse each driverIterator<Driver> itdriv;try {itdriv = getDrivers().iterator();while (itdriv.hasNext()) {Driver driver = itdriv.next();Iterator<File> itdev = driver.getDevices().iterator();while (itdev.hasNext()) {String device = itdev.next().getAbsolutePath();devices.add(device);}}} catch (IOException e) {e.printStackTrace();}return devices.toArray(new String[devices.size()]);} } 該文件實現應用程序在/dev目錄下檢索tty*節點的方法。


RealarmUartActivity.java:

package realarm.serial;import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List;import com.example.realarmapp.R;import realarm.serial.utils.SerialPort; import realarm.serial.utils.SerialPortFinder;import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.Spinner; import android.widget.ToggleButton;public class RealarmUartActivity extends Activity {protected MyApplication mApplication;protected SerialPort mSerialPort;protected OutputStream mOutputStream;private InputStream mInputStream;private ReadThread mReadThread;EditText EditTextEmission, EditTextReception;SerialPortFinder mSerialPortFinder;// 串口設備搜索Spinner spinnerCOM;Spinner spinnerBaudRateCOM;CheckBox checkBoxAutoCOM;ToggleButton toggleButtonCOM;Button buttonSendCOM, buttonClean;private class ReadThread extends Thread {@Overridepublic void run() {super.run();while (!isInterrupted()) {int size;try {byte[] buffer = new byte[64];if (mInputStream == null)return;/*** 這里的read要尤其注意,它會一直等待數據,等到天荒地老,海枯石爛。如果要判斷是否接受完成,只有設置結束標識,* 或作其他特殊的處理。*/size = mInputStream.read(buffer);if (size > 0) {onDataReceived(buffer, size);}} catch (IOException e) {e.printStackTrace();return;}}}}protected void onDataReceived(final byte[] buffer, final int size) {runOnUiThread(new Runnable() {public void run() {if (EditTextReception != null) {EditTextReception.append(new String(buffer, 0, size));}}});}private void DisplayError(int resourceId) {AlertDialog.Builder b = new AlertDialog.Builder(this);b.setTitle("Error");b.setMessage(resourceId);b.setPositiveButton("OK", new OnClickListener() {public void onClick(DialogInterface dialog, int which) {RealarmUartActivity.this.finish();}});b.show();}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.uart);<span style="color:#ff0000;">mApplication = (MyApplication) getApplication();</span>mSerialPortFinder = new SerialPortFinder();EditTextReception = (EditText) findViewById(R.id.EditTextReception);EditTextEmission = (EditText) findViewById(R.id.EditTextEmission);buttonClean = (Button) findViewById(R.id.buttonClean);buttonSendCOM = (Button) findViewById(R.id.buttonSendCOM);spinnerCOM = (Spinner) findViewById(R.id.spinnerCOM);spinnerBaudRateCOM = (Spinner) findViewById(R.id.spinnerBaudRateCOM);checkBoxAutoCOM = (CheckBox) findViewById(R.id.checkBoxAutoCOM);toggleButtonCOM = (ToggleButton) findViewById(R.id.toggleButtonCOM);ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.baudrates_value,android.R.layout.simple_spinner_item);adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);spinnerBaudRateCOM.setAdapter(adapter);spinnerBaudRateCOM.setSelection(16);String[] entryValues = mSerialPortFinder.getAllDevicesPath();List<String> allDevices = new ArrayList<String>();for (int i = 0; i < entryValues.length; i++) {allDevices.add(entryValues[i]);}ArrayAdapter<String> aspnDevices = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, allDevices);aspnDevices.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);spinnerCOM.setAdapter(aspnDevices);if (allDevices.size() > 0) {spinnerCOM.setSelection(4);}buttonClean.setOnClickListener(new ButtonClickEvent());buttonSendCOM.setOnClickListener(new ButtonClickEvent());toggleButtonCOM.setOnCheckedChangeListener(new ToggleButtonCheckedChangeEvent()); spinnerCOM.setOnItemSelectedListener(new ItemSelectedEvent());spinnerBaudRateCOM.setOnItemSelectedListener(new ItemSelectedEvent());if (!toggleButtonCOM.isChecked()) {/*如果沒有打開串口,那么發送按鈕灰色不允許操作*/buttonSendCOM.setEnabled(false);} // try { // mSerialPort = mApplication.getSerialPort(); // mOutputStream = mSerialPort.getOutputStream(); // mInputStream = mSerialPort.getInputStream(); // // /* Create a receiving thread */ // mReadThread = new ReadThread(); // mReadThread.start(); // } catch (SecurityException e) { // DisplayError(R.string.error_security); // } catch (IOException e) { // DisplayError(R.string.error_unknown); // } catch (InvalidParameterException e) { // DisplayError(R.string.error_configuration); // }}// protected abstract void onDataReceived(final byte[] buffer, final int size);@Overrideprotected void onDestroy() {if (mReadThread != null)mReadThread.interrupt();mApplication.closeSerialPort();mSerialPort = null;super.onDestroy();}// ----------------------------------------------------串口號或波特率變化時,關閉打開的串口class ItemSelectedEvent implements Spinner.OnItemSelectedListener {public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,long arg3) {if ((arg0 == spinnerCOM) || (arg0 == spinnerBaudRateCOM)) {mApplication.closeSerialPort();checkBoxAutoCOM.setChecked(false);toggleButtonCOM.setChecked(false);}}public void onNothingSelected(AdapterView<?> arg0) {}}// ----------------------------------------------------清除按鈕、發送按鈕class ButtonClickEvent implements View.OnClickListener {public void onClick(View v) {if (v == buttonClean) {EditTextReception.setText("");}else if (v == buttonSendCOM) {if (toggleButtonCOM.isChecked()) {try {mOutputStream.write(EditTextEmission.getText().toString().getBytes());mOutputStream.write('\n');System.out.println("串口數據發送成功");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}else{System.out.println("串口未打開");}}}}//----------------------------------------------------打開關閉串口class ToggleButtonCheckedChangeEvent implements ToggleButton.OnCheckedChangeListener{public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){if (buttonView == toggleButtonCOM){if (isChecked){try { // mSerialPort = new SerialPort(new File(spinnerCOM.getSelectedItem().toString()), // Integer.decode(spinnerBaudRateCOM.getSelectedItem().toString()), 0);mSerialPort = mApplication.getSerialPort(spinnerCOM.getSelectedItem().toString(), spinnerBaudRateCOM.getSelectedItem().toString(), 0);mOutputStream = mSerialPort.getOutputStream();mInputStream = mSerialPort.getInputStream();/* Create a receiving thread */mReadThread = new ReadThread();mReadThread.start();buttonSendCOM.setEnabled(true);/*使能發送按鈕,這時可以發送數據了*/System.out.println("打開串口"+spinnerCOM.getSelectedItem().toString()+"成功!");} catch (NumberFormatException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}else {mApplication.closeSerialPort();checkBoxAutoCOM.setChecked(false);buttonSendCOM.setEnabled(false);/*關閉發送按鈕使能*/System.out.println("關閉串口"+spinnerCOM.getSelectedItem().toString()+"成功!");}}}} } 該文件就是串口操作的主activity了,加載布局文件等。在該文件中,這里重要說明MyApplication這個類的調用。就是上面的紅色代碼。

也許有朋友在http://blog.csdn.net/tangcheng_ok/article/details/7021470這篇文章時,就遇到了這個問題,雖然編譯通過,可是運行就會蹦掉。當然了,我也看了,而且遇到了。

那么這是怎么回事呢,通過報錯提示“找不到資源”,可以知道當執行到紅色部分時,應用程序無法找到資源。可是我們明明定義了MyApplication這個類,且繼承與Application,為什么會找不到呢。代碼定義當然沒問題,實際上問題出在沒有告訴app我定義了這個MyApplication。只需要在AndroidManifest.xml文件中添加下面紅色的代碼即可解決問題:


這句代碼就是告訴app要使用MyApplication這個繼承與Application的類。

下面貼出運行的界面,O(∩_∩)O。

主界面:


led操作界面:


串口操作界面:



485與串口區別就是打開的串口號不同:


can操作界面:


再來個豎屏的,在布局時考慮到了適應問題,所以沒有采用絕對布局,可以適應各分辨率大小的屏幕,只要分辨率不要太小,完全顯示都是沒問題的。




源碼下載地址:http://download.csdn.net/detail/u010406724/8539209


轉載請注明出處:http://blog.csdn.net/wang_shuai_ww/article/details/44676937

總結

以上是生活随笔為你收集整理的s5p4418 android 驱动 hal 应用之led 串口 rs485 can总线应用(app 有源码)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。