- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我无法让自动波特率检测在 STM32L0
上工作。我正在使用硬件抽象层 (HAL)。
我的初始化代码是:
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 300;
huart1.Init.WordLength = UART_WORDLENGTH_9B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_EVEN;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT;
huart1.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;
huart1.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT;
HAL_UART_Init(&huart1);
}
我通过 UART1 发送的字节是:
0 1 2 3 4 5 6 7 8
000x 68 0B 0B 68 53 FD 52 FF FF .. etc.
0x68 = 0b01101000
0x0B = 0b00001011
0xFD = 0b11111101 <-- Character starting with 1, baudrate should be detected
0xFD :
start 1 1 .....
___ bit __________
¦______¦
...
为什么没有检测到波特率?我试过:
UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT
和 UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE
所以我调整了驱动程序中模式设置和启用的顺序:
/* if required, configure auto Baud rate detection scheme */
if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
{
assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
/* set auto Baudrate detection parameters if detection is enabled */
if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
{
assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
}
}
到
/* if required, configure auto Baud rate detection scheme */
if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
{
assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart-
/* set auto Baudrate detection parameters if detection is enabled */
if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
{
assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
}
MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
}
什么都不做。
此外,以下内容似乎还不错:
The clock source frequency must be compatible with the expected communication speed(when oversampling by 16, the baud rate is between fCK/65535 and fCK/16. whenoversampling by 8, the baudrate is between fCK/65535 and fCK/8).
我过采样 16,所以
fCK= 16000000
fCK > 16000000 / 65535 = 244 = 244 Hz
fCK < 16000000 / 16 = 1000000 = 1 MHz
我选择的波特率是:19200/9600/2400/300
最佳答案
如果您无法指定要由 STM32L0 的自动波特率检测硬件检查的单个字节的精确内容,您仍然可以“推出自己的”自动波特率检测方案,前提是以下假设可以为您的系统制作:
在自动波特率检测过程中允许丢弃任意数量的连续接收字符。
在接收到多个字符的任意时间间隔内,可以假定位序列 010
或 101
是比较常见的现象。
该设备有一个可用的通用定时器外设,可以映射到与 USART Rx 信号相同的设备引脚。
如果以上所有情况都成立,那么您可以使用芯片上通用定时器外设之一的输入捕获功能创建自己的自动波特率检测方案。这些定时器可以配置为使用内部 16 MHz 时钟作为它们的时钟源。每个定时器包含一个 16 位计数器。使用 16 MHz 时钟时,定时器具有 (1/16,000,000 Hz) = 62.5 nS 脉冲测量分辨率。
在您首选的波特率下,单个位的持续时间如下:
Baud Microseconds 62.5-nS Clocks
---- ------------ --------------
300 3,333.3 53,333
2400 416.7 6,667
9600 104.2 1,667
19200 52.1 833
您可以在输入捕获模式下设置定时器,并让它计算两个相邻边沿转换之间的时钟数。对相对较多的样本(例如 100)执行此操作。这些样本中的许多将表示两个或多个相邻零或两个或多个相邻零的宽度。但您正在寻找最短 样本。如果您找到一个介于 831 和 835 之间的计数,那么您可以有理由相信波特率为 19200。在 100 个样本之后,如果您找到的最短的计数介于 1665 和 1669 之间,那么您可以假设波特率为9600等等。
在此过程中,USART 被禁用,而定时器被分配给引脚。确定要使用的正确波特率后,重新配置引脚以将其分配给 USART Rx 外设功能。
关于c - STM32L0的自动波特率检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34874020/
我正在对 JVM 上的 STM 技术进行一些研究。阅读了一些文档后,我对 Multiverse 的实现有些困惑。 根据 the Multiverse FAQ , Multiverse 不支持检测。然而
我想知道 Clojure 怎么可能已经实现了软件事务内存并且没有发现任何问题,而微软没有完成它的 C# 工作并注意到一些问题使得实现这里描述的 STM 不切实际: http://www.bluebyt
最后,我有以下设置 C:>哪里玩 C:\apps\play-2.2.0\play C:\apps\play-2.2.0\play.bat C:> 哪里 scala C:\apps\scala\bin\
我试图找出 Clojure 所称的 STM 与 Haskell 中实现的 STM 之间的区别。撇开实际的语言语义差异不谈,正如 Rich Hickey 在他的演讲中所说,Clojure 的 STM 实
阅读 Bartosz Milewski 的精彩作品 blog post在 STM 上,我很兴奋地阅读了以下内容: But take into account an important fact: ST
大家好, 在某些时候,我认为这些 stm 实现(我使用过一点点的多元宇宙......),被过度宣传了。因为在某些时候他们使用 CAS 来为他们提供操作的原子性。如果我直接使用 CAS 而不是使用这些实
haskell 的 stm 库中有一个函数,其类型签名如下: alwaysSucceeds :: STM a -> STM () 根据我对 Haskell 中 STM 的了解,在执行 STM 计算时,
在 Clojure 中,我们使用 STM 来实现并发。 我的问题是STM使用数据的时间点值,这是否会带来歧义? 我们如何知道访问了什么值? 最佳答案 Clojure 中的 STM 提供了(通过 ref
我需要有关用作原子更改日志的数据结构的建议。 我正在尝试实现以下算法。有流量传入更改更新内存中的映射。在类似 Haskell 的伪代码中它是 update :: DataSet -> Some
我正在尝试对这两个(软件事务内存和原子操作,我想两者不一样)进行一些基准测试,尽管我没有使用STM做太多事情(它似乎很难使用),但我成功地尝试了对基准测试进行计数,即所有线程将共享计数器递增 5000
我能够使用 STM 初始化状态并将其打印出来: module Main where import Control.Concurrent.STM data State = State {name ::
我读过两个关于 STM 如何实现的完全不同的描述。也许两者都是正确的,或者一个是错误的,我希望有人能阐明这一点。 Take 1(维基百科):允许所有线程修改共享内存,但事务中的每次读写都会被记录下来。
我知道将具有副作用的函数放在 STM 事务中通常是不好的做法,因为它们可能会被重试和调用多次。 然而,在我看来,您可以使用代理来确保只有在事务成功完成后才会执行副作用。 例如 (dosync //
我正在编写一个程序,其中大量代理监听事件并对其使用react。由于Control.Concurrent.Chan.dupChan已弃用我决定使用 TChan 的广告。 TChan 的表现比我预想的差很
我正在研究 Clojure 中的并发编程。 http://clojure.org/concurrent_programming 我了解到atom、ref和agent形式是用来维护程序状态的。 仅ref
你好,我正在阅读《clojure 的乐趣》这本书,在关于 STM 的部分中,他们有一个 2 个事务的图像,其中 A 最初从引用中检索与 B 相同的值,然后事务 A 和 B 都进行计算但 A 首先完成并
我熟悉Database transactions ,并花费了大量的时间调整isolation levels 。我从未在代码中实现过自己的事务模型。 我已通读 the source code对于 Clo
我有一个事务由于某种原因无限期失败,我想在内部使用跟踪指令。例如,要在执行此片段中的事务之前打印 MVar 的状态: data_out do putTMVar
当我们运行 STM 表达式时,它命中了 retry,线程被阻塞,如果条目被修改,事务将再次运行。 但我想知道: 如果我们读取一个 STM 变量,但在导致重试的特定分支中实际未使用该变量,更新它是否会尝
我正在研究 Clojure 中的并发编程。 http://clojure.org/concurrent_programming 我了解到atom、ref 和agent 表单用于维护程序状态。 只有 r
我是一名优秀的程序员,十分优秀!