IO复用
通过SDK提供的API即可完成IOMUX设置
// 实际操作IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA寄存器来选择IO的功能
IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0);
// 实际操作IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA寄存器来设置IO的特性(上下拉、速率等),默认值0x10B0
IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX, 0x10B0);
第一眼看IOMUXC_UART1_TX_DATA_UART1_TX
这个宏定义有点懵,常规应该是把IO_X复用为UART或SPI等功能。
其实是这个IO的名字就叫UART1_TXD
,复用成UART1_TX
,也可以复用成GPIO1_16
再看看还有其他宏就明白了IOMUXC_UART1_TX_DATA_GPIO1_IO16
、IOMUXC_GPIO1_IO01_GPIO1_IO01
、IOMUXC_GPIO1_IO01_I2C2_SDA
配置串口
波特率公式:
B
a
u
d
R
a
t
e
=
R
e
f
F
r
e
q
16
×
(
U
B
M
R
+
1
U
B
I
R
+
1
)
BaudRate = \frac{Ref \; Freq}{16 \times \left(\frac{UBMR + 1}{UBIR + 1}\right)}
BaudRate=16×(UBIR+1UBMR+1)RefFreq
UART1->UCR2 &= ~(1 << 0); // 复位
while ((UART1->UCR2 & 0x1) == 0)
; // 等待复位完成
// 设置以115200 8 N 1为例
uint32_t reg = UART1->UCR2;
reg |= (1UL << 14); // 忽略 RTS Pin
reg &= ~(1UL << 8); // 校验位 None
reg &= ~(1UL << 6); // 停止位 1bit
reg |= (1UL << 5); // 数据位宽 8bit
reg |= (1UL << 2); // TX EN
reg |= (1UL << 1); // RX EN
UART1->UCR2 = reg;
// 文档要求此位为1
UART1->UCR3 |= 1 << 2;
// 设置UART_CLK_ROOT
CCM->CSCDR1 &= ~0x3FUL; // 选择参考时钟为 pll3_80m/1 = 80MHz
reg = UART1->UFCR;
reg &= ~(0x7UL << 7);
reg |= (0x5UL << 7);
UART1->UFCR = reg; // 对参考时钟进行1分频
// 80000000 / ( 16 * (3124+1) / (71+1) ) = 115200
UART1->UBIR = 71; // 必须先配UBIR再配UBMR 否则波特率异常
UART1->UBMR = 3124;
// Enable Uart
UART1->UCR1 |= (1 << 0);