夸克之书

  • 首页
  • 科普
  • 笔记
  • .NET/C#
  • 物联网
  • 算法
  • Linux
  • 树莓派
夸克之内,别有洞天
  1. 首页
  2. 树莓派
  3. 正文

树莓派.Net Core Iot入门系列篇(4):UART串口通信

2019-09-24 5879点热度 0人点赞 0条评论

前言

和上一篇中的I2C一样,UART也是一种非常常见通信方式。UART全称为通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)。UART用于异步通信,该总线双向通信,可以实现全双工传输和接收。在嵌入式设计中,UART用于主机与辅助设备通信,如汽车音响与外接AP之间的通信,与PC机通信包括与监控调试器和其它器件,如EEPROM通信。

树莓派串口配置

从树莓派3代开始,树莓派默认将 ttyAMA0 分配给了蓝牙,直接导致了没法使用GPIO硬件串口,而GPIO硬件串口的性能优势是没办法替代的。所以我们的先把硬件串口空出来,留给编写的程序使用。当然,鱼与熊掌不可兼得,开启硬件串口后,蓝牙将无法使用。

(1)激活串口功能

sudo nano /boot/config.txt

修改参数:enable_uart=1。 若无此参数,则在最后一行添加:enable_uart=1

然后重启。

此时查看串口设备是这样的。

ls -l /dev/ser*

结果如下:

lrwxrwxrwx 1 root root 7 Aug 28 07:41 serial0 -> ttyS0 lrwxrwxrwx 1 root root 5 Aug 28 07:41 serial1 -> ttyAMA0

(2)禁用串口控制台功能

sudo raspi-config

选择Interfacing Options->P6 Serial,按照提示关闭串口

Would you like a login shell to be accessible over serial? --No Would you like the serial port hardware to be enabled? --Yes

退出,然后重启。

(3)交换串口

sudo nano /boot/config.txt

在最下面添加:dtoverlay=pi3-miniuart-bt 保存并重启。 此时查看串口别名则发现:

lrwxrwxrwx 1 root root 7 Aug 28 07:41 serial0 -> ttyAMA0 lrwxrwxrwx 1 root root 5 Aug 28 07:41 serial1 -> ttyS0

此时,ttyAMA0串口可以正常用于串口通信,ttyS0则无法被用于串口通信,蓝牙功能失效。

硬件连接

我用了一对无线串口透传模块,一个连接在电脑上面,一个连接在树莓派上面(相当于无线串口调试器)来进行调试。

%title插图%num

在树莓派上面,RX(GPIO15)接调试模块TX,TX(GPIO14)接调试模块RX。

%title插图%num
接线示例
%title插图%num
树莓派GPIO

编写程序

C#操作串口需要用到类库System.IO.Ports,创建好控制台应用程序后,通过Nuget添加引用即可。通过System.IO.Ports编写少量代码就能完成串口信息的收发。

在串口控制台应用当中,我们要用到SerialPort类,此类中封装了大量的串口通信相关的方法。一般来说,用到的无非就是读和写操作的相关方法。下面直接贴上示例代码,接收数据通过DataReceived事件,避免了建立一个线程来专门读取数据。

class Program
{
    /// <summary>
    /// 树莓派串口操作,也可以用于Windows系统(COMx)
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
        {
            //注册退出事件
            Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs eventArgs) => { };

            string portName = "ttyAMA0";
            try
            {
                //查询系统中支持的串口列表
                var ports = SerialPort.GetPortNames();
                bool isTTY = false;
                if (ports.Length == 0)
                {
                    Console.WriteLine($"No serial port allow to use!");
                    return;
                }
                Console.WriteLine("Serial List:");
                foreach (var prt in ports)
                {
                    Console.WriteLine($"  {prt}");
                    if (prt.Contains(portName))
                        isTTY = true;
                }
                if (!isTTY)
                {
                    Console.WriteLine($"No {portName} serial port!");
                    return;
                }
                //Linux加上/dev
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    portName = $"/dev/{portName}";
                }
                //开始使用串口
                using SerialPort serial = new SerialPort(portName, 115200);
                serial.DataReceived += DataReceived;
                serial.Encoding = Encoding.UTF8;
                serial.Open();
                if (serial.IsOpen)
                {
                    Console.WriteLine($"Port {portName} has opened!");
                }
                else
                {
                    Console.WriteLine($"Port {portName} cannot open!");
                    return;
                }
                while (true)
                {
                    //读取输入的数据,然后发送
                    string input = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(input))
                    {
                        continue;
                    }
                    serial.Write(input);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

    private static void DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            if (!(sender is SerialPort))
            {
                return;
            }
            SerialPort serial = sender as SerialPort;
            string read = serial.ReadExisting();
            Console.WriteLine("-->" + read);
        }
        catch { }
    }
}

调试运行

在树莓派和计算机中分别运行程序。树莓派中运行需要将portName修改为ttyAMA0,电脑(Windows)中运行需要将portName修改COMx,x为对于的串口数字。

运行截图如下:

%title插图%num
运行截图

参考资料

(1)树莓派UART说明 (2)https://www.jianshu.com/p/26409ddf6a9b (3)System.IO.Ports Namespace

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2020-12-13

afirefish

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论
放松一下
https://www.quarkbook.com/wp-content/uploads/2021/05/凤凰传奇-海底(Live).flac
分类
  • .NET/C#
  • Linux
  • 树莓派
  • 物联网
  • 科普
  • 笔记
  • 算法
  • 默认
最新 热点 随机
最新 热点 随机
维持宇宙的四种“力量”——关于四大基本力 MinGW图形安装界面里面没有mingw32 make.exe解决办法 Windows Server 2022安装Intel I225-V/I226-V驱动 System.Text.Json与Newtonsoft.Json Json序列化与反序列化性能对比 R86S散热改造 Windows移除多余输入法'Unknown Locale (qaa-Latn)'
Windows Server 2022安装Intel I225-V/I226-V驱动MinGW图形安装界面里面没有mingw32 make.exe解决办法维持宇宙的四种“力量”——关于四大基本力
树莓派.Net Core Iot入门系列篇(3):I2C 免费本地解析域名(locallocal.cn),支持HTTPS 几种常见的开源协议详解 Ubuntu18.04安装Docker 严肃一点的排序算法(2) – 面条排序 MinGW图形安装界面里面没有mingw32 make.exe解决办法
最近评论
afirefish 发布于 4 个月前(11月28日) 非常感谢,非常棒!
》随缘《 发布于 4 个月前(11月20日) 最新【一键处理】方法: https://github.com/MrXhh/VSTools/rele...
管理员 发布于 9 个月前(06月22日) emmmm....服务器好一点???
wking 发布于 10 个月前(05月23日) 请问贵博客是怎么优化的,网页响应速度非常快。我博客同样的WordPress和kratos主题,但点一...
去月球 发布于 1 年前(01月17日) 如果使用CSI的摄像头应该怎么修改命令呢
书签
  • 打赏
  • 毒鸡汤
  • 米店
  • 金鱼直播间

COPYRIGHT © 2022 quarkbook.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备15036129号-9

登录
注册|忘记密码?