串口3的发送中断配置好后,为什么立即发送失败,但等候大约1s时间后,发送却能够正常?
串口的配置是没有问题的,关键是上述的那个问题?
“立即发送失败”的具体含义是什么?如何判断的?
“等候大约1s时间后,发送正常”,那么等候0.1s后有什么结果?等候0.5s后又有什么结果?最少需要等候多长时间才发送正常?
串口3初始化:
void Init_Uart3(void)
{
u32 tmpreg = 0x00;
u32 integerdivider = 0x00;
u32 fractionaldivider = 0x00;
RCC->APB2ENR|=RCC_APB2ENR_IOPBEN;
GPIOB->CRH&=0xFFFF00FF;GPIOB->CRH|=0x00004B00;//PA_10复用功能推挽输出,最大50MHZA_11浮空输入
RCC->APB1ENR|=0x00040000;//使能APB1总线上的UART3时钟
/* Determine the integer part */
integerdivider=((0x19*PCLK1)/(0x04*(BaudRate_UART3)));
tmpreg=(integerdivider/0x64)<<0x04;
/* Determine the fractional part */
fractionaldivider=integerdivider-(0x64*(tmpreg>>0x04));
tmpreg|=((((fractionaldivider*0x10)+0x32)/0x64))&((u8)0x0F);
/* Write to USART BRR */
USART3->BRR=(u16)tmpreg;
USART3->CR1|=0x0000000C;//接收,发送使能
USART3->CR1|=0x00000020;//接收缓冲区非空中断使能
NVIC->ISER[1]|=(1<<(USART3_IRQChannel&0x1F));
USART3->CR1|=0x00002000;//UART1使能
}
串口3用DMA(DMA1 CH2)发送:
/*******************************************************************************
*函数名 : Init_DMA1_Ch2 *
*参数 : 无 *
*返回值 : 无 *
*功能 : 初始化Init_DMA1_Ch4 *
*******************************************************************************/
void Init_DMA1_Ch2(void)
{
RCC->AHBENR|=0x00000001;//AHB外设的DMA1时钟使能
DMA1_Channel2->CCR|=(1<<12);
DMA1_Channel2->CCR|=((1<<1)|(1<<3)|(1<<4)|(1<<7)|(1<<8));
NVIC->ISER[0]|=(vu32)(1<<12);//NVIC设置允许DMA1_Ch2中断
}
/*******************************************************************************
*函数名 : DMAChannel2_IRQHandler *
*参数 : 无 *
*返回值 : 无 *
*功能 : DMA1通道4全局中断服务程序 *
*******************************************************************************/
void DMAChannel2_IRQHandler(void)
{
if((DMA1->ISR&0x00000080)==0x00000080){DMA1->IFCR|=0x00000080;}
if((DMA1->ISR&0x00000020)==0x00000020)
{
DMA1->IFCR|=0x00000020;
USART3->CR3&=0xFFFFFF7F;//DMA发送禁止
Uart3_Sen_En=0;
}
DMA1->IFCR|=0x00000010;//清全局中断标识
}
串口3发送函数(定长):
void Uart3_Sen_Via_Str_Length(const vu8 Sen_Data[],vu16 Data_Len)
{
while(Uart3_Sen_En);
p1=Uart3_Sen_Buf;p2=Sen_Data;
if(Data_Len>=1)
{
for(i=0;i<Uart3_Sen_Max_Len;i++)
{
*p1=*p2;if(i==(Data_Len-1)){i=Uart3_Sen_Max_Len;}else{p1++;p2++;}
}
Uart3_Sen_En=1;
DMA1_Channel2->CCR&=0xFFFFFFFE;
DMA1_Channel2->CPAR=(vu32)&USART3->DR;//外设地址寄存器
DMA1_Channel2->CMAR=(vu32)Uart3_Sen_Buf;//设置地址
DMA1_Channel2->CNDTR=Data_Len;//发送的个数
USART3->CR3|=0x00000080;//DMA使能发送
DMA1_Channel2->CCR|=0x00000001;
}
}
另外说说STM32F101,3串口发送中断,有时候TC(发送完成)中断根本就不会产生(偷懒),判断串口发送中断标识最好用“发送寄存器空中断”而非“TC中断”。
..初始化配置:
......................
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
//使能串口发送中断
USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
USART_Cmd(USART3, ENABLE);
中断:
void USART3_IRQHandler(void)
{
uint8_t yy = 0 ;
if(USART_GetITStatus(USART3, USART_IT_RXNE) == SET)
{
USART_ClearITPendingBit(USART3,USART_IT_RXNE);
yy = USART3->DR ;
}
if(USART_GetITStatus(USART3, USART_IT_TXE) == SET)
{
USART_ClearITPendingBit(USART3,USART_IT_TXE);
//USART1_IRQ_Fun();
}
}
然后程序直接进入到发送中断,出不来
发送完最后一个数据后应该禁止“发送寄存器空中断”吧,当写第一个数据到发送寄存器后再打开中断,
9楼的方法可行,试过的。与pic18F的发送使能类似了。