最近在做DMA接收,采用的是串口空闲中断。用的是STM32F103RC芯片。用串口助手发9000个字节数据时,发现缓存只能接收到4096个数据,发送数据小于4096时,可以完整接收到,可是明明DMA 的CNDTR寄存器设置的是9000,为什么只能接收到4096个数据呢?
[mw_shl_code=c,true]#define UART4_REC_LEN 9100
u16 UART4_RX_STA=0; //接收数据状态
u8 UART4_RX_BUF[UART4_REC_LEN]; //接收缓冲,最大UART4_RECV_LEN个字节.
void DMA_uart4_init(void)
{
RCC->AHBENR=1<<1; //使能DMA2时钟
DMA2_Channel3->CCR&=~(1<<4); //从外设读取数据
DMA2_Channel3->CCR&=~(1<<5); //不循环
DMA2_Channel3->CCR&=~(1<<6); //外设地址非增量模式
DMA2_Channel3->CCR|=1<<7; //存储器地址增量
DMA2_Channel3->CCR&=~(1<<8); //8位数据长度
DMA2_Channel3->CCR&=~(1<<10); //8位数据长度
DMA2_Channel3->CCR|=1<<12; //优先级别中
DMA2_Channel3->CCR&=~(1<<14); //非存储器到存储器模式
DMA2_Channel3->CNDTR=UART4_REC_LEN; //传输数据长度
DMA2_Channel3->CPAR =(u32)&(UART4->DR);//传输数据外设地址
DMA2_Channel3->CMAR =(u32)(UART4_RX_BUF);//传输数据存储器地址
DMA2_Channel3->CCR|=(1<<0); //开始DMA传输
}
u16 get_DMA2ch3_reclen(void)
{
return UART4_REC_LEN - DMA2_Channel3->CNDTR;
}
void UART4_IRQHandler(void)
{
if(UART4->SR&(1<<4)) //空闲中断
{
UART4_RX_STA=UART4->SR;//先读SR,然后读DR才能清除IDLE
UART4_RX_STA=UART4->DR;
UART4_RX_STA=get_DMA2ch3_reclen();
UART4_RX_STA|=1<<15; //强制标记接收完成
DMA2_Channel3->CCR&=~(1<<0); //关闭DMA传输
DMA2_Channel3->CNDTR = UART4_REC_LEN;
DMA2_Channel3->CCR|=(1<<0); //开启DMA传输
}
}
void uart4_init(u32 pclk1,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<4; //使能PORTC口时钟
RCC->APB1ENR|=1<<19; //使能串口4时钟
GPIOC->CRH&=0XFFFF00FF;//IO状态设置
GPIOC->CRH|=0X00008B00;//IO状态设置
RCC->APB1RSTR|=1<<19; //复位串口4
RCC->APB1RSTR&=~(1<<19);//停止复位
//波特率设置
UART4->BRR=mantissa; // 波特率设置
UART4->CR1|=0X200C; //1位停止,无校验位.
UART4->CR1|=1<<4; //空闲中断使能
UART4->CR3=1<<6; //使能串口4的DMA接收
// UART4->CR1|=1<<8; //PE中断使能
UART4->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,UART4_IRQn,2);//组2,最低优先级
DMA_uart4_init();
}[/mw_shl_code]
[mw_shl_code=c,true]
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
uart4_init(36,38400); //串口初始化为9600
delay_init(72); //延时初始化
while(1)
{
if(UART4_RX_STA&0X8000) //串口4接收到一次数据了
{
// data_process(UART4_RX_BUF);
UART4_RX_STA=0;
}
}
}
[/mw_shl_code]
|