Embedded 如何从efm32控制器一次发送32位帧

Embedded 如何从efm32控制器一次发送32位帧,embedded,Embedded,我试图从efm32控制器中的USART一次发送32位。 我临时采用了以下方法,将usart帧寄存器的前4位字段定义为13,使其具有16位帧,如手动bellowusing中所示 USART0->FRAME=USART0->FRAME&(0xFFFFFFF<<4) //leaving all bits except the first 4 USART0->FRAME=USART0->FRAME|(0b1010) 使用TXDOUBLE寄存器,我将第一个16

我试图从efm32控制器中的USART一次发送32位。 我临时采用了以下方法,将usart帧寄存器的前4位字段定义为13,使其具有16位帧,如手动bellowusing中所示

USART0->FRAME=USART0->FRAME&(0xFFFFFFF<<4) //leaving all bits except the first 4
USART0->FRAME=USART0->FRAME|(0b1010)
使用TXDOUBLE寄存器,我将第一个16位变量放在0-15位,第二个16位变量放在16-31位,如下面的手册所示

USART0->TXDOUBLE=(USART0->TXDOUBLE)&(0xFFFF<<16)//zeros at b15-b0
USART0->TXDOUBLE=USART0->TXDOUBLE|TxBuffer[0]; //setting b15-b0  
USART0->TXDOUBLE=(USART0->TXDOUBLE)&(0xFFFF)//zeros at b31-b16
USART0->TXDOUBLE=USART0->TXDOUBLE|(TxBuffer[1]<<16); //setting b31-b16
这是有效的方法吗? 我是否正确实施了位字段值设置? 完整代码如下所示。 谢谢

在此处输入图像描述


下面是一些代码,它是如何工作的。因为我从未使用过EFM32,也没有编译或验证代码的方法,所以这是一次冒险。我不明白USART0->ROUTE的用途,所以我只是复制了一下

uint8_t TxBuffer[] = { 0b00000011, 0b00001111, 0b11111111, 0b11110000 };

int main(void)
{
  ...

  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_USART0, true);
  GPIO_PinModeSet(gpioPortE, 12, gpioModePushPull, 0); // US1_CLK is push pull
  GPIO_PinModeSet(gpioPortA, 2, gpioModePushPull, 1); // US1_CS is push pull
  GPIO_PinModeSet(gpioPortE, 10, gpioModePushPull, 0); // US1_TX (MOSI) is push pull
  GPIO_PinModeSet(gpioPortE, 11, gpioModeInput, 1);    // US1_RX (MISO) is input

  ...
  
  USART_InitSync_TypeDef config = USART_INITSYNC_DEFAULT;
  config.master       = true;            // master mode
  config.baudrate     = 1000000;         // CLK freq is 1 MHz
  config.databits     = usartDatabits8;
  config.autoCsEnable = false;            // CS pin controlled by hardware, not firmware
  config.clockMode    = usartClockMode0; // clock idle low, sample on rising/first edge
  config.msbf         = true;            // send MSB first

  USART_InitSync(USART0, &config);
  USART0->ROUTE = USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC0;
  USART_Enable(USART0, usartEnable);

  while (1)
  {
    Transmit(TxBuffer, sizeof(TxBuffer));
    Delay(2000);
  }
}

void Transmit(const uint8_t* buf, int len)
{
  // Pull CS (SYNC) low
  GPIO_PinOutClear(gpioPortA, 2);

  for (int i = 0; i < len; i++)
  {
    // Wait until FIFO is (half) empty
    while( !(USART0->STATUS & USART_STATUS_TXBL) ); 

    // Put next byte into FIFO
    USART0->TXDATA = buf[i];
  }
  
  // Wait until transmissiob is complete
  while( !(USART0->STATUS & USART_STATUS_TXC) );

  // Pull CS (SYNC) high
  GPIO_PinOutSet(gpioPortA, 2);
}
USART有一个三级队列、两个FIFO寄存器和一个移位寄存器。因此,通过检查TXBL标志,可能会在前一个字节仍在传输时将新字节放入队列。这样就很容易保持队列已满,这样USART就不需要在字节之间暂停


最后,检查TXC标志,以确保在CS/SYNC拉高之前队列中的所有字节都已完全传输。

您到底想实现什么?从机期望什么样的数据格式?如果从机在常规8位模式下工作,则使用8位模式并发送四个单字节。您好,从机希望接收到conitues 32位cammandclock不停止,如果发送四次8位,则clk在两次之间停止i获取时钟间隔。它发送8位时钟暂停,发送8位时钟暂停,发送8位时钟暂停,发送8位时钟暂停。这是SPI吗?或者协议是什么?在SPI中,只要芯片选择保持不变,间隙就没有问题。从机将查看时钟信号,以确定下一位何时准备就绪。是,DAC80004和xr25闪存的SPI。对于常识,我的方法正确吗?对于常识:不,有几个问题。TXDOUBLE的上16位始终被忽略。即使您的UART配置为在16位模式下工作,您也会进行4次写入,从而导致传输64位。不初始化config.databits可能会导致未定义的行为。帧寄存器只有8个相关位;您可以配置奇怪的停止位和13个数据位。您启用中断,但使用TXC状态位等待完成。恐怕你误解了几个部分。
uint8_t TxBuffer[] = { 0b00000011, 0b00001111, 0b11111111, 0b11110000 };

int main(void)
{
  ...

  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_USART0, true);
  GPIO_PinModeSet(gpioPortE, 12, gpioModePushPull, 0); // US1_CLK is push pull
  GPIO_PinModeSet(gpioPortA, 2, gpioModePushPull, 1); // US1_CS is push pull
  GPIO_PinModeSet(gpioPortE, 10, gpioModePushPull, 0); // US1_TX (MOSI) is push pull
  GPIO_PinModeSet(gpioPortE, 11, gpioModeInput, 1);    // US1_RX (MISO) is input

  ...
  
  USART_InitSync_TypeDef config = USART_INITSYNC_DEFAULT;
  config.master       = true;            // master mode
  config.baudrate     = 1000000;         // CLK freq is 1 MHz
  config.databits     = usartDatabits8;
  config.autoCsEnable = false;            // CS pin controlled by hardware, not firmware
  config.clockMode    = usartClockMode0; // clock idle low, sample on rising/first edge
  config.msbf         = true;            // send MSB first

  USART_InitSync(USART0, &config);
  USART0->ROUTE = USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC0;
  USART_Enable(USART0, usartEnable);

  while (1)
  {
    Transmit(TxBuffer, sizeof(TxBuffer));
    Delay(2000);
  }
}

void Transmit(const uint8_t* buf, int len)
{
  // Pull CS (SYNC) low
  GPIO_PinOutClear(gpioPortA, 2);

  for (int i = 0; i < len; i++)
  {
    // Wait until FIFO is (half) empty
    while( !(USART0->STATUS & USART_STATUS_TXBL) ); 

    // Put next byte into FIFO
    USART0->TXDATA = buf[i];
  }
  
  // Wait until transmissiob is complete
  while( !(USART0->STATUS & USART_STATUS_TXC) );

  // Pull CS (SYNC) high
  GPIO_PinOutSet(gpioPortA, 2);
}