STM32F4 UART半字寻址

Posted

技术标签:

【中文标题】STM32F4 UART半字寻址【英文标题】:STM32F4 UART half word addressing 【发布时间】:2021-10-31 06:59:07 【问题描述】:

尝试为 STM32F4 UART 推出我自己的代码。 该芯片的一个特点是,如果您在设置单个位时像 GNAT 编译器那样使用字节寻址,则设置半字的另一个字节中的相应位。数据表说使用半字寻址。有没有办法告诉编译器这样做?我试过了 对于 CR1_register'Size 使用 16;

但这没有任何效果。写入整个 16 位字可以,但您无法设置命名位。

【问题讨论】:

【参考方案1】:

在 AdaCore Ada Drivers Library 中使用的 GNAT 方法是使用仅 GNAT 方面 Volatile_Full_Access,GNAT Reference Manual 对此进行了说明

这在效果上类似于 pragma Volatile,除了对对象的任何引用都保证只能通过读取或写入对象所有位的指令来完成。此外,如果对象是复合类型,则对对象子组件的任何引用都保证读取和/或写入对象的所有位。

其目的是使其适用于某些机器上的内存映射 I/O 设备。请注意,这与 pragma Atomic 有两个重要方面不同。首先,对 Volatile_Full_Access 对象的引用不是 RM 9.10 意义上的顺序操作,因此不会创建同步点。其次,在 pragma Atomic 的情况下,如果引用不是对整个对象,则不能保证所有位都会被访问;在这种情况下,编译器只允许(并且通常会)访问对象的一部分。

他们的代码是

   --  Control register 1
   type CR1_Register is record
      --  Send break
      SBK            : Boolean := False;
      ...
   end record
     with Volatile_Full_Access, Size => 32,
          Bit_Order => System.Low_Order_First;

   for CR1_Register use record
      SBK            at 0 range 0 .. 0;
      ...
   end record;

【讨论】:

【参考方案2】:

可移植的方式是明确地执行此操作:读取整个记录,修改,然后将其写回。只要声明为Volatile,编译器就不会优化读写。

    -- excerpt from my working code --
    declare
        R : Control_Register_1 := Module.CR1;
    begin
        R.UE := True;
        Module.CR1 := R;
    end;

这很冗长,但它确实有效。

【讨论】:

以上是关于STM32F4 UART半字寻址的主要内容,如果未能解决你的问题,请参考以下文章

STM32F4 UART1 DMA发送和接收不定长度数据

STM32F4 UART HAL驱动程序'将字符串保存在变量缓冲区中'

stm32f4 dma + uart idle + double 调试小记

带有 HAL 库的 STM32F4-Discovery (STM32F429ZIT6) 上的 RS232 (UART)?

STM32F4 在中断时从UART接收数据的问题

STM32F4 HAL库开发 -- 串口