c#SerialPort的数据处理问题

我想对读取串口发来的数据做处理,分别是单次发送来和两次(多次)短时间内发来的数据做不同的处理,怎么实现?谢谢!

1个回答

你最好在消息中加上消息头,区分是什么类型的,否则你靠这个时间,不靠谱

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
C#serialPort实现串口通信
我想实现的是上位机发送数据,然后接收数据,然后上位机处理数据,再继续发送数据一直循环到结束。 目前的问题就是,我通过以下代码实现的是在循环调用测试函数,循环运行完了以后,才开始读取数据 ``` public Form1() { InitializeComponent(); serialPort1.DataReceived += serialPort1_DataReceived; } private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { this.Invoke(new EventHandler(Read)); } private void Read(object s, EventArgs e) { int n = serialPort1.BytesToRead; byte[] buf = new byte[n]; serialPort1.Read(buf, 0, n); data_catched=true; } public bool test_CA() {//测试CA //定义附加信息 Byte[] test_CA_add = new Byte[1] { 0x00 }; //发送命令帧 Write(test_cmd_CA, test_CA_add);//发送数据函数测试无误,并在发送完后立刻有数据返回 byte test_CA_data; //时延等待接收数据 for (int i = 0; !data_catched && i < 300; i++) { Thread.Sleep(10); } if (!data_catched) { //处理数据 } data_catched=false; } ```
C# SerialPort的Datareceive事件触发后,BytesToRead的值有时候为零
下位机每隔0.5秒通过串口传25个字节到上位机,串口接收到数据后处理并用zedgraph控件绘制实时曲线图,程序运行几分钟后,Datareceive事件触发后,BytesToRead的值有时候为0,有时是25,也有时是50,界面刷新有时也不是0.5秒。 接收程序: ``` private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { if (mySerialPort.IsOpen) { Thread.Sleep(10); int count = mySerialPort.BytesToRead; byte[] data = new byte[count]; mySerialPort.Read(data, 0, count); if (data[0] == 0x01 && data[1] == 0x03) { this.Invoke(textChanged, data, count); } } } catch (Exception err) { throw err; } } ``` 处理程序: ``` textChanged += new UpdateTextEventHandler(ChangeText); private delegate void UpdateTextEventHandler(byte[] buffer,int m);//定义委托 private event UpdateTextEventHandler textChanged;//定义事件 private void ChangeText(byte[] buffer,int m) //事件处理方法 { s1 = ""; Array.Copy(buffer, 3, float_byte1, 0, 4); Array.Copy(buffer, 8, float_byte2, 0, 4); Array.Copy(buffer, 13, float_byte3, 0, 4); Array.Copy(buffer, 18, float_byte4, 0, 4); temperture[0] = BitConverter.ToSingle(float_byte1, 0); temperture[1] = BitConverter.ToSingle(float_byte2, 0); temperture[2] = BitConverter.ToSingle(float_byte3, 0); temperture[3] = BitConverter.ToSingle(float_byte4, 0); textBox1.Text = temperture[0].ToString(); textBox2.Text = temperture[1].ToString(); textBox3.Text = temperture[2].ToString(); textBox4.Text = temperture[3].ToString(); for (int i = 0; i < m; i++) { s1 += buffer[i].ToString("X2"); s1 += " "; } textBox5.Text = s1.ToString(); if (Curve_Flag == 1) { i++; creatGraph(temperture[j]); } } ``` zedgraph绘图: ``` public void creatGraph(float temp) { double x = (double)i; double y = Convert.ToDouble(temp); list.Add(x, y); myCurve = zedGraphControl1.GraphPane.AddCurve("", list, Color.Red, SymbolType.None); //myCurve.Symbol.Fill = new Fill(Color.Blue);//填充数据点 zedGraphControl1.AxisChange();//画到zedGraphControl1控件中,此句必加 zedGraphControl1.Refresh();//重新刷新 } ```
基于C# 条形码扫描系统 问题点();
基于C# 条形码扫描系统 问题点(); 系统控制流程 A.固定式条码阅读器,读取产品条形码,通过USB串口线连接IPC,并将条形码存入数据库。 B.当固定式条码阅读器无法扫码成功,信号灯点亮蜂鸣器报警;要求手动扫码。 C.手动扫码失败,即由人工输入完成条码录入。 问题点: 1. 固定式扫码枪串口连接电脑,C#程序调用SerialPort类实现Textbox接收条码数据,并绑定到DataGridView显示,请问是否可以实现? 2. 考虑到产品条码数据的庞大数据量,是否需要调用多线程处理?如何开多线程处理,如有这方面的实例,请多多指教!非常感谢~ ![图片说明](https://img-ask.csdn.net/upload/201603/15/1458022793_233341.jpg)
c#编写的串口助手打开串口32单片机立刻黑屏,急求
using Microsoft.Win32; using System; using System.IO.Ports; using System.Windows.Forms; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; namespace WindowsFormsApp { public partial class Form1 : Form { //SerialPort sp = null;//声明一个串口类 bool isOpen = false;//打开串口标志位 bool isSetProperty = false;//属性设置标志位 bool isHex = false;//十六进制显示标志位 public Form1() { InitializeComponent(); System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//设置该属性为false } //我们在form载入时,扫描识别存在的串口。 private void Form1_Load(object sender, EventArgs e) { this.MaximumSize = this.Size; this.MinimumSize = this.Size; this.MaximizeBox = false; RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm"); if (keyCom != null) { string[] sSubKeys = keyCom.GetValueNames(); cbxCOMPort.Items.Clear(); foreach (string sName in sSubKeys) { string sValue = (string)keyCom.GetValue(sName); cbxCOMPort.Items.Add(sValue); } if (cbxCOMPort.Items.Count > 0) cbxCOMPort.SelectedIndex = 0; else { cbxCOMPort.Text = ""; MessageBox.Show("没有找到可用串口!", "错误提示"); } } cbxBaudRate.SelectedIndex = 4; cbxStopBits.SelectedIndex = 1; cbxDataBits.SelectedIndex = 0; cbxParity.SelectedIndex = 0; rbnChar.Checked = true; } private void btnCheckCOM_Click(object sender, EventArgs e)//检测哪些串口可用 { RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm"); if (keyCom != null) { string[] sSubKeys = keyCom.GetValueNames(); cbxCOMPort.Items.Clear(); foreach (string sName in sSubKeys) { string sValue = (string)keyCom.GetValue(sName); cbxCOMPort.Items.Add(sValue); } if (cbxCOMPort.Items.Count > 0) cbxCOMPort.SelectedIndex = 0; else { cbxCOMPort.Text =""; MessageBox.Show("没有找到可用串口!", "错误提示"); } } } private bool CheckPortSetting()//检查串口是否设置 { if (cbxCOMPort.Text.Trim() == "") return false; if (cbxBaudRate.Text.Trim() == "") return false; if (cbxDataBits.Text.Trim() == "") return false; if (cbxParity.Text.Trim() == "") return false; if (cbxStopBits.Text.Trim() == "") return false; return true; } private bool CheckSendData() { if (tbxSendData.Text.Trim() == "") return false; return true; } private void SetPortProperty()//设置串口的属性 { serialPort.PortName = cbxCOMPort.Text.Trim();//设置串口名 serialPort.BaudRate = Convert.ToInt32(cbxBaudRate.Text.Trim());//设置串口的波特率 float f = Convert.ToSingle(cbxStopBits.Text.Trim());//设置停止位 if (f == 0) { serialPort.StopBits = StopBits.None; } else if (f == 1.5) { serialPort.StopBits = StopBits.OnePointFive; } else if (f == 1) { serialPort.StopBits = StopBits.One; } else if (f == 2) { serialPort.StopBits = StopBits.Two; } else { serialPort.StopBits = StopBits.One; } serialPort.DataBits = Convert.ToInt16(cbxDataBits.Text.Trim());//设置数据位 string s = cbxParity.Text.Trim(); //设置奇偶校验位 if (s.CompareTo("无") == 0) { serialPort.Parity = Parity.None; } else if (s.CompareTo("奇校验") == 0) { serialPort.Parity = Parity.Odd; } else if (s.CompareTo("偶校验") == 0) { serialPort.Parity = Parity.Even; } else { serialPort.Parity = Parity.None; } serialPort.ReadTimeout = -1;//设置超时读取时间 serialPort.RtsEnable = true; //定义DataReceived 事件,当串口收到数据后触发事件 serialPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived); if (rbnHex.Checked) { isHex = true; } else { isHex = false; } } private void btnOpenCom_Click(object sender, EventArgs e) { if (!isOpen) { if (!CheckPortSetting())//检测串口设置 { MessageBox.Show("串口未设置!", "错误提示"); return; } if (!isSetProperty)//串口未设置则设置串口 { SetPortProperty(); isSetProperty = true; } try { serialPort.Open(); //打开串口 btnOpenCom.Text = "关闭串口"; cbxCOMPort.Enabled = false;//关闭使能 cbxBaudRate.Enabled = false; cbxStopBits.Enabled = false; cbxParity.Enabled = false; cbxDataBits.Enabled = false; rbnChar.Enabled = false; rbnHex.Enabled = false; isOpen = true; serialPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);//串口接收处理函数 } catch { MessageBox.Show("串口打开失败!"); } } else { try { serialPort.Close(); //关闭串口 btnOpenCom.Text = "打开串口"; cbxCOMPort.Enabled = true;//打开使能 cbxBaudRate.Enabled = true; isOpen = false; } catch { MessageBox.Show("串口关闭失败!"); } } } //private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) //{ // string str = serialPort.ReadExisting();//字符串方式读 // tbxRecvData.Text = "";//先清除上一次的数据 // tbxRecvData.Text += str; //} private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) { System.Threading.Thread.Sleep(100);//延时 100ms 等待接收完数据 //this.Invoke 就是跨线程访问 ui 的方法,也是本文的范例 this.Invoke((EventHandler)(delegate { if (isHex == false) { tbxRecvData.Text += serialPort.ReadLine(); } else { Byte[] ReceivedData = new Byte[serialPort.BytesToRead]; //创建接收字节数组 serialPort.Read(ReceivedData, 0, ReceivedData.Length); //读取所接收到的数据 String RecvDataText = null; for (int i = 0; i < ReceivedData.Length - 1; i++) { RecvDataText += ("0x" + ReceivedData[i].ToString("X2") + " "); } tbxRecvData.Text += RecvDataText; } serialPort.DiscardInBuffer();//丢弃接收缓冲区数据 })); } private void btnSend_Click(object sender, EventArgs e) { //发送数据 if (serialPort.IsOpen) {//如果串口开启 if (tbxSendData.Text.Trim() != "")//如果框内不为空则 { serialPort.Write(tbxSendData.Text.Trim());//写数据 } else { MessageBox.Show("发送框没有数据"); } } else { MessageBox.Show("串口未打开"); } } private void btnCleanData_Click(object sender, EventArgs e) { tbxRecvData.Text = ""; tbxSendData.Text = ""; } } } 打开串口没有提示失败,但是单片机就不运行了。
C# 多窗口之间动态传值问题
我在做一个串口接收数据并处理的小软件,在主窗口接收并处理后在TextBox上输出,为了直观的显示数据变化,所以再开一个窗口显示波形。 我采用public类传递数值,为了方便测试,我还顺便传了一个随机数,结果每次随机数传过去了,串口的数据没有传过去。 把随机数生成放在接收事件中一样传递不过去。 传递参数的Public类。 ``` public int[] tranTest() { Random rd = new Random(); int[] TranArr = new int[4]; if (SpeedR1.Count > 0) { TranArr[0] = SpeedR1[SpeedR1.Count - 1]; TranArr[1] = SpeedR2[SpeedR2.Count - 1]; TranArr[2] = SpeedSU[SpeedSU.Count - 1]; } TranArr[3] = rd.Next(0, 400); return TranArr; } ``` 数据接收和处理 ``` int count = 0; Byte[] TFrame = new Byte[20]; int CountData = 0; Byte Flag = 0; private List<int> SpeedR1 = new List<int>(); private List<int> SpeedR2 = new List<int>(); private List<int> SpeedSU = new List<int>(); private List<int> SpeedAc = new List<int>(); private List<int> Reli = new List<int>(); private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { Byte[] data = new Byte[serialPort1.BytesToRead]; Byte[] Cdata = new Byte[1024*10]; string RecieveData=""; serialPort1.Read(data, 0, data.Length); //读取串口数据 for (int i = 0; i < data.Length; i++) { //RecieveData = RecieveData + BitConverter.ToString(data[i], 16) + " "; Cdata[CountData++] = data[i]; } RecieveData = BitConverter.ToString(data).Replace("-"," ")+" "; Thread DealData = new Thread(new ThreadStart(dealStr)); if (CountData >= 15) { int Temp=0; for (int j = 0; j < CountData - 2; j++) { if (Cdata[j] == 0xF3 && Cdata[j + 1] == 0xF4) { Flag = 1; Temp = j; break; } } if (Flag == 1) { for (int t = 0; t < 15 && Temp + t < CountData; t++) TFrame[count++] = Cdata[Temp + t]; if (count >= 15) { count = 0; Flag = 0; DealData.Start(); } } CountData = 0; } TxtRec.Invoke(new Action(() => { TxtRec.AppendText(RecieveData); })); } public void dealStr() { if (TFrame[2] == 1) SpeedR1.Add(TFrame[3] * 256 + TFrame[4]); else SpeedR1.Add((TFrame[3] * 256 + TFrame[4]) * (-1)); if (TFrame[5] == 1) SpeedR2.Add(TFrame[6] * 256 + TFrame[7]); else SpeedR2.Add((TFrame[6] * 256 + TFrame[7]) * (-1)); if (TFrame[8] == 1) SpeedSU.Add(TFrame[9] * 256 + TFrame[10]); else SpeedSU.Add((TFrame[9] * 256 + TFrame[10]) * (-1)); if (TFrame[11] == 1) SpeedAc.Add(TFrame[12]); else SpeedAc.Add(TFrame[12] * (-1)); Reli.Add (TFrame[13]); //tranTest(); string Speed1 = SpeedR1[SpeedR1.Count-1].ToString(); if (Speed1[0] != '0') { int Count1 = Speed1.Length; Speed1 = Speed1.Insert(Count1 - 2, "."); } string Speed2 = SpeedR2[SpeedR2.Count-1].ToString(); if (Speed2[0] != '0') { int Count1 = Speed2.Length; Speed2 = Speed2.Insert(Count1 - 2, "."); } string Speed_S = SpeedSU[SpeedSU.Count-1].ToString(); if (Speed_S[0] != '0') { int Count1 = Speed_S.Length; Speed_S = Speed_S.Insert(Count1 - 2, "."); } string Acc_Speed = SpeedAc[SpeedAc.Count-1].ToString(); if (Acc_Speed[0] != '0') { int Count1 = Acc_Speed.Length; if(Count1==1) Acc_Speed = Acc_Speed.Insert(Count1 - 1, "0."); else Acc_Speed = Acc_Speed.Insert(Count1 - 1, "."); } string Reliability = Reli[Reli.Count-1].ToString() + "%"; R1Speed.Invoke(new Action(() => { R1Speed.Clear(); R1Speed.AppendText(Speed1); })); R2Speed.Invoke(new Action(() => { R2Speed.Clear(); R2Speed.AppendText(Speed2); })); SumSpeed.Invoke(new Action(() => { SumSpeed.Clear(); SumSpeed.AppendText(Speed_S); })); AccSpeed.Invoke(new Action(() => { AccSpeed.Clear(); AccSpeed.AppendText(Acc_Speed); })); ReBility.Invoke(new Action(() => { ReBility.Clear(); ReBility.AppendText(Reliability); })); } ``` 窗口2中获取数据类有个定时器,定时获取。 ``` MainForm frm = new MainForm(); int[] DrawL1 = new int[1024 * 1024]; int[] DrawL2 = new int[1024 * 1024]; int[] DrawL3 = new int[1024 * 1024]; int[] TestDraw = new int[1024 * 1024]; int DCount=0; private void GetData() { int[] Tran=frm.tranTest(); DrawL1[DCount] = Tran[0]; DrawL2[DCount] = Tran[1]; DrawL3[DCount] = Tran[2]; TestDraw[DCount] = Tran[3]; DCount++; } ``` 一直在做C的嵌入式编程,现在要自己写一些测试软件和配套软件所以刚开始学C#,求各位大神指点。
上位机串口数据卡死 C# PID调试工具
自己用VS2013 C#编了一个类似串口助手的上位机现在出现以下问题 1.调试时未出现卡死任何问题,生成后点击传送数据没问题,但是不断发送就会直接卡死 自己分析:1.我每次传送36个字节,波特率9600 数据量太大 2.程序没有及时释放存储空间,导致卡死 3.程序处理的时间太长,导致处理不够及时 我大致搜了一下,他们说需要用一个线程。具体没学过C#,只是照着,查着学的。请高手帮我想想方法 以下是部分程序 串口接收事件: private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { if (!radioButton3.Checked) { textBox1.AppendText(serialPort1.ReadExisting()); //串口类会自动处理汉字,所以不需要特别转换 } else { try { byte[] data = new byte[serialPort1.BytesToRead]; //定义缓冲区,因为串口事件触发时有可能收到不止一个字节 serialPort1.Read(data, 0, data.Length); if (Displayer != null) Displayer.AddData(data); //!!!!! foreach (byte Member in data) //遍历用法 { string str = Convert.ToString(Member, 16).ToUpper(); textBox1.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " "); } } catch { } } } 以下是数据处理: public void AddData(byte[] Data) { if (Flag == 1) { for (int i = 0; i < Data.Length; i++) DataList.Add(Data[i]);//链表尾部添加数据 if (DataList.Count - 1 >= (this.ClientRectangle.Width - StartPrint - 240) / DrawStep)//如果数据量大于可容纳的数据量,即删除最左数据 { DataList.RemoveRange(0, 35); } data_get(); } Invalidate();//刷新显示 } public void data_get() { for (int i = DataList.Count -36 ; i < DataList.Count - 1; i++) //数据包分配 { if( DataList[i] == 0x50 ) { switch(DataList[i+1]) { case 0x56: { for (int j = 0; j < 4; j++) { Now_Data[j] = DataList[i + 2 + j]; //实时值数组 } break; } case 0x51: { for (int j = 0; j < 4; j++) { fData[j] = DataList[i + 2 + j]; //目标值数据 } break; } case 0x52: { for (int j = 0; j < 4; j++) { P_Data[j] = DataList[i + 2 + j]; //P数据 } break; } case 0x53: { for (int j = 0; j < 4; j++) { I_Data[j] = DataList[i + 2 + j]; } break; } case 0x54: { for (int j = 0; j < 4; j++) { D_Data[j] = DataList[i + 2 + j]; } break; } case 0x55: { for (int j = 0; j < 4; j++) { PWM_Data[j] = DataList[i + 2 + j]; } break; } } } } N_val[0]= BitConverter.ToSingle(Now_Data, 0); //以下为byte转化为float类型 Goal_val = BitConverter.ToSingle(fData, 0); P_val = BitConverter.ToSingle(P_Data, 0); I_val = BitConverter.ToSingle(I_Data, 0); D_val = BitConverter.ToSingle(D_Data, 0); PWM_val = BitConverter.ToSingle(PWM_Data, 0); if (N_Data.Count - 1 >= (this.ClientRectangle.Width - StartPrint - 240) / DrawStep)//如果数据量大于可容纳的数据量,即删除最左数据 { N_Data.RemoveRange(0, 5); } N_Data.Add(N_val[0]); textBox10.Text = (N_val[0]).ToString(); //以下为文本显示 textBox11.Text = Goal_val.ToString(); textBox12.Text = PWM_val.ToString(); textBox16.Text = P_val.ToString(); textBox17.Text = I_val.ToString(); textBox15.Text = D_val.ToString(); }
求助 ,关于C# winform窗体串口在读取一组参数后再一次读取另一组参数的问题
有两个按钮,一个是“开启基本数据按钮设为button1”,另一个是“读取ListBox内部 数据的内容“设为button2,设定是先开启button1接收基本数据后才能开启button2接 收ListBox内的数据,接收协议一共有5位,分别是报头,符号位,数据位,数据位,校验位(没有长度位),当开启button1后界面上的基本数据的TextBox值会不断发生变化。 。当点击button2后(会有个“正在发送,请等待5s”的一个winform窗口弹出。当第二 次再次接收到数据后,会把协议转换成数据添加到ListBox中,但问题来了:为什么有时 点击button2后接收到的数据中ListBox的第一行数据有时是0没收到数据,有时候会读 到数??????????????????? 我这里button1的基本原理是给控制器发送一个协议,控制器收到后吧几个基本数据的 协议发送给winform窗口并将协议转换为基本数据记录到TextBox内,这时数据是无限 接收的,从而几个基本数据会不断地有变化。button2和button1原理类似都是发送一 个协议而给ListBox发送数据,发送完成后退出窗口,ListBox的所有行的值都变化之后 继续接收button1的基础数据。 接收代码: int S, A, B, C, D; private List<byte> memory = new List<byte>(4096); private byte[] bufferbyte = new byte[5]; private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { if (Closing) return; Control.CheckForIllegalCrossThreadCalls = false; int n = comm.BytesToRead; Byte[] bytes = new Byte[n]; r_count += n;//记录接收的字节 comm.Read(bytes, 0, n); try { this.Invoke((EventHandler)delegate { if (n > 0) { #region 协议解析/分析数据 //<协议解析> bool data_1_catched = false;//缓存记录数据是否捕获到 memory.AddRange(bytes);//缓存数据 while (memory.Count >= 2)//至少要包含头(1字节)+校验(1字节) { if (memory[0] == 0x88) { if (memory.Count < 5) break; //<数据校验> if ((memory[4] != (memory[1] + memory[2] + memory[3]) % 256) && (memory[4] != (memory[1] - 128 + memory[2] + memory[3]) % 256)) { memory.RemoveRange(0, 5); continue; } memory.CopyTo(0, bufferbyte, 0, 5); data_1_catched = true; memory.RemoveRange(0, 5); //<分析数据> if (data_1_catched) { #region 接收协议定义,用于将协议转化为数据 ............................. #endregion #region 将基本数据转化并填充到TextBox ............................. #endregion #region 将ListBox数据协议转化并填充到ListBox ............................. #endregion } } }); Button1方法比较简单,就是两句话: SendData("88", "FF", "01", "01", "01", 10);//是发送协议方法 周期为10ms comm.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); Button2方法: private void ReadListBoxData_Click(object sender, EventArgs e) { WaitingForm waitf = new WaitingForm(); waitf.ShowIcon = false; waitf.label1.Text = "正在处理,请稍后......"; waitf.Show(); //如果不加上此句话,新窗体加载的内容都在队列中等待而不会绘制,从而导致新窗体没有内容。加上的话,新窗体会重新绘制 Application.DoEvents(); for (int ti = 0; ti < 4; ti++) { SendData("88", "FF", "04", "04", "07", 1000); } Thread.Sleep(4000); if (IsNull(bufferbyte) == true) { MessageBox.Show("重复超时,重新读取"); } waitf.Dispose(); //接受完ListBox的数据后,继续接收基本数据 SendData("88", "FF", "01", "01", "01", 10);// comm.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); } 最大的问题再说一下,就是ListBox的第一行数据有的时候能收到数有时候收不到数,但是自己通过把数据转化到字符串框之后,发现第一列的协议都没有问题, 怀疑是和之前的基本数据协议的尾端发生冲突了,求解决办法?? 现在有一个方法是协商控制器,在发送第一组数据之前添加个5位保护协议。有没有 更好的方法???
C# 代码错误,未将对象引用设置到对象的实例
private void btnSend_Click(object sender, EventArgs e) { if (cbTimeSend.Checked) { tmSend.Enabled = true; } else { tmSend.Enabled = false; } if (!sp1.IsOpen) //如果没打开 { MessageBox.Show("请先打开串口!", "Error"); return; } // string strSend = null; String strSend = txtSend.Text.ToString(); if (radio1.Checked == true) //“HEX发送” 按钮 { //处理数字转换 string sendBuf = strSend; string sendnoNull = sendBuf.Trim(); string sendNOComma = sendnoNull.Replace(',', ' '); //去掉英文逗号 string sendNOComma1 = sendNOComma.Replace(',', ' '); //去掉中文逗号 string strSendNoComma2 = sendNOComma1.Replace("0x", ""); //去掉0x strSendNoComma2.Replace("0X", ""); //去掉0X string[] strArray = strSendNoComma2.Split(' '); int byteBufferLength = strArray.Length; for (int i = 0; i < strArray.Length; i++) { if (strArray[i] == "") { byteBufferLength--; } } // int temp = 0; byte[] byteBuffer = new byte[byteBufferLength]; int ii = 0; for (int i = 0; i < strArray.Length; i++) //对获取的字符做相加运算 { Byte[] bytesOfStr = Encoding.Default.GetBytes(strArray[i]); int decNum = 0; if (strArray[i] == "") { //ii--; //加上此句是错误的,下面的continue以延缓了一个ii,不与i同步 continue; } else { decNum = Convert.ToInt32(strArray[i], 16); //atrArray[i] == 12时,temp == 18 } try //防止输错,使其只能输入一个字节的字符 { byteBuffer[ii] = Convert.ToByte(decNum); } catch (System.Exception ex) { MessageBox.Show("字节越界,请逐个字节输入!", "Error"); tmSend.Enabled = false; return; } ii++; } sp1.Write(byteBuffer, 0, byteBuffer.Length); } else //以字符串形式发送时 { sp1.WriteLine(txtSend.Text); //写入数据 } } void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e) { //输出当前时间 DateTime dt = DateTime.Now; txtReceive.Text += dt.GetDateTimeFormats('f')[0].ToString() + "\r\n"; txtReceive.SelectAll(); txtReceive.SelectionColor = Color.Blue; //改变字体的颜色 try { byte[] receivedData = new byte[sp1.BytesToRead]; //创建接收字节数组 sp1.Read(receivedData, 0, receivedData.Length); //读取数据 if (receivedData.Length == 0) return; sp1.DiscardInBuffer(); //清空SerialPort控件的Buffer if (receivedData.Length == 3 && receivedData[0] == 0xFF && receivedData[1] == _totalBytes[1] && receivedData[2] == 0x00) { //_totalBytes[1] = Convert.ToByte(_totalBytes[1] == 0xB5 ? 0xB6 : 0xB5); _totalBytes[1] = Convert.ToByte(_totalBytes[1] == 0xB6 ? 0xB5 : 0xB6); //_size += _totalBytes[1] == 0xB5 ? 512 : 0; _size += _totalBytes[1] == 0xB6 ? 512 : 0; SendBytes(false); } else { //发送失败 } string strRcv = null; if (rdSendStr.Checked) { strRcv = sp1.Encoding.GetString(receivedData); } else { //int decNum = 0;//存储十进制 for (int i = 0; i < receivedData.Length; i++) //窗体显示 { strRcv += receivedData[i].ToString("X2"); //16进制显示 } } txtReceive.Text += strRcv + "\r\n"; } catch (System.Exception ex) { MessageBox.Show(ex.Message, "出错提示"); txtSend.Text = ""; } } ``` 串口发送一段指定的字符串,串口接收,串口收到回复消息,提示出错。未将对象引用设置到对象的实例 ``` ![图片说明](https://img-ask.csdn.net/upload/201712/05/1512440456_874167.png) ``` ``` ``` ```
C#依据硬件传上来的数据 位图显示问题
![![图片说明](https://img-ask.csdn.net/upload/201610/31/1477879610_274745.png)图片说明](https://img-ask.csdn.net/upload/201610/31/1477879603_45251.png) private void RX_thread() { int buffersize = _SerialPort.BytesToRead; //十六进制数的大小 byte[] buffer = new Byte[buffersize]; //创建缓冲区 _SerialPort.Read(buffer, 0, buffersize); //将数读到buffer里,来创建一个缓冲区; if (RX_HEX_checkBox.Checked) { RXbox.AppendText(HEX_To_String(buffer)); //将数据放在一个textbox 里,进行显示; } else { try { //int itemp = int.Parse(HEX_To_ASCII(buffer)); //ltBuffer.Add(); RXbox.AppendText(HEX_To_ASCII(buffer)); //蛋疼的处理richtextbox //richtextbox中\n \r两者都是换行 //if ((buffer[0] == 0x0A) && (flagRN)) { } else { flagRN = false; } //if (buffer[buffer.Length - 1] == 0x0D) { flagRN = true; } } catch { } } //if (scroll_checkBox.Checked) //{ // //RXbox.AutoScrollOffset // //RXbox.view // //RXbox_Scroll.Maximum = RXbox.ViewportHeight; //} RXL = RXL + buffer.Length; toolStripStatusLabel_R.Text = RXL.ToString(); //MessageBox.Show(RXbox.Text); //if(ltBuffer.Count == 641) //{ // MessageBox.Show("1"); // if (ltBuffer[640] == "T") // { // ltBuffer.Clear(); // } //} //一下代码就是对位图进行一行行处理 // if (ltBuffer.Count == 640) if (ltBuffer.Count > 640) { //draw Bitmap b = new Bitmap(16, 40); MemoryStream m = new MemoryStream(); //缓冲区? //锁定位图 BitmapData bbb = b.LockBits(new System.Drawing.Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); IntPtr ptr = bbb.Scan0; //找到位图首地址 byte[] byteData = new byte[b.Width * b.Height * 3];//存放位图 System.Runtime.InteropServices.Marshal.Copy(ptr, byteData, 0, b.Width * b.Height * 3); //给RGB赋值 //核心代码,循环处理位图 for (int i = 16 * 40 - 1; i >= 0; i--) { double dscal; if (double.Parse(ltBuffer[16 * 40 - 1 - i]) > 145) { Console.WriteLine("I de 值:" + i+" "+ltBuffer); dscal = 1; } else { if (double.Parse(ltBuffer[16 * 40 - 1 - i]) < 16) { dscal = 0; } else { dscal = (double.Parse(ltBuffer[16 * 40 - 1 - i]) - 16) / 255.0; } } if (dscal > 1) { dscal = 1; } byteData[i * 3 + 0] = (byte)(255 * dscal);//B byteData[i * 3 + 1] = (byte)(255 * dscal);//G byteData[i * 3 + 2] = (byte)(255 * dscal);//R } // if (ltBuffer.Count == 689) // // if (ltBuffer.Count > 688) // { // //draw // Bitmap b = new Bitmap(16, 43); // MemoryStream m = new MemoryStream(); //缓冲区? // //锁定位图 // BitmapData bbb = b.LockBits(new System.Drawing.Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // IntPtr ptr = bbb.Scan0; //找到位图首地址 // byte[] byteData = new byte[b.Width * b.Height * 3];//存放位图 // System.Runtime.InteropServices.Marshal.Copy(ptr, byteData, 0, b.Width * b.Height*3); //给RGB赋值 // //核心代码,循环处理位图 // for (int i = b.Width*b.Height - 1; i >= 0; i--) // { // double dscal; // if (double.Parse(ltBuffer[b.Width * b.Height - 1 - i]) > 156)//修改一处: // { // dscal = 1; // } // else // { // if (double.Parse(ltBuffer[b.Width * b.Height - 1 - i]) < 17) // { // dscal = 0; // } // else // { // dscal = (double.Parse(ltBuffer[b.Width * b.Height - 1 - i]) - 17) / 255.0; // } // } // // if (dscal > 1) // { // dscal = 1; // } // // byteData[i * 3 + 0] = (byte)(255-255 * dscal);//B // byteData[i * 3 + 1] = (byte)(255-255 * dscal);//G // byteData[i * 3 + 2] = (byte)(255-255 * dscal);//R // } //放回位图 System.Runtime.InteropServices.Marshal.Copy(byteData, 0, ptr, b.Width * b.Height * 3); //释放位图 b.UnlockBits(bbb); //保存位图 b.Save(m, ImageFormat.Bmp); //以下代码,进行位图的显示操作 Image bba = Image.FromStream(m); ImageAttributes im = new ImageAttributes(); Graphics g = Graphics.FromImage(bba); this.pictureBox1.Image = bba; g.DrawImage(bba, new Point(20, 20)); ltBuffer.Clear(); } else if(ltBuffer.Count > 640)// // if(ltBuffer.Count > 688) { // MessageBox.Show(ltBuffer.Count.ToString()); ltBuffer.Clear(); } }
C#,用串口读缓存文件时只读了一小部分,没有读完整。求大佬帮忙。
如题,原文件很大,50多万个字符吧。不知道是不是太大影响的 以下是代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; namespace 串口实验2 { public partial class Form1 : Form { string s = ""; string ss = ""; string[] s_1; int i=0; SerialPort serialPort1 = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); //初始化串口设置 public delegate void Displaydelegate(byte[] InputBuf); // Byte[] OutputBuf = new Byte[128]; public Displaydelegate disp_delegate; public Form1() { disp_delegate = new Displaydelegate(DispUI); serialPort1.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived); InitializeComponent(); this.BackgroundImage = Image.FromFile(@"C:\Users\hasee\Desktop\plane.jpg"); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { try { if (button1.Text == "打开") { serialPort1.Open(); button1.Text = "关闭"; } else { serialPort1.Close(); button1.Text = "打开"; } } catch (Exception ex) { MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e) { int count = serialPort1.BytesToRead; Byte[] InputBuf = new Byte[count]; try { serialPort1.Read(InputBuf, 0, serialPort1.BytesToRead); //读取缓冲区的数据直到“}”即0x7D为结束符 System.Threading.Thread.Sleep(50); this.Invoke(disp_delegate, InputBuf); } catch (TimeoutException ex) //超时处理 { MessageBox.Show(ex.ToString()); } } public void DispUI(byte[] InputBuf) { ASCIIEncoding encoding = new ASCIIEncoding(); s= encoding.GetString(InputBuf); ss = s.Replace(@"\r\nNNNN", "a"); s_1=ss.Split(new char[] { 'a' }); // TextBox1.Text = ss;// encoding.GetString(InputBuf); } private void timer1_Tick(object sender, EventArgs e) { //TextBox1.Text = s_1[i]; TextBox1.Text = s_1.Length.ToString(); i = i + 1; } private void button2_Click(object sender, EventArgs e) { timer1.Enabled = true; timer1.Interval = 10; } } }
STM32 串口接收指令无反应。
C#上位机通过串口给STM32发送指令,结果发现发送指令下位机偶尔有反应,大多数情况下没反应,只有多次点击有时会返回一次数据。代码如下 ``` 上位机发送部分 char[] a = new char[1];//设置标志位 a[0] = 'a'; serialPort1.Write(a, 0, 1); ``` STM32处理部分: ``` while(1) { if(USART_GetITStatus(USART1,USART_IT_RXNE)!=Bit_RESET) { UART_data=USART_ReceiveData(USART1);//接收串口数据 if(UART_data=='a')//进行判断 { USART_SendData(USART1,a);//a为之前定义的一个变量 b也是 } if(UART_data=='b') { USART_SendData(USART1,b); } while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==Bit_RESET); } } ```
串口和串口轉usb的區別
圖一: ![知道串口轉usb](https://img-ask.csdn.net/upload/201811/22/1542851006_844269.png) 圖二: ![這是串口的](https://img-ask.csdn.net/upload/201811/22/1542851037_642924.png) # **提問:圖一圖二可不可以都用下面的代碼獲取數據:(圖二可以用下面的代碼獲取數據,但是圖一不知道行不行,請各位大佬路過看看)** ``` package com.lyf.test2; import java.awt.Button; import java.awt.Color; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.Label; import java.awt.Toolkit; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JOptionPane; import com.lyf.test2.SerialTool; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import serialException.ExceptionWriter; import serialException.NoSuchPort; import serialException.NotASerialPort; import serialException.PortInUse; import serialException.ReadDataFromSerialPortFailure; import serialException.SendDataToSerialPortFailure; import serialException.SerialPortInputStreamCloseFailure; import serialException.SerialPortOutputStreamCloseFailure; import serialException.SerialPortParameterFailure; import serialException.TooManyListeners; /** * 主程序 * @author zhong * */ public class Client extends Frame{ private static final long serialVersionUID = 1L; /** * 程序界面宽度 */ public static final int WIDTH = 800; /** * 程序界面高度 */ public static final int HEIGHT = 620; /** * 程序界面出现位置(横坐标) */ public static final int LOC_X = 200; /** * 程序界面出现位置(纵坐标) */ public static final int LOC_Y = 70; private static SerialPort serialPort = null; //保存串口对象 private Font font = new Font("微软雅黑", Font.BOLD, 25);//文本框字體 private Label weight = new Label("暫無數據", Label.CENTER); //重量 private Button saveButton = new Button("保存");//设置button按钮 Image offScreen = null; //用于双缓冲 //设置window的icon(这里我自定义了一下Windows窗口的icon图标,因为实在觉得哪个小咖啡图标不好看 = =) Toolkit toolKit = getToolkit();//返回此窗体的工具包 Image icon = toolKit.getImage(Client.class.getResource("computer.png"));//獲取當前類所在的包下面的圖片 /** * 主方法 * @param args * @throws SerialPortOutputStreamCloseFailure * @throws SendDataToSerialPortFailure * @throws PortInUse * @throws NoSuchPort * @throws NotASerialPort * @throws SerialPortParameterFailure */ public static void main(String[] args) throws SendDataToSerialPortFailure, SerialPortOutputStreamCloseFailure, SerialPortParameterFailure, NotASerialPort, NoSuchPort, PortInUse { new Client().launchFrame(); } /** * 主菜单窗口显示; * 添加Label、按钮、下拉条及相关事件监听; */ public void launchFrame() { this.setBounds(LOC_X, LOC_Y, WIDTH, HEIGHT); this.setTitle("CDIO工程项目"); this.setIconImage(icon); this.setBackground(Color.white); this.setLayout(null); //改變按鈕的事件监听 this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent arg0) { if (serialPort != null) { //程序退出时关闭串口释放资源 SerialTool.closePort(serialPort); } System.exit(0); } }); //设置文本框位置、背景颜色、是否粗体、字体颜色 weight.setBounds(140, 103, 225, 50); weight.setBackground(Color.black); weight.setFont(font); weight.setForeground(Color.white); add(weight); //添加保存按钮 saveButton.setBounds(250, 490, 300, 50); saveButton.setBackground(Color.lightGray); saveButton.setFont(new Font("微软雅黑", Font.BOLD, 20)); saveButton.setForeground(Color.darkGray); add(saveButton); //添加打开串口按钮的事件监听 try { //指定端口名及波特率的串口对象 serialPort = SerialTool.openPort("COM1", 4800); //在该串口对象上添加监听器 SerialTool.addListener(serialPort, new SerialListener()); } catch (SerialPortParameterFailure | NotASerialPort | NoSuchPort | PortInUse | TooManyListeners e1) { //发生错误时使用一个Dialog提示具体的错误信息 JOptionPane.showMessageDialog(null, e1, "错误", JOptionPane.INFORMATION_MESSAGE); } this.setResizable(false);//设置此框架是否可由用户调整大小。 this.setVisible(true); //显示窗口 new Thread(new RepaintThread()).start(); //启动重画线程 } /** * 画出主界面组件元素 * 设置button的字体颜色、设置字体样式 是否粗体 字体大小、文本、位置 */ public void paint(Graphics g) { g.setColor(Color.black); g.setFont(new Font("微软雅黑", Font.BOLD, 25)); g.drawString(" 重量: ", 45, 130); } /** * 双缓冲方式重画界面各元素组件 */ public void update(Graphics g) { if (offScreen == null) offScreen = this.createImage(WIDTH, HEIGHT); Graphics gOffScreen = offScreen.getGraphics(); Color c = gOffScreen.getColor(); gOffScreen.setColor(Color.white); gOffScreen.fillRect(0, 0, WIDTH, HEIGHT); //重画背景画布 this.paint(gOffScreen); //重画界面元素 gOffScreen.setColor(c); g.drawImage(offScreen, 0, 0, null); //将新画好的画布“贴”在原画布上 } /** * 以内部类形式创建一个串口监听类 * @author zhong * */ private class SerialListener implements SerialPortEventListener { /** * 处理监控到的串口事件 */ public void serialEvent(SerialPortEvent serialPortEvent) { try { // 等待1秒钟让串口把数据全部接收后在处理 Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } switch (serialPortEvent.getEventType()) { case SerialPortEvent.BI: // 10 通讯中断 JOptionPane.showMessageDialog(null, "与串口设备通讯中断", "错误", JOptionPane.INFORMATION_MESSAGE); break; case SerialPortEvent.OE: // 7 溢位(溢出)错误 case SerialPortEvent.FE: // 9 帧错误 case SerialPortEvent.PE: // 8 奇偶校验错误 case SerialPortEvent.CD: // 6 载波检测 case SerialPortEvent.CTS: // 3 清除待发送数据 case SerialPortEvent.DSR: // 4 待发送数据准备好了 case SerialPortEvent.RI: // 5 振铃指示 case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空 break; case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据 byte[] data = null; try { if (serialPort == null) {//判断串口对象是否为空 JOptionPane.showMessageDialog(null, "串口对象为空!监听失败!", "错误", JOptionPane.INFORMATION_MESSAGE); }else { data = SerialTool.readFromPort(serialPort); //读取数据,存入字节数组 //System.out.println(new String(data)); //自定义解析过程 if (data != null && data.length > 1) { //检查数据是否读取正确 try { weight.setText(new String(data) + " g"); } catch (ArrayIndexOutOfBoundsException e) { JOptionPane.showMessageDialog(null, "数据解析过程出错,更新界面数据失败!请检查设备或程序!", "错误", JOptionPane.INFORMATION_MESSAGE); System.exit(0); } }else { JOptionPane.showMessageDialog(null, "读取数据过程中未获取到有效数据!请检查设备或程序!", "错误", JOptionPane.INFORMATION_MESSAGE); System.exit(0); } } } catch (ReadDataFromSerialPortFailure | SerialPortInputStreamCloseFailure e) { JOptionPane.showMessageDialog(null, e, "错误", JOptionPane.INFORMATION_MESSAGE); System.exit(0); //发生读取错误时显示错误信息后退出系统 } break; } } } /** * 重画线程(每隔30毫秒重画一次) */ private class RepaintThread implements Runnable { public void run() { while(true) { //调用重画方法 repaint(); try { Thread.sleep(30); } catch (InterruptedException e) { String err = ExceptionWriter.getErrorInfoFromException(e); JOptionPane.showMessageDialog(null, err, "错误", JOptionPane.INFORMATION_MESSAGE); System.exit(0); } } } } } ``` ``` package com.lyf.test2; import java.io.IOException; import java.io.InputStream; import java.util.TooManyListenersException; import gnu.io.CommPort; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.SerialPortEventListener; import gnu.io.UnsupportedCommOperationException; import serialException.*; /** * 串口服务类,提供打开、关闭串口,读取、发送串口数据等服务(采用单例设计模式) * @author zhong * */ public class SerialTool { private static SerialTool serialTool = null; static { //在该类被ClassLoader加载时就初始化一个SerialTool对象 if (serialTool == null) { serialTool = new SerialTool(); } } //私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象 private SerialTool() {} /** * 获取提供服务的SerialTool对象 * @return serialTool */ public static SerialTool getSerialTool() { if (serialTool == null) { serialTool = new SerialTool(); } return serialTool; } /** * 打开串口 * @param portName 端口名称 * @param baudrate 波特率 * @return 串口对象 * @throws SerialPortParameterFailure 设置串口参数失败 * @throws NotASerialPort 端口指向设备不是串口类型 * @throws NoSuchPort 没有该端口对应的串口设备 * @throws PortInUse 端口已被占用 */ public static final SerialPort openPort(String portName, int baudrate) throws SerialPortParameterFailure, NotASerialPort, NoSuchPort, PortInUse { try { //通过端口名识别端口 CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); //打开端口,并给端口名字和一个timeout(打开操作的超时时间) CommPort commPort = portIdentifier.open(portName, 2000); //判断是不是串口 if (commPort instanceof SerialPort) { SerialPort serialPort = (SerialPort) commPort; try { //设置一下串口的波特率等参数 serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } catch (UnsupportedCommOperationException e) { throw new SerialPortParameterFailure(); } //System.out.println("Open " + portName + " sucessfully !"); return serialPort; } else { //不是串口 throw new NotASerialPort(); } } catch (NoSuchPortException e1) { throw new NoSuchPort(); } catch (PortInUseException e2) { throw new PortInUse(); } } /** * 关闭串口 * @param serialport 待关闭的串口对象 */ public static void closePort(SerialPort serialPort) { if (serialPort != null) { serialPort.close(); serialPort = null; } } /** * 从串口读取数据 * @param serialPort 当前已建立连接的SerialPort对象 * @return 读取到的数据 * @throws ReadDataFromSerialPortFailure 从串口读取数据时出错 * @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错 */ public static byte[] readFromPort(SerialPort serialPort) throws ReadDataFromSerialPortFailure, SerialPortInputStreamCloseFailure { InputStream in = null; byte[] bytes = null; try { in = serialPort.getInputStream();//取入数据 int bufflenth = in.available(); //获取buffer里的数据长度 while (bufflenth != 0) { bytes = new byte[bufflenth]; //初始化byte数组为buffer中数据的长度 in.read(bytes); bufflenth = in.available(); } } catch (IOException e) { throw new ReadDataFromSerialPortFailure(); } finally { try { if (in != null) { in.close(); in = null; } } catch(IOException e) { throw new SerialPortInputStreamCloseFailure(); } } return bytes; } /** * 添加监听器 * @param port 串口对象 * @param listener 串口监听器 * @throws TooManyListeners 监听类对象过多 */ public static void addListener(SerialPort port, SerialPortEventListener listener) throws TooManyListeners { try { //给串口添加监听器 port.addEventListener(listener); //设置当有数据到达时唤醒监听接收线程 port.notifyOnDataAvailable(true); //设置当通信中断时唤醒中断线程 port.notifyOnBreakInterrupt(true); } catch (TooManyListenersException e) { throw new TooManyListeners(); } } } ```
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 free -m 其中:m表示兆,也可以用g,注意都要小写 Men:表示物理内存统计 total:表示物理内存总数(total=used+free) use...
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入 假设现有4个人...
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发...
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 演示地点演示 html代码如下` music 这个年纪 七月的风 音乐 ` 然后就是css`*{ margin: 0; padding: 0; text-decoration: none; list-...
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。
数据库优化 - SQL优化
以实际SQL入手,带你一步一步走上SQL优化之路!
通俗易懂地给女朋友讲:线程池的内部原理
餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”
经典算法(5)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
使用 Docker 部署 Spring Boot 项目
Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下。首先构建一个简单的 S...
英特尔不为人知的 B 面
从 PC 时代至今,众人只知在 CPU、GPU、XPU、制程、工艺等战场中,英特尔在与同行硬件芯片制造商们的竞争中杀出重围,且在不断的成长进化中,成为全球知名的半导体公司。殊不知,在「刚硬」的背后,英特尔「柔性」的软件早已经做到了全方位的支持与支撑,并持续发挥独特的生态价值,推动产业合作共赢。 而对于这一不知人知的 B 面,很多人将其称之为英特尔隐形的翅膀,虽低调,但是影响力却不容小觑。 那么,在...
面试官:你连RESTful都不知道我怎么敢要你?
干货,2019 RESTful最贱实践
刷了几千道算法题,这些我私藏的刷题网站都在这里了!
遥想当年,机缘巧合入了 ACM 的坑,周边巨擘林立,从此过上了"天天被虐似死狗"的生活… 然而我是谁,我可是死狗中的战斗鸡,智力不够那刷题来凑,开始了夜以继日哼哧哼哧刷题的日子,从此"读题与提交齐飞, AC 与 WA 一色 ",我惊喜的发现被题虐既刺激又有快感,那一刻我泪流满面。这么好的事儿作为一个正直的人绝不能自己独享,经过激烈的颅内斗争,我决定把我私藏的十几个 T 的,阿不,十几个刷题网...
白话阿里巴巴Java开发手册高级篇
不久前,阿里巴巴发布了《阿里巴巴Java开发手册》,总结了阿里巴巴内部实际项目开发过程中开发人员应该遵守的研发流程规范,这些流程规范在一定程度上能够保证最终的项目交付质量,通过在时间中总结模式,并推广给广大开发人员,来避免研发人员在实践中容易犯的错误,确保最终在大规模协作的项目中达成既定目标。 无独有偶,笔者去年在公司里负责升级和制定研发流程、设计模板、设计标准、代码标准等规范,并在实际工作中进行...
SQL-小白最佳入门sql查询一
不要偷偷的查询我的个人资料,即使你再喜欢我,也不要这样,真的不好;
redis分布式锁,面试官请随便问,我都会
文章有点长并且绕,先来个图片缓冲下! 前言 现在的业务场景越来越复杂,使用的架构也就越来越复杂,分布式、高并发已经是业务要求的常态。像腾讯系的不少服务,还有CDN优化、异地多备份等处理。 说到分布式,就必然涉及到分布式锁的概念,如何保证不同机器不同线程的分布式锁同步呢? 实现要点 互斥性,同一时刻,智能有一个客户端持有锁。 防止死锁发生,如果持有锁的客户端崩溃没有主动释放锁,也要保证锁可以正常释...
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
Nginx 原理和架构
Nginx 是一个免费的,开源的,高性能的 HTTP 服务器和反向代理,以及 IMAP / POP3 代理服务器。Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。 Nginx 的整体架构 Nginx 里有一个 master 进程和多个 worker 进程。master 进程并不处理网络请求,主要负责调度工作进程:加载配置、启动工作进程及非停升级。worker 进程负责处...
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
程序员:我终于知道post和get的区别
是一个老生常谈的话题,然而随着不断的学习,对于以前的认识有很多误区,所以还是需要不断地总结的,学而时习之,不亦说乎
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU...
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1...
Java世界最常用的工具类库
Apache Commons Apache Commons有很多子项目 Google Guava 参考博客
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员...
网易云6亿用户音乐推荐算法
网易云音乐是音乐爱好者的集聚地,云音乐推荐系统致力于通过 AI 算法的落地,实现用户千人千面的个性化推荐,为用户带来不一样的听歌体验。 本次分享重点介绍 AI 算法在音乐推荐中的应用实践,以及在算法落地过程中遇到的挑战和解决方案。 将从如下两个部分展开: AI算法在音乐推荐中的应用 音乐场景下的 AI 思考 从 2013 年 4 月正式上线至今,网易云音乐平台持续提供着:乐屏社区、UGC...
【技巧总结】位运算装逼指南
位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。 判断奇偶数 判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下...
为什么要学数据结构?
一、前言 在可视化化程序设计的今天,借助于集成开发环境可以很快地生成程序,程序设计不再是计算机专业人员的专利。很多人认为,只要掌握几种开发工具就可以成为编程高手,其实,这是一种误解。要想成为一个专业的开发人员,至少需要以下三个条件: 1) 能够熟练地选择和设计各种数据结构和算法 2) 至少要能够熟练地掌握一门程序设计语言 3) 熟知所涉及的相关应用领域的知识 其中,后两个条件比较容易实现,而第一个...
Android 9.0 init 启动流程
阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android本篇文章主要介绍Android开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:一、启动流程概述一、 启动流程概述Android启动流程跟Linux启动类似,大致分为如下五个阶段。1.开机上电,加载固化的ROM。2.加载BootLoader,拉起Android OS。3.加载Uboot,初始外设,引导Kernel启动等。...
8年经验面试官详解 Java 面试秘诀
作者 |胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。 Java程序员准备和投递简历的实...
面试官如何考察你的思维方式?
1.两种思维方式在求职面试中,经常会考察这种问题:北京有多少量特斯拉汽车?某胡同口的煎饼摊一年能卖出多少个煎饼?深圳有多少个产品经理?一辆公交车里能装下多少个乒乓球?一个正常成年人有多少根头发?这类估算问题,被称为费米问题,是以科学家费米命名的。为什么面试会问这种问题呢?这类问题能把两类人清楚地区分出来。一类是具有文科思维的人,擅长赞叹和模糊想象,它主要依靠的是人的第一反应和直觉,比如小孩...
前后端分离,我怎么就选择了 Spring Boot + Vue 技术栈?
前两天又有小伙伴私信松哥,问题还是职业规划,Java 技术栈路线这种,实际上对于这一类问题我经常不太敢回答,每个人的情况都不太一样,而小伙伴也很少详细介绍自己的情况,大都是一两句话就把问题抛出来了,啥情况都不了解,就要指出一个方向,这实在是太难了。 因此今天我想从我学习 Spring Boot + Vue 这套技术栈的角度,来和大家聊一聊没有人指导,我是如何一步一步建立起自己的技术体系的。 线上大...
17张图带你解析红黑树的原理!保证你能看懂!
二叉查找树 由于红黑树本质上就是一棵二叉查找树,所以在了解红黑树之前,咱们先来看下二叉查找树。 二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树: 若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若任意结点的...
so easy! 10行代码写个"狗屁不通"文章生成器
前几天,GitHub 有个开源项目特别火,只要输入标题就可以生成一篇长长的文章。 背后实现代码一定很复杂吧,里面一定有很多高深莫测的机器学习等复杂算法 不过,当我看了源代码之后 这程序不到50行 尽管我有多年的Python经验,但我竟然一时也没有看懂 当然啦,原作者也说了,这个代码也是在无聊中诞生的,平时撸码是不写中文变量名的, 中文...
知乎高赞:中国有什么拿得出手的开源软件产品?(整理自本人原创回答)
知乎高赞:中国有什么拿得出手的开源软件产品? 在知乎上,有个问题问“中国有什么拿得出手的开源软件产品(在 GitHub 等社区受欢迎度较好的)?” 事实上,还不少呢~ 本人于2019.7.6进行了较为全面的回答,对这些受欢迎的 Github 开源项目分类整理如下: 分布式计算、云平台相关工具类 1.SkyWalking,作者吴晟、刘浩杨 等等 仓库地址: apache/skywalking 更...
MySQL数据库总结
一、数据库简介 数据库(Database,DB)是按照数据结构来组织,存储和管理数据的仓库。 典型特征:数据的结构化、数据间的共享、减少数据的冗余度,数据的独立性。 关系型数据库:使用关系模型把数据组织到数据表(table)中。现实世界可以用数据来描述。 主流的关系型数据库产品:Oracle(Oracle)、DB2(IBM)、SQL Server(MS)、MySQL(Oracle)。 数据表:数...
相关热词 c# 二进制截断字符串 c#实现窗体设计器 c#检测是否为微信 c# plc s1200 c#里氏转换原则 c# 主界面 c# do loop c#存为组套 模板 c# 停掉协程 c# rgb 读取图片
立即提问