本帖最后由 FBI快开门 于 2022-8-4 17:03 编辑
按照官网给的例程,改了下串口的管脚配置,dma通道配置,下载之后前几秒不能正常工作,一直打印\0\0\0\0\0\,几秒钟之后才恢复正常,不清楚什么原因
void USART_Send(USART_SFRmap *USARTx, Usart_Sdu_Type *Usart_Sdu)
{
for (uint32_t Send_data_count = 0; Send_data_count < Usart_Sdu->Length; Send_data_count++)
{
USART_SendData(USARTx, Usart_Sdu->Data[Send_data_count]);
while (!USART_Get_Transmitter_Empty_Flag(USARTx))
;
}
}
#endif
/**
* 描述 串口异步全双工配置(默认8bit收发使能 全双工 9600)
* 输入 指向USART内存结构的指针,取值为USART0_SFR~USART8_SFR
* 返回 无
* 说明 波特率38400,发送一个字节大约需要时间0.26ms
* 这里选用SCLK=48MHZ作为波特率发生器时钟
*
* 波特率 =Fck/(16*z(1+x/y)) 外设时钟内部高频16M
* 4800 z:208 x:0 y:0
* 9600 z:104 x:0 y:0
* 19200 z:52 x:0 y:0
* 115200 z:8 x:1 y:13
* 波特率9600
**/
void USART_Async_config(USART_SFRmap *USARTx)
{
USART_InitTypeDef USART_InitStructure;
USART_Struct_Init(&USART_InitStructure);
/* Set Usart To Async Mode */
USART_InitStructure.m_Mode=USART_MODE_FULLDUPLEXASY; //全双工
USART_InitStructure.m_TransferDir=USART_DIRECTION_FULL_DUPLEX; //传输方向
USART_InitStructure.m_WordLength=USART_WORDLENGTH_8B; //8位数据
USART_InitStructure.m_StopBits=USART_STOPBITS_1; //1位停止位
/* Set baudrate to 38400 */
USART_InitStructure.m_BaudRateBRCKS=USART_CLK_SCLK; //内部高频时钟作为 USART波特率发生器时钟
USART_InitStructure.m_BaudRateInteger=78; //USART波特率整数部分z,取值为0~65535
USART_InitStructure.m_BaudRateNumerator=0; //USART波特率小数分子部分x,取值为0~0xF
USART_InitStructure.m_BaudRateDenominator=0; //USART波特率小数分母部分y,取值为0~0xF
USART_Reset(USARTx); //USARTx复位
USART_Configuration(USARTx,&USART_InitStructure); //USARTx配置
USART_Passageway_Select_Config(USARTx,USART_U7816R_PASSAGEWAY_TX0);//UASRTx选择TX0通道
//USART_Clear_Transmit_BUFR_INT_Flag(USARTx); //USARTx发送BUF清零
USART_RESHD_Enable (USARTx, TRUE); //使能RESHD位
USART_Transmit_Data_Enable(USARTx, TRUE); //USARTx发送使能
USART_Cmd(USARTx,TRUE);
DMA_Channel_Enable(DMA0_SFR,DMA_CHANNEL_5,TRUE);
DMA_Channel_Enable(DMA0_SFR,DMA_CHANNEL_6,TRUE);
USART_Receive_DMA_INT_Enable(USARTx,TRUE);
USART_Transmit_DMA_INT_Enable(USARTx,TRUE);
USART_Clear_Transmit_BUFR_INT_Flag(USARTx);
USART_Receive_Idle_Frame_Config(USARTx, TRUE);
USART_IDLE_INT_Enable(USARTx, TRUE);
INT_Interrupt_Enable(INT_USART2, TRUE);
}
/**
* @brief :USART receive enable, and interrupt enable
* @param in :
* USARTx : A pointer to the USART memory structure
* with a value of USART0_SFR/USART1_SFR/USART2_SFR/USART5_SFR
* Peripheral :Interrupt vector number
* @param out :None
* @retval :None
*/
void USART_ReceiveInt_config(USART_SFRmap *USARTx,InterruptIndex Peripheral)
{
USART_RDR_INT_Enable(USARTx,TRUE);
INT_Interrupt_Enable(Peripheral,TRUE);
USART_ReceiveData(USARTx);
}
void Usart2_GPIO_Init(void)
{
/*
GPIO_Write_Mode_Bits(GPIOA_SFR ,GPIO_PIN_MASK_8, GPIO_MODE_RMP); //重映射IO口功能模式
GPIO_Write_Mode_Bits(GPIOA_SFR ,GPIO_PIN_MASK_9, GPIO_MODE_RMP); //重映射IO口功能模式
GPIO_Pin_RMP_Config (GPIOA_SFR ,GPIO_Pin_Num_8, GPIO_RMP_AF5_USART2); //重映射为USART2
GPIO_Pin_RMP_Config (GPIOA_SFR ,GPIO_Pin_Num_9, GPIO_RMP_AF5_USART2); //重映射为USART2
GPIO_Pin_Lock_Config (GPIOA_SFR ,GPIO_PIN_MASK_8, TRUE); //配置锁存
GPIO_Pin_Lock_Config (GPIOA_SFR ,GPIO_PIN_MASK_9, TRUE); //配置锁存
*/
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PA9 remap mode */
GPIO_InitStructure.m_Mode = GPIO_MODE_RMP;
GPIO_InitStructure.m_OpenDrain = GPIO_POD_PP;
GPIO_InitStructure.m_PullDown = GPIO_NOPULL;
GPIO_InitStructure.m_PullUp = GPIO_NOPULL;
GPIO_InitStructure.m_Speed = GPIO_LOW_SPEED;
GPIO_InitStructure.m_Pin = GPIO_PIN_MASK_9;
GPIO_Configuration(GPIOA_SFR, &GPIO_InitStructure);
/* Configure PA8 remap mode, as RX pin, it should be pullup */
GPIO_InitStructure.m_PullUp = GPIO_PULLUP;
GPIO_InitStructure.m_Pin = GPIO_PIN_MASK_8;
GPIO_Configuration(GPIOA_SFR, &GPIO_InitStructure);
GPIO_Pin_RMP_Config(GPIOA_SFR, GPIO_Pin_Num_8, GPIO_RMP_AF5_USART2);
GPIO_Pin_RMP_Config(GPIOA_SFR, GPIO_Pin_Num_9, GPIO_RMP_AF5_USART2);
}
/**
* @brief :DMA initialization of Usart
* @param in :None
* @param out :None
* @retval :None
*/
void Usart_Dma_Init(void)
{
/* Reset the DMA0 peripheral to enable the peripheral clock */
DMA_Reset(DMA0_SFR);
/*
* DMA0_TX configured as follow:
* - DMA channel selection channel 5
* - Bit width of memory = 8
* - Cyclic mode disable
*/
DMA_InitTypeDef DMA_TX_INIT,DMA_RX_INIT;
DMA_TX_INIT.m_Channel = DMA_CHANNEL_5; //这里usart2_tx是通道5
DMA_TX_INIT.m_Direction = DMA_MEMORY_TO_PERIPHERAL;//tx传输方向从内存到外设
DMA_TX_INIT.m_PeripheralDataSize = DMA_DATA_WIDTH_8_BITS;//外设传输数据位宽设置为8bit
DMA_TX_INIT.m_MemoryDataSize = DMA_DATA_WIDTH_8_BITS;//内存数据位宽设置为8bit
DMA_TX_INIT.m_Priority = DMA_CHANNEL_LOWER;
DMA_TX_INIT.m_PeripheralInc = FALSE;
DMA_TX_INIT.m_MemoryInc = TRUE;
DMA_TX_INIT.m_LoopMode = FALSE;
DMA_TX_INIT.m_BlockMode = DMA_TRANSFER_BYTE;
DMA_TX_INIT.m_MemoryAddr = (uint32_t)0;
DMA_TX_INIT.m_PeriphAddr = (uint32_t)&(USART2_SFR->TBUFR);//这里要改成usart2的发送寄存器地址
DMA_Configuration(DMA0_SFR,&DMA_TX_INIT);
/*
* DMA0_RX configured as follow:
* - DMA channel selection channel 2
* - Bit width of memory = 8
* - Number of data transmitted = 100
* - Cyclic mode disable
*/
DMA_RX_INIT.m_Channel = DMA_CHANNEL_6;//这里usart2_rx是通道6
DMA_RX_INIT.m_Direction = DMA_PERIPHERAL_TO_MEMORY;//rx传输方向从内存到外设
DMA_RX_INIT.m_PeripheralDataSize = DMA_DATA_WIDTH_8_BITS;
DMA_RX_INIT.m_MemoryDataSize = DMA_DATA_WIDTH_8_BITS;
DMA_RX_INIT.m_Priority = DMA_CHANNEL_LOWER;
DMA_RX_INIT.m_Number = 25;
DMA_RX_INIT.m_PeripheralInc = FALSE;
DMA_RX_INIT.m_MemoryInc = TRUE;
DMA_RX_INIT.m_LoopMode = TRUE;
DMA_RX_INIT.m_BlockMode = DMA_TRANSFER_BYTE;
DMA_RX_INIT.m_PeriphAddr = (uint32_t)&(USART2_SFR->RBUFR);//这里要改成usart2的接收寄存器地址
DMA_RX_INIT.m_MemoryAddr = (uint32_t)&Usart_Receive_Sdu.Data[0];//从外设端口接收的数据直接存储在内存中,这里是内存首地址
DMA_Configuration(DMA0_SFR,&DMA_RX_INIT);
}
/**
* @brief :USART transfers data using DMA
* @param in : pData : Memory first address
* nSize : Length of Data sent
* @param out :None
* @retval :None
*/
void UartDMATransmit(uint8_t *pData,uint16_t nSize)
{
DMA_Memory_Start_Address_Config(DMA0_SFR, DMA_CHANNEL_5,(uint32_t)pData);//这里传输改为通道5
DMA_Transfer_Number_Config(DMA0_SFR, DMA_CHANNEL_5,nSize);//这里传输改为通道5
USART_Transmit_Data_Enable(USART2_SFR,TRUE);//使能usart2发送
DMA_Channel_Enable (DMA0_SFR, DMA_CHANNEL_5, TRUE);//使能DMA通道5发送
}
/**
* @brief :USART receives data processing functions
* @param in : None
* @param out :None
* @retval :None
*/
void Receiving_data_processing(void)
{
/* Determines whether the data spans the end of the array */
if(Usart_Receive_Sdu.Length < pre_length)
{
/* If spanned, segmented output data */
UartDMATransmit(pre_address,100 - pre_length);
systick_delay_ms(5);
UartDMATransmit(Usart_Receive_Sdu.Data,Usart_Receive_Sdu.Length);
}else
{
/* Direct output */
UartDMATransmit(pre_address,Usart_Receive_Sdu.Length - pre_length);
}
systick_delay_ms(10);
memset(Usart_Receive_Sdu.Data, 0, Usart_Receive_Sdu.Length+2);
pre_length = Usart_Receive_Sdu.Length;
pre_address = Usart_Receive_Sdu.Data + Usart_Receive_Sdu.Length;
}
void Usart2_Init(void)
{
Usart2_GPIO_Init();
Usart_Dma_Init();
//全双工异步8bit 38400波特率
USART_Async_config(USART2_SFR);
//串口接收中断使能
USART_ReceiveInt_config(USART2_SFR,INT_USART2);
/* Tag address initialization */
pre_address = Usart_Receive_Sdu.Data;
/* Tag length initialization */
pre_length = 0;
}
#else
/////////////////////////////////////////////////////////////////////////////
void Usart_Gpio_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PA3 remap mode */
GPIO_InitStructure.m_Mode = GPIO_MODE_RMP;
GPIO_InitStructure.m_OpenDrain = GPIO_POD_PP;
GPIO_InitStructure.m_PullDown = GPIO_NOPULL;
GPIO_InitStructure.m_PullUp = GPIO_NOPULL;
GPIO_InitStructure.m_Speed = GPIO_LOW_SPEED;
GPIO_InitStructure.m_Pin = GPIO_PIN_MASK_9;
GPIO_Configuration(GPIOA_SFR, &GPIO_InitStructure);
/* Configure PE7 remap mode, as RX pin, it should be pullup */
GPIO_InitStructure.m_PullUp = GPIO_PULLUP;
GPIO_InitStructure.m_Pin = GPIO_PIN_MASK_8;
GPIO_Configuration(GPIOA_SFR, &GPIO_InitStructure);
/* Configure PA3 remap function to AF3 */
GPIO_Pin_RMP_Config(GPIOA_SFR, GPIO_Pin_Num_8, GPIO_RMP_AF5_USART2);
/* Configure PE7 remap function to AF3 */
GPIO_Pin_RMP_Config(GPIOA_SFR, GPIO_Pin_Num_9, GPIO_RMP_AF5_USART2);
}
/**
* @brief :
* @param in :None
* @param out :None
* @retval :None
*/
void USART_Send(USART_SFRmap *USARTx, Usart_Sdu_Type *Usart_Sdu)
{
for (uint32_t Send_data_count = 0; Send_data_count < Usart_Sdu->Length; Send_data_count++)
{
USART_SendData(USARTx, Usart_Sdu->Data[Send_data_count]);
while (!USART_Get_Transmitter_Empty_Flag(USARTx))
;
}
}
/**
* @brief :
* @param in :None
* @param out :None
* @retval :None
*/
void USART_Mode_Config(USART_SFRmap *USARTx)
{
USART_InitTypeDef USART_InitStructure;
USART_Struct_Init(&USART_InitStructure);
/* Set Usart To Async Mode */
USART_InitStructure.m_Mode = USART_MODE_FULLDUPLEXASY;
USART_InitStructure.m_TransferDir = USART_DIRECTION_FULL_DUPLEX;
USART_InitStructure.m_WordLength = USART_WORDLENGTH_8B;
USART_InitStructure.m_StopBits = USART_STOPBITS_1;
/* Set baudrate to 115200 */
USART_InitStructure.m_BaudRateBRCKS = USART_CLK_SCLK;
USART_InitStructure.m_BaudRateInteger = 78;
USART_InitStructure.m_BaudRateNumerator = 0;
USART_InitStructure.m_BaudRateDenominator = 0;
USART_Reset(USARTx);
USART_Configuration(USARTx, &USART_InitStructure);
USART_Passageway_Select_Config(USARTx, USART_U7816R_PASSAGEWAY_TX0);
USART_RESHD_Enable(USARTx, TRUE);
USART_Transmit_Data_Enable(USARTx, TRUE);
USART_Cmd(USARTx, TRUE);
DMA_Channel_Enable(DMA0_SFR,DMA_CHANNEL_5,TRUE);
DMA_Channel_Enable(DMA0_SFR,DMA_CHANNEL_6,TRUE);
//USART_DMA_Read_Receive_Enable(USARTx,TRUE);
//USART_DMA_Write_Transmit_Enable(USARTx,TRUE);
USART_Receive_DMA_INT_Enable(USARTx,TRUE);
USART_Transmit_DMA_INT_Enable(USARTx,TRUE);
}
/**
* @brief :
* @param in :None
* @param out :None
* @retval :None
*/
void USART_Int_Config(USART_SFRmap *USARTx, InterruptIndex Peripheral)
{
USART_Clear_Transmit_BUFR_INT_Flag(USARTx);
USART_Receive_Idle_Frame_Config(USARTx, TRUE);
USART_IDLE_INT_Enable(USARTx, TRUE);
// USART_RDR_INT_Enable(USARTx, TRUE);
// USART_TFE_INT_Enable(USARTx, TRUE);
INT_Interrupt_Enable(Peripheral, TRUE);
} |