本帖最后由 blavy 于 2018-3-26 16:09 编辑
调试DMA加串口的时候,发送数据是成功了,但是接收数据一直都是0,查了初始化与中断,好象都没问题啊。
懂的人解一下惑吧。
/*
发送的DMA初始化
*/
void MYDMA_TX_Cfg(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC->AHBENR|=RCC_AHBPeriph_DMA1; //开启DMA1时钟
delay_ms(5); //等待DMA时钟稳定,必须延时
DMA_CHx->CPAR=cpar; //DMA1 外设地址
DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址
DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量
DMA_CHx->CCR=0; //复位
DMA_CHx->CCR|=(1<<1); //使能完成中断
DMA_CHx->CCR|=1<<4; //从存储器读
DMA_CHx->CCR&=~(1<<5); //普通模式
DMA_CHx->CCR&=~(1<<6); //外设地址非增量模式
DMA_CHx->CCR|=1<<7; //存储器增量模式
DMA_CHx->CCR&=~(1<<8); //外设数据宽度为8位
DMA_CHx->CCR&=~(1<<10); //存储器数据宽度8位
DMA_CHx->CCR|=1<<12; //中等优先级
DMA_CHx->CCR&=~(1<<14); //非存储器到存储器模式
MY_NVIC_Init(3,3,DMA1_Channel4_IRQChannel,2);
}
/*
接收的DMA初始化
*/
void MYDMA_RX_Cfg(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC->AHBENR|=RCC_AHBPeriph_DMA1; //开启DMA1时钟
delay_ms(5); //等待DMA时钟稳定,必须延时
DMA_CHx->CPAR=cpar; //DMA1 外设地址
DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址
DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量
DMA_CHx->CCR=0; //复位
DMA_CHx->CCR&=~(1<<4); //从外设串口读
DMA_CHx->CCR&=~(1<<5); //普通模式
DMA_CHx->CCR&=~(1<<6); //外设地址非增量模式
DMA_CHx->CCR|=1<<7; //存储器增量模式
DMA_CHx->CCR&=~(1<<8); //外设数据宽度为8位
DMA_CHx->CCR&=~(1<<10); //存储器数据宽度8位
DMA_CHx->CCR|=1<<12; //中等优先级
DMA_CHx->CCR&=~(1<<14); //非存储器到存储器模式
DMA_CHx->CCR|=(1<<0); //启动DMA
}
/*
*/
void MYDMA_Enable(DMA_Channel_TypeDef *DMA_CHx)
{
DMA_CHx->CCR&=~(1<<0); //关闭DMA传输
DMA_CHx->CNDTR=BUFF_LEN; //DMA1,传输数据量
DMA_CHx->CCR|=(1<<0); //开启DMA传输
}
/*
DMA发送完成中断
*/
void DMA1_Channel4_IRQHandler(void)
{
if(DMA1->ISR&(1<<13)) //等待通道4传输完成 BIT: TCIF
{
DMA1->IFCR|=1<<13; //清除通道4传输完成标志 BIT: CTCIF
// printf("
SEND!!
");
}
}
void Usart1_Init(unsigned int pclk2,unsigned int bound)
{
float temp;
unsigned short mantissa;
unsigned short fraction;
//Tx/Rx 波特率=fck/(16*( USARTDIV))
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分 ----无符号整数 与 浮点数的运算
fraction=(temp-mantissa)*16; //得到小数部分 浮点数 - 无符号整数 = 浮点数
mantissa<<=4; // USARTDIV的整数部分 ---bit4~bit15
mantissa+=fraction; // USARTDIV的小数部分 ---bit0~bit3
RCC->APB2ENR |= (RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1); //使能PORTA口时钟,使能串口时钟
GPIOA->CRH &= (GPIO_Crh_P9 & GPIO_Crh_P10); //IO状态设置 : USART1_TX PA.9,USART1_RX PA.10
GPIOA->CRH |= (GPIO_Mode_IN_PU_PD_P10 | GPIO_Mode_AF_PP_50MHz_P9); //IO状态设置:TX---复用推挽输出,RX---下拉输入
RCC->APB2RSTR |= RCC_APB2Periph_USART1; //复位串口1
RCC->APB2RSTR &= ~RCC_APB2Periph_USART1; //停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1 |= (USART_ENABLE | USART_Mode_Rx | USART_Mode_Tx); //默认:一个起始位,8个数据位,1位停止,无校验位.
#if EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1|= (USART_PEIE | USART_RXNEIE); //PE中断使能,接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQChannel,2); //组2(4组抢占(0,1,2,3),4组优先(0,1,2,3)),最低抢占级,最低优先级
#endif
}
//如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
//接收状态
void USART1_IRQHandler(void)
{
UINT8 cnt=0;
volatile unsigned char res;
if(USART1->SR&(1<<4))
{//空闲中断
res = USART1->SR;
res = USART1->DR;
DMA1_Channel5->CCR &= ~(1<<0);
printf("
REVIEVED!!%d",(RCV_LEN-DMA1_Channel5->CNDTR));
printf("
");
for(cnt=0; cnt<RCV_LEN; cnt++)
{
printf("%02x ",RcvBuf[cnt]);
}
DMA1_Channel5->CNDTR=RCV_LEN; //DMA1,传输数据量
DMA1_Channel5->CMAR=(UINT32)RcvBuf;
DMA1_Channel5->CCR|=(1<<0); //开启DMA传输
}
}
主程序main.cj里面f进行初始化调用
#define BUFF_LEN 30
#define RCV_LEN 5
UINT8 SndBuf[BUFF_LEN] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,10};
UINT8 RcvBuf[RCV_LEN];
MYDMA_TX_Cfg(DMA1_Channel4,(u32)&USART1->DR,(u32)SndBuf,BUFF_LEN);//DMA1通道4,外设为串口1,存储器为SendBuff,长(TEXT_LENTH+2)*100.
MYDMA_RX_Cfg(DMA1_Channel5,(u32)&USART1->DR,(u32)RcvBuf,RCV_LEN);//DMA1通道5,外设为串口1,存储器为SendBuff,长(TEXT_LENTH+2)*100.
一周热门 更多>