tag 标签: 串口

相关帖子
相关博文
  • 热度 3
    2021-4-17 18:09
    595 次阅读|
    1 个评论
    用两张图,详解FreeModbus在单片机串口上的数据收发过程-FreeModbus从站设计(9)
    FreeModbus从站设计(9)-详解FreeModbus在单片机串口上的数据收发过程 关键词:FreeModbus STM32F103 CubeMX HAL库 串口 1.引言 在上一篇文章中,主要阐述了vMBPortSerialEnable()这个函数如何基于HAL库调度单片机串口的收发,感觉还是不是很清晰,因此,孔丙火(微信公众号:孔丙火)在这一篇文章中,重点捋一下串口的收发函数调用关系,以求有有一个清晰的脉络。 2.函数调用的基本框架 直接上图,更清晰,接收过程如图1所示,发送过程如图2所示。 图1 接收过程起源于vMBPortSerialEnable()函数的调用,此时,该函数将串口设置位接收状态,即使能接收中断,禁止发送中断。从图中可以清晰的看出,需要修改的地方就是接收中断的回调函数和portserial.c和porttimer.c中的几个函数。至于何时调用vMBPortSerialEnable()函数,孔丙火(微信公众号:孔丙火)认为,我们是不需要关心的,只要按照之前的文章,把FreeModbus的代码添加到keil工程中,FreeModbus协议栈会进行调度。接收过程是一个字节一个字节进行接收的,当协议栈检测到定时器超时,则认为一个完整的数据帧接收完毕,开始进入数据处理的阶段,数据处理完成后,则进行回复数据的发送。 图2 发送过程同样起源于vMBPortSerialEnable()函数的调用,此时,该函数将串口设置位发送状态,即使能发送中断,禁止接收中断。从图中可以清晰的看出,需要修改的地方就是发送中断的回调函数和portserial.c中的几个函数。至于何时调用vMBPortSerialEnable()函数,孔丙火(微信公众号:孔丙火)认为,我们是不需要关心的,只要按照之前的文章,把FreeModbus的代码添加到keil工程中,FreeModbus协议栈会进行调度。发送过程同样是一个字节一个字节进行的,在xMBRTUTransmitFSM()函数中,会检测是否还有需要发送的数据,若没有数据需要发送了,则会调用vMBPortSerialEnable()函数,再次将串口设置为接收状态。作为Modbus从站,串口大部分时间是处于接收状态的。 3.总结 在这篇文章中,孔丙火(微信公众号:孔丙火)接着上一篇文章的思路,用两张图把FreeModbus在单片机串口上数据收发流程进行了梳理,脉络更加清晰。有了这样一个思路,可以更好地理解,移植FreeModbus的时候,为什么需要修改portserial.c和porttimer.c中的函数,和为什么需要修改串口中断的回调函数。从这篇文章中,也可以看出,采用HAL库是比较简单的,像是中断处理这些内容库函数都已经处理好了,很方便,可以提高开发效率。 文章在公众号( 孔丙火 )同步推出,欢迎查看更多系列文章。 单片机、ARM、现场总线、PLC、嵌入式软硬件的设计经验分享,秉承“点点滴滴皆智慧”的理念,以实际项目为单元阐述知识点,一起分享,共同交流。
  • 热度 4
    2020-6-21 07:56
    972 次阅读|
    0 个评论
    部分特性说明: NOISE ERROR FLAG(NF,START位噪音探测标志):仅在START位时进行判断,RX下降沿启动检测,在START位的中间位置检测到1时则置位该标志,然后丢弃当前START位,等待下一个START开始条件 FRAMING ERROR FLAG(帧错误):当收到一个BREAK字符、大量噪音或者数据非同步(波特率错误),会被认为是帧错误,置位该位 OVERRUN FLAG(溢出错误):当RXNE标志置位时,又收到新字符。此时新收到的字符会被丢弃,RX寄存器中数据不会被覆盖。该位为1说明至少漏掉了1个字符数据。如果该位为1时,RXNE为0,表明数据丢弃正好发生在读取上一个数据的过程中 IDLE字符:RX一次下降沿后收到全1值(TE位关闭到开启也会在TX线上产生一个IDLE字符) BREAK字符:RX一次下降沿后收到全0值(发送器会在BREAK帧后插入2个停止位) 发送中断包括:传输完成、CTS、发送寄存器空、帧错误 接收中断包括:IDLE线天策、溢出错误、接收寄存器非空、极性校验错误、噪音错误、帧错误、字符匹配等 UART低功耗模式使用注意: 1. 为了能够支持STOP模式下唤醒串口,UART时钟必须为HSI或者LSE 对于HSI作为串口时钟:STOP模式下,RX上的下降沿触发HSI启动。根据唤醒配置(开始条件、地址匹配以及RXNE置位),满足条件则唤醒Core,否则HSI被关闭。 对于LSE作为串口时钟:类似HSI的情况,区别在于RX下降沿会开通LSE作为串口时钟,满足唤醒条件时则唤醒Core,否则断开LSE(为了达到9600波特率,CR3:UCESM必须置位) 2. 如果使用RXNE中断作为唤醒条件,则进入STOP模式前RXNEIE位必须被置位(即必须允许RX非空中断) 3. CR1:UECM在进入STOP模式前必须置位 4. 探测到唤醒事件时,WUF标志被硬件置位(无论当前Core处于STOP模式还是运行模式),如果WUFIE置位的话,也会产生一个wakeup中断(仅在STOP模式时产生中断,运行模式不会) 5. RX下降沿将置位BUSY标志(有效开始位置位,接收完成时复位),但BUSY标志不能保证Core不会进入STOP模式 6. 发送数据时必须判断TC=1时(发送结束),才能进入STOP模式 CR3:UCESM: 该位可使STOP模式下串口时钟一直开启(即不会断开LSE或不会关闭HSI) CR1:UESM: STM32建议在进入STOP模式前置位,在退出STOP模式后复位(该位复位后,WUF标志也会被清除) 进入STOP模式前注意点: 1. BUSY标志应该为0,该位为1时说明串口正在接收数据 2. 用户自定义的接收缓冲区为空。缓冲区有数据的话,应该处理完再进入STOP模式。 3. 如果使用了RS485-RTU模式,要确保超时定时器未工作。如果定期器在工作,表明正在的等待T3.5过程中
  • 热度 6
    2019-8-26 22:00
    1183 次阅读|
    0 个评论
    前面两期让UFUN开发板有了“嘴”,有了表达交流的元素工具——可显示的字符。接下来是什么呢?当然是让UFUN开发板交流起来。交流就是我问你答,我们的每一次表达都能得到适当的回应,这样就具备智能的潜质。就像微软的小兵、阿里的天猫精灵、小米的小爱,搭配了语音识别和语音合成后,已经开始具备了机器人部分特性。那就让UFUN交流起来吧,通过OLED屏幕响应PC通过USB转串口模块传送的信息。预想的效果是每次PC端发送一个ASC码字符,UFUN会通过OLED告诉我们收到了什么字符,此字符的ASC码是多少。 主程序很简单,就是初始化后显示一个等待PC端发送ASC码字符的界面。 int main(void) { extern unsigned char R_str ;// 全局字符串变量R_str ,用于串口接收数据传送 extern uint8_t ucTemp; uint8_t send_flag=0; //发送标志位 USART_Config(); //串口配置 NVIC_Config(); //中断配置 DelayInit(); I2C_Configuration(); OLED_Init(); OLED_Fill(0x00);//清屏 while(1) { OLED_ShowStr(0,0,"UFUN_PC Talk:",1);// 标题测试6*8字符 ",1);// 标题测试6*8字符 DelayS(1); } 参考了UFUN的串口通讯例程,在主程序里设置了一个全局字符串变量R_str ,用于传送串口接收中断子程序接收的ASC码。就是在这一步差点把人逼疯,出现很多难以想象异常现象:接收到的回送数值无缘无故就变成一个很大的值,比如0xFE、0xE0,在OLED上只能显示一个乱码,如果在串口接收中断子程序和主程序同时回送时子程序回送的数值是对的,那就直接在中断子程序完成回送和显示吧,其结果又是照错不误。 串口发送0x77,回送的数值莫名其妙地变成0xF7,反反复复的修改都试了,就是这么个结果。不多说了,把串口接收中断子程序贴上,希望能得到大牛们指导性的回应。 void USART1_IRQHandler() //串口接收中断 { if (USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) { ucTemp = USART_ReceiveData( USART1 ); Usart_SendByte(USART1,ucTemp);//回送 R_str = ucTemp; //传送接收数据到main.c R_str = 0; OLED_Fill(0x00);//清屏 OLED_ShowStr(0,0,"UFUN_PC Talk:",1);// 标题测试6*8字符 ",1);// 标题测试6*8字符 OLED_ShowStr(10,2,R_str,1);// 显示接收字符 OLED_ShowStr(0,4,"> 4]; hex = chHex ) & 0xf]; hex = ' '; } hex = '\0'; return len * 3; } 最后附上一个没有达到预期效果的程序运行效果图片,这是一个失败的编程经历,到现在也没弄清问题到底出在哪里,留待以后经验丰富了回头分析。 附件: 对话UFUN(串口通讯待修改)源程序 https://mbb.eet-china.com/download/20409.html
  • 热度 5
    2019-6-2 14:55
    3922 次阅读|
    2 个评论
    NUCLEO-F411RE串口输出趣味图像
    一, 概述 拿到 NUCLEO-F411RE 也有两个周了,第一周完成了一篇开箱评测,还没来得及进行深入研究。这周抽个周末摸一下这块入门级高性能芯片的性能。 本篇评测的主要内容为串口输出图像。在有些论坛,经常看到有看到一些有趣的图像,说图片其实也不准确,应该是利用文字的排版完成了一副图像的输出。比那些直接的图像显得更加有趣好玩。本文就利用 NUCLEO-F411 板载的 STM32F411RET6 输出类似的图像。下图是我输出的部分文字,炯炯有神的眼睛,猜猜我是谁 ~~~ 二, 开发平台搭建 现在貌似 Cube 比较流行,只要点几下配置配置源代码就生成了。但是本人不爱学习新东西,至今还没摸过这玩意,所以还是以我熟悉的标准库来进行开发。开发工具用的是 IAR , IAR 简洁大方,就是输入提示功能实在是有点跟不上节奏,要能做到 VS 的提示输入功能,那真是要好用到飞起了。打开标准库中模板 \en.stm32f4_dsp_stdperiph_lib\STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Templates\EWARM\Project.eww 工程。打开后如下图,图中的 MCU 选择应该选择板卡对应的 STM32F411xE 。编译下载能够运行的断点能够跳到 Main 函数,基本就算运行环境OK。 三, LED 灯驱动 开发环境建立完成,首先操作毫无疑问就是进行 LED 常规电灯操作。 根据板卡电路图 LED 的配置到了两个引脚 PA5 和 PB13 ,一开始没有仔细看,配置到了 PB13 ,发生了什么情况你们懂得。点灯程序比较简单,直接贴图就好 四, 串口驱动 对于玩 MCU 的来说点灯是第一步, Hello word 的串口输出是和点灯同样重要的完美搭档。废话不多说。先查看原理图,串口的配置在 PA2 和 PA3 上,查看 Datasheet ,其配置为串口 2 。串口也是比较简单的,贴代码就 OK 了。 五, 串口输出趣味图像 本人桌面是这个 Nike 的标语。受其启发,本实例也是做得简化版的此种效果。先看看单片机版的 Just do it 吧。下面我以输出文字为例子,详细给出制作这种效果的方法。 1. 制作需要输出的图片 打开电脑自带的图片编辑器。在上面调整背景大小,我图中的背景为 104*32 。在图上打上 JUST DO IT 的文字。然后另存为 BMP 图片格式,注意图片的格式为单色位图。 然后我们就要处理这个图片了。找到 ImageLcd 这个软件 。 打开软件输出图片设置图片转换格式。这里有好多输出的样式,可以实现镜像、负片等效果。这个后面读者可以自行尝试。本文对正常的文本进行处理。然后保存成 .h 或 .c 文件。到此部,数据的基本处理已经 OK 了。后面就要去程序中处理了。 2. 数据进行输出 输出的文件格式为一个数组。每个字节代表横向的 8 个像素的值,这个和扫描方向有关系。例如本实例中,第一个字节内容为 0x00 ,则分解成二进制 00000000 的 BIN 格式, bit 为 0 表示没有黑色像素落到此区域,所以串口输出空格,如果 bit 为 1 ,则输出实体的表示字符。本例中用‘ ’表示为无,‘ A ’表示为有像素值。 图片输出程序其实特别简单,如下图的图片所示。 3. 图像输出 其实拓展到其他图片都是一样的,如下图。这个其实就是本文一开始那对囧囧有神的眼睛。 经过上述步骤的操作处理后,输出的图像如下 六, 总结 本文简单的描述了如何用串口输出一个二值的图像。希望本文的抛砖引玉能够使得爱折腾的你能够发现更多的奇妙玩法。在此也要感谢面包板社区提供的 NUCLEO-F411RE 开发版,后面有时间还会就其处理器性能进行进一步评估。 文章中涉及的附件在下列帖子: https://forum.mianbaoban.cn/topic/71366_1_1.html
  • 热度 12
    2016-3-22 15:38
    600 次阅读|
    3 个评论
    ARM嵌入式系统常常会遇到多串口应用需求,而ARM芯片系统原生的UART数目有限,因此就需要通过其他高速总线来扩展更多的接口。本文就以 Toradex 基于NXP i.MX6D/6Q处理器的Apalis i.MX6D/Q ARM计算机模块,在Linux系统下通过EXAR方案扩展8路串口。 Apalis i.MX6D/Q 模块自身最多可以支持 5 个 UART 串口输出。兼容 高速 TIA/EIA-232F(最高 5Mbit/s)。支持7、8 或者 9(用于RS485)位数据,1或者2位停止位。其中 UART1 为全功能串口,其余部分串口也可支持 RTS和CTS 信号。 在 Linux 系统中一般会保留一个串口用于应用调试开发以及系统升级。虽然 SSH 等功能也可以用于远程网络访问以及系统调试,但是对于嵌入式产品,系统启动时,特别是 Uboot 启动的信息,可以有助于功能调试以及问题定位。而这部分信息只能从串口输出。Toradex 模块在更新 Linux BSP 的时候也同样需要在 Uboot 进行。 Apalis i.MX6Q/D 模块剩余的4个串口,除了可以使用 TTL 电平直接控制相应的外设,也可以扩展为 RS232/RS485/RS422 常用的工业控制端口。对于更多串口的需求,目前有多种方案实现串口扩展,例如通过 USB、SPI、Memory Bus、I2C以及 PCIe 等总线。 Memory Bus 和 PCIe 相对于其他总线具有更高的实时性,在同一个接口上也能够扩展出更多的串口。对于串口数量以及数据实时性较高的应用可以优先选择这两种扩展方案。与此同时, Memory Bus 和 PCIe 属于高速信号总线,在 PCB 布线方面需要一些特殊考虑。Toradex 为此也提供了免费的 PCB 设计指导。下面我们就将介绍如何使用 EXAR 基于 PCIe 总线的 XR17V358 方案,扩展 8 路串口。 1). XR17V358 方案简介及驱动下载 XR17V358 扩展的 8 个串口均支持 RTS/CTS 或者 DTR/DSR 流控功能,每个串口带有 256 字节的 FIFO,独立时钟输出,支持半双工 RS485,最高传输速度为 25 Mbps 。XR17V358 使用 PCIe 2.0 Gen 1 与 Apalis i.MX6Q/D 相连接,保证高速实时地数据传输。EXAR 目前为 XR17V358 提供了 Windows 和 Linux 驱动。这里我们采用其最新的 Linux 驱动,并移植到 Apalis i.MX6 平台上。驱动源码下载地址 http://www.exar.com/common/content/document.ashx?id=20121 2). 配置编译环境 在编译之前,还需要下载  Apalis i.MX6 的 Linux 内核以及交叉编译工具。 a). Apalis i.MX6 的 Linux 内核下载 $ git clone -b toradex_imx_3.14.28_1.0.0_ga-next git://git.toradex.com/linux-toradex.git   b). 交叉编译工具下载 $ wget http://releases.linaro.org/14.11/components/toolchain/binaries/arm-linux-gnueabihf/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz $ tar xvf gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz $ ln -s gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf gcc-linaro $ export ARCH=arm $ export PATH=~/gcc-linaro/bin/:$PATH $ export CROSS_COMPILE=arm-linux-gnueabihf- 注意: 上面的路径需要对应交叉编译工具实际解压的目录。   c). 编译 Linux 内核,为 XR17V358  提供必要的配置文件。 $ make apalis_imx6_defconfig $ make -j4 uImage LOADADDR=10008000   d). 编译  XR17V358 驱动 // 编辑 Makefile 文件,将 KERNEL_SRC  指向 Linux 内核所在目录 KERNEL_SRC = /home/ban/Toradex/oe-core-tegra/LinuxKernel/v2.5/mx6/toradex_imx_3.14.28_1.0.0_ga-next/linux-toradex // 保持后运行 make 命令进行编译,确保上面提到的 ARCH、PATH和 CROSS_COMPILE 参数仍然有效。 $ make // 编译成功后会生成针对 ARM 处理器的内核模块文件  xr17v35x.ko $ file xr17v35x.ko xr17v35x.ko: ELF 32-bit LSB  relocatable, ARM, EABI5 version 1 (SYSV), BuildID =399121b7862105b185e24b45ba3522f14158295e, not stripped   e). 安装驱动 将 xr17v35x.ko 复制到 Apalis i.MX6 模块上,并安装 root@apalis-imx6:~# insmod xr17v35x.ko Exar PCIe (XR17V35x) serial driver Revision: 2.0   root@apalis-imx6:~# lspci 00:00.0 PCI bridge: Device 16c3:abcd (rev 01) 01:00.0 PCI bridge: PLX Technology, Inc. PEX 8605 PCI Express 4-port Gen2 Switch (rev aa) 02:01.0 PCI bridge: PLX Technology, Inc. PEX 8605 PCI Express 4-port Gen2 Switch (rev aa) 02:02.0 PCI bridge: PLX Technology, Inc. PEX 8605 PCI Express 4-port Gen2 Switch (rev aa) 02:03.0 PCI bridge: PLX Technology, Inc. PEX 8605 PCI Express 4-port Gen2 Switch (rev aa) 03:00.0 Serial controller: Exar Corp. Device 0358 (rev 03)   在 /dev 目录下出现对应的串口设备文件 ttyXR0 至 ttyXR7。 root@apalis-imx6:/dev# ls autofs              network_latency     tty18               tty60 block               network_throughput  tty19               tty61 bus                 null                tty2                tty62 char                port                tty20               tty63 console             ppp                 tty21               tty7 cpu_dma_latency     ptmx                tty22               tty8 cuse                ptp0                tty23               tty9 disk                pts                 tty24               ttyXR0 dri                 ram0                tty25               ttyXR1 fb                  ram1                tty26               ttyXR2 fb0                 ram10               tty27               ttyXR3 fb1                 ram11               tty28               ttyXR4 fb2                 ram12               tty29               ttyXR5 fb3                 ram13               tty3                ttyXR6 fd                  ram14               tty30               ttyXR7   f). 设置波特率 root@apalis-imx6:~# stty -F /dev/ttyXR0 115200 驱动加载完毕后,在 Linux 中可以和其他串口一样正常使用。
相关资源
广告