STM32485串口只能发送第一个字符问题
STM32调试时发现当波特率为9600时串口助手收到程序发送出来的字符只有第一个字符,但是当把USART的波特率设置成38400时,串口助手就能收到完整的命令,哪位大神能解释下原因吗??void USART1_IRQHandler(void)
{
u8 ucUartTemp;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
ucUartTemp = USART_ReceiveData(USART1);
Usart1.TimeOutCounter = Reset;
if(Usart1.Usart_RxStatus == RX_IDLE)
{
if(ucUartTemp == Usart_StartMark )
{
Usart1.Usart_RxStatus = RX_HEAD;
Usart1.Usart_ReceiveCache = ucUartTemp;
Usart1.Usart_Cache_Where = CPOS_CMD;
}
}
else if(Usart1.Usart_RxStatus == RX_HEAD )
{
if(Usart1.Usart_Cache_Where == CPOS_Length-1)
Usart1.Usart_RxStatus = RX_Length;
Usart1.Usart_ReceiveCache = ucUartTemp;
Usart1.Usart_Cache_Where ++;
}
else if(Usart1.Usart_RxStatus == RX_Length)
{
Usart1.Usart_ReceiveCache = ucUartTemp;
Usart1.Usart_Cache_Where++;
// if((Usart1.Usart_Cache_Where > Usart1_ReceiveLength) ||
// (Usart1.Usart_Cache_Where > (Usart1.Usart_ReceiveCache -'0')*10 + (Usart1.Usart_ReceiveCache -'0')*1))
// {//接收超过限定长度
// Usart1.Err_Code = ERR_OutLength;
// Usart1.Usart_RxStatus = RX_END;
// }
if((Usart1.Usart_ReceiveCache == Usart_StartMark ) &&
Usart1.Usart_Cache_Where == Usart1.Usart_ReceiveCache )
{//正确接收完成
Usart1.Usart_RxStatus = RX_END;
}
}
}
ucUartTemp=USART1->SR;
//if(ucUartTemp==RESET)ucUartTemp=Reset;
ucUartTemp=USART1->DR;
//if(ucUartTemp==RESET)ucUartTemp=Reset;
}
void Usart1Comm_app(void)
{
if(Usart1.Usart_RxStatus == RX_END)
{
u8 i=0;
//u8* crc;
//CRC
//for(i=0;i<Usart1.Usart_Cache_Where-4;i++)
// temp8 ^= Usart1.Usart_ReceiveCache;
// if(temp8 != (u8)AsciiHEXtoInt(Usart1.Usart_ReceiveCache+Usart1.Usart_Cache_Where-2,2))
// {
// if(Usart1.Err_Code == Reset)
// Usart1.Err_Code = ERR_CRC;//CRC校验错误
// }
// else
//CRC正确
for(i=0;i<Usart1_ReportLength;i++)
Usart1.Usart_ReportCache = 0;
for(i=0;i<CPOS_CMD+1;i++)
Usart1.Usart_ReportCache = Usart1.Usart_ReceiveCache;
DeviceCode = (u8)AsciiHEXtoInt(Usart1.Usart_ReceiveCache+CPOS_Device,2);
switch (Usart1.Usart_ReceiveCache)
{
case CMD_GetVER:
{
/////////////////////////////////////Report////////////////////////////////////////////
//memcpy(Usart1.Usart_ReportCache+7,Usart1.Usart_ReceiveCache+7,Usart1.Usart_Cache_Where);
//步骤代码
Usart1.Usart_ReportCache = 0x07;
Usart1.Usart_ReportCache = 0x40;
Usart1.Usart_ReportCache = 0x96;
Usart1.Usart_RxStatus = RX_IDLE;
Usart1.Err_Code = Reset;
break;}
default:
Usart1.Err_Code = ERR_NoDefCMD;//未定义命令
break;
}
Uart_PutChar(1,Usart1.Usart_ReportCache,7);
DelayNms(1);
RS485_DE_L();
/*
//REPROT
if(Usart1.Err_Code == Reset)
{
u16 SendCharLength = 0;
SendCharLength = strlen((char *)Usart1.Usart_ReportCache);
if(SendCharLength > Usart1_ReportLength) SendCharLength = Usart1_ReportLength;
Usart1.Usart_ReportCache = SendCharLength + CrcLength;
//Usart1.Usart_ReportCache = (SendCharLength + CrcLength)% 10/1+ '0';;
//CRC
//temp8 = 0;
//for(i=0;i<SendCharLength;i++)
//temp8 ^= Usart1.Usart_ReportCache;
//Usart1.Usart_ReportCache = (((u16)temp8/16)<=9)?((u16)temp8/16+'0'):((u16)temp8/16-9+'@');
//Usart1.Usart_ReportCache = (((u16)temp8%16)<=9)?((u16)temp8%16+'0'):((u16)temp8%16-9+'@');
//crc=CRC162(Usart2.Usart_ReportCache,i);//计算CRC校验值
//Usart2.Usart_ReportCache = *(crc+i);
//i++;
//Usart2.Usart_ReportCache = *(crc+i);
//i++;
//Usart2.Usart_ReportCache = *(crc+i);
//i++;
//Usart2.Usart_ReportCache = *(crc+i);
//i++;
Uart_PutChar(1,Usart1.Usart_ReportCache, SendCharLength);
//for (i=0;i<7;i++)
//Usart1.Usart_ReceiveCache=0;
SYS_ReStart = Reset;
}
else
{//
SYS_ERRStatus = Set;
Usart1.Usart_RxStatus = RX_IDLE;
}*/
}
}
voidUsart2Comm_app (void)
{
if(Usart2_Receiver_Over)
{
Usart2_Receiver_Over = 0;
}
}
voidUsart3Comm_app (void)
{
if(Usart3_Receiver_Over)
{
Usart3_Receiver_Over = 0;
}
}
voidUsart4Comm_app (void)
{
if(Usart4_Receiver_Over)
{
Usart4_Receiver_Over = 0;
}
}
voidUsart5Comm_app (void)
{
if(Usart5_Receiver_Over)
{
Usart5_Receiver_Over = 0;
}
}
/*
void Usart3_init(u32 bdr)
{
USART_Cmd(USART1, DISABLE);//
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = bdr; //设定传输速率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //设定传输数据位数偶校验9位
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_Rx | USART_Mode_Tx; //使用接收和发送功能
USART_Init(USART1, &USART_InitStructure);//初始化串口1
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1, ENABLE);//使能串口1
}
*/
void Five_usart_init(void)
{
/* Timer Clock configuration ------------------------------------------------*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 ,ENABLE);
//RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2 ,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);
/* Timer Interrupt configuration ---------------------------------------------*/
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//4组抢占 4组从优先
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_Init(&NVIC_InitStructure);
//NVIC_InitStructure.NVIC_IRQChannel = USART5_IRQChannel;
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//NVIC_Init(&NVIC_InitStructure);
/* Usart configuration ---------------------------------------------*/
Usart_init(USART1,Usart1_BandRate,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,USART_HardwareFlowControl_None);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1, ENABLE);
//使能u1-tx DMA发送
Usart_DMAtx_init(USART1,DMA1_Channel4);
DMA_Cmd(DMA1_Channel4, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
Usart_init(USART2,Usart2_BandRate,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,USART_HardwareFlowControl_None);
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
//USART_Cmd(USART2, ENABLE);//使能串口2
Usart_init(USART3,Usart3_BandRate,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,USART_HardwareFlowControl_None);
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
// USART_Cmd(USART3, ENABLE);//使能串口3
Usart_init(UART4,Usart4_BandRate,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,USART_HardwareFlowControl_None);
USART_ITConfig(UART4,USART_IT_RXNE,ENABLE);
//USART_Cmd(UART4, ENABLE);//使能串口4
Usart_init(UART5,Usart5_BandRate,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,USART_HardwareFlowControl_None);
USART_ITConfig(UART5,USART_IT_RXNE,ENABLE);
//USART_Cmd(UART5, ENABLE);//使能串口5
DelayNms(50);
/* Timer GPIO configuration ------------------------------------------------*/
Set_Port_Status(GPIO_A,GPIO_Pin_9,GPIO_Mode_AF_PP); //TX1
Set_Port_Status(GPIO_A,GPIO_Pin_10,GPIO_Mode_IN_FLOATING); //RX1
Set_Port_Status(GPIO_A,GPIO_Pin_2,GPIO_Mode_AF_PP); //TX2
Set_Port_Status(GPIO_A,GPIO_Pin_3,GPIO_Mode_IN_FLOATING);//RX2
Set_Port_Status(GPIO_B,GPIO_Pin_10,GPIO_Mode_AF_PP); //TX3
Set_Port_Status(GPIO_B,GPIO_Pin_11,GPIO_Mode_IN_FLOATING); //RX3
Set_Port_Status(GPIO_C,GPIO_Pin_10,GPIO_Mode_AF_PP); //TX4
Set_Port_Status(GPIO_C,GPIO_Pin_11,GPIO_Mode_IN_FLOATING); //RX4
//Set_Port_Status(GPIO_C,GPIO_Pin_12,GPIO_Mode_AF_PP); //TX5
//Set_Port_Status(GPIO_C,GPIO_Pin_13,GPIO_Mode_IN_FLOATING); //RX5
}
/*******************************************************************************
*函数名称:
*******************************************************************************/
void Usart_init(USART_TypeDef* USARTx,u32 Usartx_BandRate,u16 USARTx_WordLength,u16 USARTx_StopBits,u16 USARTx_Parity,u16 USARTx_HardwareFlowControl)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = Usartx_BandRate;
USART_InitStructure.USART_WordLength = USARTx_WordLength;
USART_InitStructure.USART_StopBits = USARTx_StopBits;
USART_InitStructure.USART_Parity = USARTx_Parity;
USART_InitStructure.USART_HardwareFlowControl = USARTx_HardwareFlowControl;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USARTx, &USART_InitStructure);
}
/*******************************************************************************
*函数名称:
*******************************************************************************/
void Usart_DMAtx_init(USART_TypeDef* USARTx,DMA_Channel_TypeDef * DMAx_Channelx)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USARTx->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(&USARTx->DR);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMAx_Channelx, &DMA_InitStructure);
}
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;// | GPIO_Pin_2;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIO_Init(GPIOA, &GPIO_InitStructure);
///*
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
//GPIO_Init(GPIOB, &GPIO_InitStructure);
//
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;//| GPIO_Pin_12;
//GPIO_Init(GPIOC, &GPIO_InitStructure);
//*/
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;// | GPIO_Pin_3;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//GPIO_Init(GPIOA, &GPIO_InitStructure);
//
////GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
////GPIO_Init(GPIOB, &GPIO_InitStructure);
//
////GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
////GPIO_Init(GPIOC, &GPIO_InitStructure);
//
////GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
////GPIO_Init(GPIOD, &GPIO_InitStructure);
//******************************************************************************
// 函数名称 : UART1_PutChar()
// 功能描述 : 串口1发送数据函数.
// 输入 : u8 ch 要发送的数据
// 输出 : None
// 返回 : None
//******************************************************************************
voidUart_PutChar(u8 CH,u8 *p,u8 NUM)
{
u16 i=0;
u8 j=0;
switch(CH)
{
case 1:
//USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);
//USART_ClearITPendingBit(USART1,USART_IT_RXNE);
//USART_ClearITPendingBit(USART1,USART_IT_IDLE);
//USART_ClearITPendingBit(USART1,USART_IT_ORE);
//USART_ClearFlag(USART1,USART_FLAG_RXNE);
//USART_ClearFlag(USART1,USART_FLAG_IDLE);
//USART_ClearFlag(USART1,USART_FLAG_ORE);
//GPIOA->CRH |= 0x00000300; //RX端口设置 设为输出模式 防止进入usart-ORE中断
//DMA_Send585_END=0;
//DMA_Send585_END_Timer=0;//用于延迟485使能端
//GPIO_SetBits(GPIOA, GPIO_Pin_10);
RS485_DE_H();
DelayNms(5);
DMA_Cmd(DMA1_Channel4, DISABLE);
DMA1_Channel4->CNDTR=NUM;
DMA1_Channel4->CMAR=(u32)p;
DMA_Cmd(DMA1_Channel4, ENABLE);
break;
case 2:
for(i=0;i<NUM;i++)
{
j = *(p+i);
USART2->DR = (j & (u16)0x01FF);
while(!(USART2->SR & USART_FLAG_TXE));
}
break;
case 3:
for(i=0;i<NUM;i++)
{
j = *(p+i);
USART3->DR = (j & (u16)0x01FF);
while(!(USART3->SR & USART_FLAG_TXE));
}
break;
case 4:
for(i=0;i<NUM;i++)
{
j = *(p+i);
UART4->DR = (j & (u16)0x01FF);
while(!(UART4->SR & USART_FLAG_TXE));
}
break;
case 5:
for(i=0;i<NUM;i++)
{
j = *(p+i);
UART5->DR = (j & (u16)0x01FF);
while(!(UART5->SR & USART_FLAG_TXE));
}
break;
}
}
下面串口助手接收的信息
485芯片是半双工芯片,发送的时候要把芯片置为发送模式,在发送完成后芯片置为接收模式,你的问题是在发送完毕后,程序内部状态是发送完毕,但是实质最后一个字节数据在硬件层没有发送完毕,这时候你将485芯片置为接收状态,最后一个字节会发送失败,在波特率越低状态下越明显,所以你检测到发送完成后。人为延时1ms,问题就会解决了,你可以试一试。 楼主,从现象来看,是发生了数据丢失,如果不用DMA会不会发生丢失的情况。 安 发表于 2017-5-19 09:59
楼主,从现象来看,是发生了数据丢失,如果不用DMA会不会发生丢失的情况。 ...
如果是数据丢失的话也应该是延时的问题感觉,毕竟在38400波特率下数据并没有丢失而只在9600的情况下才丢失了 波特率越高,发送时间越短。波特率低的情况下丢失,很多是因为数据传输太快导致。 明白,我去试试不用DMA传送数据。 DMA发送后中断标识位未清空 wolfgang2015 发表于 2017-5-19 13:18
DMA发送后中断标识位未清空
清空的
void DMA1_Channel4_IRQHandler(void)
{//485发送完成中断
if(DMA_GetITStatus(DMA1_IT_TC4))
{
DMA_ClearITPendingBit(DMA1_FLAG_TC4);
DMA_Send585_END=1;
//TIM_Cmd(TIM8, ENABLE);
}
}
进来看看了,吗,,,, 楼主,用DMA传输的时候,能不能一次多传输一些数据,不要一个字节一个字节的传输。如果单字节传输时,考虑判断一下上次数据发送完成,再进行下次发送。
页:
[1]