本帖最后由 lilijin1995 于 2023-7-11 00:12 编辑
之所以要串口重映射,是因为我发现参考了网上的原理图,把UART的TX和RX接反了,如下图,接收数据流程应该是
RX232->R1IN->R1OUT,但是我这里画反了。
并且也留意到CH32V003可以重映射PD5可以配置TX或RX,
PD6也是一样。如下图
接着我们一起来看一下如何把PD5重映射为URX_,PD6重映射为UTX_;这里参考了该篇帖子:
https://www.makerwitawat.com/%E0%B8%A7%E0%B8%B4%E0%B8%98%E0%B8%B5%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B9%80%E0%B8%9B%E0%B8%A5%E0%B8%B5%E0%B9%88%E0%B8%A2%E0%B8%99-port-tx-%E0%B8%AA%E0%B8%B3%E0%B8%AB%E0%B8%A3%E0%B8%B1%E0%B8%9A-ch32v003j4/
void USART_Printf_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDef USART_InitStructure = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap2_USART1, ENABLE); // กำหนดค่า REMAP TX:PD6, RX:PD5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // กำหนดขา GPIO
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);;
USART_Cmd(USART1, ENABLE);}
其实这里跟沁恒官方例程基本一致,不过需要通过GPIO_PinRemapConfig重映射,重映射是 通过AFIO寄存器实现的
AFIO_PCFR1的UART1 映射配置低位(配合 AFIO_PCFR1 寄存器
bit21 USART1REMAP1 使用[21,2])
即GPIO_PinRemapConfig 的参数选择;
#define GPIO_PartialRemap2_USART1 ((uint32_t)0x80200000)
同时我调试的时候发现104电容GND虚焊了,因为铺地了,所以需要加热久一点。
最后的,中断请求安排上。
void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
* @fn USART1_IRQHandler
*
* [url=home.php?mod=space&uid=247401]@brief[/url] This function handles USART3 global interrupt request.
*
* [url=home.php?mod=space&uid=266161]@return[/url] none
*/
void USART1_IRQHandler(void)
{
u8 rxData=0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
rxData=USART_ReceiveData(USART1);
USART_ClearFlag(USART1, USART_IT_RXNE);
UartRecStruct.RxBuf[UartRecStruct.RxCounter]=rxData;
switch(UartRecStruct.RxCounter)
{
case 0:
{
if(rxData == 0xAA)
{
UartRecStruct.RxCounter++;
}
}break;
case 1:
{
if(rxData == 0x55)
{
UartRecStruct.RxCounter++;
}else
{
ResetUart(&UartRecStruct);
}
}break;
case 4:
{
if(rxData == 0x0D)
{
UartRecStruct.RxCounter++;
}else
{
ResetUart(&UartRecStruct);
}
}break;
case 5:
{
if(rxData == 0x0A)
{
UartRecStruct.RxCounter++;
UartRecStruct.RxOkFlag=READY;
USART_SendData(USART1,rxData);
}else
{
ResetUart(&UartRecStruct);
}
}break;
default:
{
UartRecStruct.RxCounter++;
}break;
}
}
}
|