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