单片机通过串口发送12位的十六进制数据,先发高4位,后发低8位,用C#做了一个串口,用于接收数据

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-06-16
C# 串口通信 高低字节合并是怎么回事啊

一般情况下单片机有8位单片,16位单片以及32位单片机。一般情况下对于8位单片的比较多,比如51单片机。所谓的8位单片,就是因单片机系中最大的寄存器为8位,当其想表示一个16bits的数时,必须发送过来两个数字,就是把16bits的数分成两个8bits时向上位机发送,换句话来说,你的8位单片机,每次只能给你发一个8bits的字节,而它要表示一个数据必须使用16bits编码时,其实需要两次发送,也就是你所说的两个字节。

但事实你必须要知道的是这两个字节是不可分的,只有这两个8bits才能表示一个完整意义。而计算机对于16bits,32bits等处理是绰绰有余的,所以计算在接收这两个数字之间必须将其合并成一个,当然单片机也有发送顺序,先发送高位,再发送低位。这时你需要将这两个得新组合。

定义一个smallint类型,接收第一个字节,并将其向左移8位,实际上是乘256也是一样的,但可能会溢出。然后再通过字节的OR操作与后一个字节,和出的结果就是合并后的结果。


从原理与算法上我感觉你应该明白高低字节合并,和为什么会出现高低字节合并了!

串口主要有以下几个参数:
1.串口名称(PortName)
2.波特率(BaudRate)
3.数据位(DataBits)
4.奇偶效应(Parity)
5.停止位(StopBits)

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Data;
8 using System.Windows.Documents;
9 using System.Windows.Input;
10 using System.Windows.Media;
11 using System.Windows.Media.Imaging;
12 using System.Windows.Navigation;
13 using System.Windows.Shapes;
14 using System.IO.Ports;
15
16 namespace CsharpComm
17 {
18 ///
19 /// Window1.xaml 的交互逻辑
20 ///
21 public partial class Window1 : Window
22 {
23 public Window1()
24 {
25 InitializeComponent();
26 }
27
28 //定义 SerialPort对象
29 SerialPort port1;
30
31 //初始化SerialPort对象方法.PortName为COM口名称,例如"COM1","COM2"等,注意是string类型
32 public void InitCOM(string PortName)
33 {
34 port1 = new SerialPort(PortName);
35 port1.BaudRate = 9600;//波特率
36 port1.Parity = Parity.None;//无奇偶校验位
37 port1.StopBits = StopBits.Two;//两个停止位
38 port1.Handshake = Handshake.RequestToSend;//控制协议
39 port1.ReceivedBytesThreshold = 4;//设置 DataReceived 事件发生前内部输入缓冲区中的字节数
40 port1.DataReceived += new SerialDataReceivedEventHandler(port1_DataReceived);//DataReceived事件委托
41 }
42
43 //DataReceived事件委托方法
44 private void port1_DataReceived(object sender, SerialDataReceivedEventArgs e)
45 {
46 try
47 {
48 StringBuilder currentline = new StringBuilder();
49 //循环接收数据
50 while (port1.BytesToRead > 0)
51 {
52 char ch = (char)port1.ReadByte();
53 currentline.Append(ch);
54 }
55 //在这里对接收到的数据进行处理
56 //
57 currentline = new StringBuilder();
58 }
59 catch(Exception ex)
60 {
61 Console.WriteLine(ex.Message.ToString());
62 }
63
64 }
65
66 //打开串口的方法
67 public void OpenPort()
68 {
69 try
70 {
71 port1.Open();
72 }
73 catch { }
74 if (port1.IsOpen)
75 {
76 Console.WriteLine("the port is opened!");
77 }
78 else
79 {
80 Console.WriteLine("failure to open the port!");
81 }
82 }
83
84 //关闭串口的方法
85 public void ClosePort()
86 {
87 port1.Close();
88 if (!port1.IsOpen)
89 {
90 Console.WriteLine("the port is already closed!");
91 }
92 }
93
94 //向串口发送数据
95 public void SendCommand(string CommandString)
96 {
97 byte[] WriteBuffer = Encoding.ASCII.GetBytes(CommandString);
98 port1.Write(WriteBuffer, 0, WriteBuffer.Length);
99 }
100
101 //调用实例
102 private void btnOpen_Click(object sender, RoutedEventArgs e)
103 {
104 //我现在用的COM1端口,按需要可改成COM2,COM3
105 InitCOM("COM1");
106 OpenPort();
107 }
108 }
109 }


最后推荐你再看一下这篇文章,应该会很有帮助
http://scorpiomiracle.javaeye.com/blog/653923

发送:
int ii;
char i;
ii=data;//待发送数据
i=ii>>8;//取高8位
i&=0x0f;//取高4位
putchar(i);//发送高4位
i=ii&0xff;//取低8位
putchar(i);//发送低8r
接收:
int ii;
char i;
i=getchar();//收到高4位
ii=i;
ii<<=8;//ii左移8位
i=getchar();
ii+=i;// 得到12位数据

  • 与单片机间的串口通信,如何能发送与接收16位的数据
    答:当然不能一次就发16位数据的,要把16位数据分成两个字节,即高8位和低8位。发送时,可先发低8位,后发高8位。接收时,也按这个顺序接收,再组合恢复成16位数就行了。如果先发高8位,后发低8位也行,只要发送/接收要统一先后顺序就可以,就能接收到正确的16位数据了。
  • 单片机串口发送16进制程序
    答:不用16进制那就是字符,电脑发送和单片机接收都是该字符的asii码 字符1的asii码=16进制的31,即0x31
  • 我想利用单片机通过串口发送几个16进制数FF 10 11 01 DD 求高手指点...
    答:单片机通过串口发送几个16进制数FF 10 11 01 DD,程序如下:void Send(unsigned char Tx_Data)//向串口发字符 { SBUF=Tx_Data;while(!TI);TI=0;} main(){ 先串口初始化,然后:Send(0xFF);Send(0x10);Send(0x11);Send(0x01);Send(0xDD);即可。} ...
  • java串口怎么给温控器发送16进制数
    答:做串口通讯的时候基本都是通过io流读取、输出。那么在java开发中发送数据的时候使用OutputStream,而其write()的参数是字节数组、int整形。如果使用字节数组发送的时候,通常可以直接写成out.write("1234".getBytes())。这样一来单片机读到的数据则是31 32 33 34。但是在串口发送的时候先把16进制字符串...
  • 单片机通过串口发送一个16位数
    答:单片机通过串口发送一个16位数只能分两次发送,因为sbuff只是一个八位寄存器,只能装八位数据;单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动...
  • 每按一次单片机上的按键,把一个16进制的数据发送到串口利用串口调试助 ...
    答:ORG 0000H SJMP STA ORG 0023H LJMP SERINT ORG 0030H STA:MOV SP,#6FH SETB ES SETB EA LOOP:JB KEY,LOOP LCALL DELAY JB KEY,LOOP MOV SBUF,#DAT LCALL SEND SJMP LOOP DELAY:MOV R0,#10 D1:MOV R1,#200 DJNZ R1,DJNZ R0,D1 RET ;---串口中断程序--- SERINT:JBC RI,R_DA...
  • 易语言 单片机串口通讯问题 我做了个串口通讯软件,发现只能传输ASCII数...
    答:在串口输入数据加一段ASCII转HEX的程序,ASCII转HEX的程序很多。
  • 单片机怎样通过串口向计算机发送数据
    答:单片机怎样通过串口向计算机发送数据:单片机可以实现与计算机的发送和接收。首先,要正确配置单片机的串口,包括波特率、使用时钟源、COM口、数据位位数、奇偶校验位、停止位位数等,同时要保证计算机的配置和单片机的一致。然后,把要发送的数据送到发送缓存,只能一个字节一个字节的发送。启动单片机发送,就...
  • 单片机串口调试问题
    答:用串口调试助手的话,有一个“十六进制接收”和“十六进制发送”的选项,你打上勾,就可以看到你用“a = 9”发送的十六进制数9了,否则串口调试助手会按ASC码来显示,0x9的ASC码是显示不出来任何东西的。你用“a='9'”发送的十六进制数是0x39,串口调试助手按ASC码来显示就是数字符号9。。
  • 我用51串口接收数据 发送一位四位数 例如2400怎么将 24 和00分别读出来...
    答:51单片机每次只能接受8位或者9位二进制数;一般方便都是8位二进制的。像你是想把十进制数2400发到单片机去,转换成16 进制是0x960;总共是12位二进制 了。上位机要分两次发送。例如先把高位发送到单片机0x09; 然后再发送0x60; 单片机接收后,每次上位机发送 你就从串口接收寄存器读出保存,然后处理一...