用的外设是PA9 PA10
DMA选择是DMA2_Channel6
代码中还用了DMA传输完成中断,备用配置ADM2483的管脚。直接
上代码了:
void UART_Init(u32 pclk2, u32 bound, u8 checkMode)
{
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
__GPIOC_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
MODIFY_REG(USART1-》CR1, USART_CR1_UE_Msk, 0); // 失能串口
while (READ_BIT(USART1-》CR1, USART_CR1_UE_Msk) != 0);
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, 0); //dis: Channel disable
while(DMA2_Channel6-》CCR & DMA_CCR_EN_Msk); //确保 DMA 可以被设置
GPIO_Set(GPIOA, GPIO_PIN_9 | GPIO_PIN_10, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_FREQ_LOW, GPIO_NOPULL); // PB14设置
GPIO_AF_Set(GPIOA, 9, GPIO_AF7_USART1); // PA9, AF7
GPIO_AF_Set(GPIOA, 10, GPIO_AF7_USART1); // PA10, AF7
u32 USARTDiv = 2 * pclk2 * 1000000 / bound;
USART1-》BRR = (USARTDiv & 0xFFFFFFF0) | ((USARTDiv & 0x0F) 》》 1);
// MeterConfig.s.rsCheckMode
if (checkMode == checkMode_NONE) {
MODIFY_REG(USART1-》CR1, USART_CR1_PCE_Msk, 0); // 0: Parity control disabled
MODIFY_REG(USART1-》CR1, USART_CR1_M_Msk, 0); // M[1:0] = 00: 1 Start bit, 8 data bits, n stop bits
} else if (checkMode == checkMode_ODD) {
MODIFY_REG(USART1-》CR1, USART_CR1_PCE_Msk, USART_CR1_PCE); // 1: Parity control enabled
MODIFY_REG(USART1-》CR1, USART_CR1_PS_Msk, USART_CR1_PS); // 1: Odd parity
MODIFY_REG(USART1-》CR1, USART_CR1_M_Msk, USART_CR1_M0); // M[1:0] = 01: 1 Start bit, 8 data bits, n stop bits
} else if (checkMode == checkMode_EVEN) {
MODIFY_REG(USART1-》CR1, USART_CR1_PCE_Msk, USART_CR1_PCE); // 1: Parity control enabled
MODIFY_REG(USART1-》CR1, USART_CR1_PS_Msk, 0); // 0: Even parity
MODIFY_REG(USART1-》CR1, USART_CR1_M_Msk, USART_CR1_M0); // M[1:0] = 01: | SB | 8-bit data | PB | STB |
}
MODIFY_REG(USART1-》CR1, USART_CR1_OVER8_Msk, USART_CR1_OVER8); // 0: Oversampling by 16
MODIFY_REG(USART1-》CR1, USART_CR1_TE_Msk, USART_CR1_TE); // 1: Transmitter is enabled
MODIFY_REG(USART1-》CR1, USART_CR1_RE_Msk, USART_CR1_RE); // 1: Receiver is enabled and begins searching for a start bit
MODIFY_REG(USART1-》CR3, USART_CR3_DMAT_Msk, USART_CR3_DMAT); // 1: DMA mode is enabled for transmission
// 1: A USART interrupt is generated whenever ORE=1 or RXNE=1 in the USART_ISR register
MODIFY_REG(USART1-》CR1, USART_CR1_RXNEIE_Msk, USART_CR1_RXNEIE);
NVIC_Init(USART1_IRQn, 3, 0); // 抢占 3,子优先级 1
// 发送DMA配置
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_MEM2MEM_Msk, (0x0UL 《《 DMA_CCR_MEM2MEM_Pos)); // 00: Low
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_PL_Msk, (0x0UL 《《 DMA_CCR_PL_Pos)); // 00: Low
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_MSIZE_Msk, (0x0UL 《《 DMA_CCR_MSIZE_Pos)); // 00: 8-bits 01: 16-bits 10: 32-bits 11: Reserved
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_PSIZE_Msk, (0x0UL 《《 DMA_CCR_PSIZE_Pos)); // 00: 8-bits 01: 16-bits 10: 32-bits 11: Reserved
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_MINC_Msk, (0x1UL 《《 DMA_CCR_MINC_Pos)); // Memory increment mode
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_PINC_Msk, (0x0UL 《《 DMA_CCR_PINC_Pos)); // Peripheral increment mode
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_CIRC_Msk, (0x0UL 《《 DMA_CCR_CIRC_Pos)); // Circular mode
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_DIR_Msk, (0x1UL 《《 DMA_CCR_DIR_Pos)); // DIR: Data transfer direction 1: Read from memory
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_TCIE_Msk, DMA_CCR_TCIE); //Transfer complete interrupt enable
NVIC_Init(DMA2_Channel6_IRQn, 3, 1); // 抢占 3,子优先级 1
MODIFY_REG(DMA2_CSELR-》CSELR, DMA_CSELR_C6S_Msk, ((0x2UL) 《《 DMA_CSELR_C6S_Pos)); // the remaining bytes to be transmitted
DMA2_Channel6-》CPAR = (uint32_t)&(USART1-》TDR); // 外设地址
DMA2_Channel6-》CMAR = (uint32_t)(rsData.sendData); // 内存地址
MODIFY_REG(USART1-》CR1, USART_CR1_UE_Msk, USART_CR1_UE); // 使能串口
// MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, (0x1UL 《《 DMA_CCR_EN_Pos)); //EN: Channel enable
}
void UART_DeInit(void)
{
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, 0); //dis: Channel enable
MODIFY_REG(USART1-》CR1, USART_CR1_UE_Msk, 0); // 失能串口
GPIO_Set(GPIOA, GPIO_PIN_9 | GPIO_PIN_10, GPIO_MODE_AIN, GPIO_OTYPE_PP, GPIO_SPEED_FREQ_LOW, GPIO_NOPULL); // PB14设置
GPIO_Set(GPIOC, GPIO_PIN_6, GPIO_MODE_AIN, GPIO_OTYPE_PP, GPIO_SPEED_FREQ_LOW, GPIO_NOPULL); // PC6 -- RE 设置
__HAL_RCC_DMA2_CLK_DISABLE();
__HAL_RCC_USART1_CLK_DISABLE();
}
//开启一次 DMA 传输
//DMA_Streamx:DMA 数据流,DMA1_Stream0~7/DMA2_Stream0~7
//ndtr:数据传输量
void UART_DMA_Enable(u16 ndtr)
{
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, 0); //dis: Channel disable
while(DMA2_Channel6-》CCR & DMA_CCR_EN_Msk); //确保 DMA 可以被设置
// memset(rsData.sendData, 0x37, ndtr);
DMA2_Channel6-》CNDTR = ndtr; //DMA 存储器 0 地址
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, DMA_CCR_EN); //EN: Channel enable
}
发送任务:
void uartTask(void)
{
if (rsData.enableFlag == 0 && lcdCtrl.settingFlag != IS_SETTING) {
UART_Init(4, atoi(RS_BaudRate[MeterConfig.s.rsBaudRate].str), MeterConfig.s.rsCheckMode);
rsData.enableFlag = 1;
}
if (rsData.rcvCompleteFlag == METER_TRUE) {
memcpy(rsData.sendData, rsData.rcvData, rsData.rcvDataLen);
UART_DMA_Enable(rsData.rcvDataLen);
rsData.rcvCompleteFlag = 0;
rsData.rcvDataLen = 0;
}
}
接收中断:
void USART1_IRQHandler(void)
{
//1: A USART interrupt is generated whenever ORE=1 or RXNE=1 in the USART_ISR register
if ((USART1-》ISR & (USART_ISR_ORE_Msk | USART_ISR_RXNE_Msk)) != 0) {
u8 rcvData = USART1-》RDR;
if (MeterConfig.s.rsMode == RTU_MODE) {
rtuRcvByte(&rsData, rcvData);
} else if (MeterConfig.s.rsMode == ASCII_FST) {
asciiRcvByte(&rsData, rcvData);
}
// 清中断
USART1-》ICR = USART_ICR_ORECF;
}
}
测试OK:
用的外设是PA9 PA10
DMA选择是DMA2_Channel6
代码中还用了DMA传输完成中断,备用配置ADM2483的管脚。直接
上代码了:
void UART_Init(u32 pclk2, u32 bound, u8 checkMode)
{
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
__GPIOC_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
MODIFY_REG(USART1-》CR1, USART_CR1_UE_Msk, 0); // 失能串口
while (READ_BIT(USART1-》CR1, USART_CR1_UE_Msk) != 0);
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, 0); //dis: Channel disable
while(DMA2_Channel6-》CCR & DMA_CCR_EN_Msk); //确保 DMA 可以被设置
GPIO_Set(GPIOA, GPIO_PIN_9 | GPIO_PIN_10, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_FREQ_LOW, GPIO_NOPULL); // PB14设置
GPIO_AF_Set(GPIOA, 9, GPIO_AF7_USART1); // PA9, AF7
GPIO_AF_Set(GPIOA, 10, GPIO_AF7_USART1); // PA10, AF7
u32 USARTDiv = 2 * pclk2 * 1000000 / bound;
USART1-》BRR = (USARTDiv & 0xFFFFFFF0) | ((USARTDiv & 0x0F) 》》 1);
// MeterConfig.s.rsCheckMode
if (checkMode == checkMode_NONE) {
MODIFY_REG(USART1-》CR1, USART_CR1_PCE_Msk, 0); // 0: Parity control disabled
MODIFY_REG(USART1-》CR1, USART_CR1_M_Msk, 0); // M[1:0] = 00: 1 Start bit, 8 data bits, n stop bits
} else if (checkMode == checkMode_ODD) {
MODIFY_REG(USART1-》CR1, USART_CR1_PCE_Msk, USART_CR1_PCE); // 1: Parity control enabled
MODIFY_REG(USART1-》CR1, USART_CR1_PS_Msk, USART_CR1_PS); // 1: Odd parity
MODIFY_REG(USART1-》CR1, USART_CR1_M_Msk, USART_CR1_M0); // M[1:0] = 01: 1 Start bit, 8 data bits, n stop bits
} else if (checkMode == checkMode_EVEN) {
MODIFY_REG(USART1-》CR1, USART_CR1_PCE_Msk, USART_CR1_PCE); // 1: Parity control enabled
MODIFY_REG(USART1-》CR1, USART_CR1_PS_Msk, 0); // 0: Even parity
MODIFY_REG(USART1-》CR1, USART_CR1_M_Msk, USART_CR1_M0); // M[1:0] = 01: | SB | 8-bit data | PB | STB |
}
MODIFY_REG(USART1-》CR1, USART_CR1_OVER8_Msk, USART_CR1_OVER8); // 0: Oversampling by 16
MODIFY_REG(USART1-》CR1, USART_CR1_TE_Msk, USART_CR1_TE); // 1: Transmitter is enabled
MODIFY_REG(USART1-》CR1, USART_CR1_RE_Msk, USART_CR1_RE); // 1: Receiver is enabled and begins searching for a start bit
MODIFY_REG(USART1-》CR3, USART_CR3_DMAT_Msk, USART_CR3_DMAT); // 1: DMA mode is enabled for transmission
// 1: A USART interrupt is generated whenever ORE=1 or RXNE=1 in the USART_ISR register
MODIFY_REG(USART1-》CR1, USART_CR1_RXNEIE_Msk, USART_CR1_RXNEIE);
NVIC_Init(USART1_IRQn, 3, 0); // 抢占 3,子优先级 1
// 发送DMA配置
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_MEM2MEM_Msk, (0x0UL 《《 DMA_CCR_MEM2MEM_Pos)); // 00: Low
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_PL_Msk, (0x0UL 《《 DMA_CCR_PL_Pos)); // 00: Low
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_MSIZE_Msk, (0x0UL 《《 DMA_CCR_MSIZE_Pos)); // 00: 8-bits 01: 16-bits 10: 32-bits 11: Reserved
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_PSIZE_Msk, (0x0UL 《《 DMA_CCR_PSIZE_Pos)); // 00: 8-bits 01: 16-bits 10: 32-bits 11: Reserved
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_MINC_Msk, (0x1UL 《《 DMA_CCR_MINC_Pos)); // Memory increment mode
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_PINC_Msk, (0x0UL 《《 DMA_CCR_PINC_Pos)); // Peripheral increment mode
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_CIRC_Msk, (0x0UL 《《 DMA_CCR_CIRC_Pos)); // Circular mode
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_DIR_Msk, (0x1UL 《《 DMA_CCR_DIR_Pos)); // DIR: Data transfer direction 1: Read from memory
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_TCIE_Msk, DMA_CCR_TCIE); //Transfer complete interrupt enable
NVIC_Init(DMA2_Channel6_IRQn, 3, 1); // 抢占 3,子优先级 1
MODIFY_REG(DMA2_CSELR-》CSELR, DMA_CSELR_C6S_Msk, ((0x2UL) 《《 DMA_CSELR_C6S_Pos)); // the remaining bytes to be transmitted
DMA2_Channel6-》CPAR = (uint32_t)&(USART1-》TDR); // 外设地址
DMA2_Channel6-》CMAR = (uint32_t)(rsData.sendData); // 内存地址
MODIFY_REG(USART1-》CR1, USART_CR1_UE_Msk, USART_CR1_UE); // 使能串口
// MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, (0x1UL 《《 DMA_CCR_EN_Pos)); //EN: Channel enable
}
void UART_DeInit(void)
{
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, 0); //dis: Channel enable
MODIFY_REG(USART1-》CR1, USART_CR1_UE_Msk, 0); // 失能串口
GPIO_Set(GPIOA, GPIO_PIN_9 | GPIO_PIN_10, GPIO_MODE_AIN, GPIO_OTYPE_PP, GPIO_SPEED_FREQ_LOW, GPIO_NOPULL); // PB14设置
GPIO_Set(GPIOC, GPIO_PIN_6, GPIO_MODE_AIN, GPIO_OTYPE_PP, GPIO_SPEED_FREQ_LOW, GPIO_NOPULL); // PC6 -- RE 设置
__HAL_RCC_DMA2_CLK_DISABLE();
__HAL_RCC_USART1_CLK_DISABLE();
}
//开启一次 DMA 传输
//DMA_Streamx:DMA 数据流,DMA1_Stream0~7/DMA2_Stream0~7
//ndtr:数据传输量
void UART_DMA_Enable(u16 ndtr)
{
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, 0); //dis: Channel disable
while(DMA2_Channel6-》CCR & DMA_CCR_EN_Msk); //确保 DMA 可以被设置
// memset(rsData.sendData, 0x37, ndtr);
DMA2_Channel6-》CNDTR = ndtr; //DMA 存储器 0 地址
MODIFY_REG(DMA2_Channel6-》CCR, DMA_CCR_EN_Msk, DMA_CCR_EN); //EN: Channel enable
}
发送任务:
void uartTask(void)
{
if (rsData.enableFlag == 0 && lcdCtrl.settingFlag != IS_SETTING) {
UART_Init(4, atoi(RS_BaudRate[MeterConfig.s.rsBaudRate].str), MeterConfig.s.rsCheckMode);
rsData.enableFlag = 1;
}
if (rsData.rcvCompleteFlag == METER_TRUE) {
memcpy(rsData.sendData, rsData.rcvData, rsData.rcvDataLen);
UART_DMA_Enable(rsData.rcvDataLen);
rsData.rcvCompleteFlag = 0;
rsData.rcvDataLen = 0;
}
}
接收中断:
void USART1_IRQHandler(void)
{
//1: A USART interrupt is generated whenever ORE=1 or RXNE=1 in the USART_ISR register
if ((USART1-》ISR & (USART_ISR_ORE_Msk | USART_ISR_RXNE_Msk)) != 0) {
u8 rcvData = USART1-》RDR;
if (MeterConfig.s.rsMode == RTU_MODE) {
rtuRcvByte(&rsData, rcvData);
} else if (MeterConfig.s.rsMode == ASCII_FST) {
asciiRcvByte(&rsData, rcvData);
}
// 清中断
USART1-》ICR = USART_ICR_ORECF;
}
}
测试OK:
举报