本帖最后由 ZLI 于 2019-4-2 09:29 编辑
//DMA2接收串口4
//**********************************************
#include"dma.h"
#include "sys.h"
#include "delay.h"
u16 DMA2_MEM_LEN;//保存 DMA 每次数据传送的长度
//DMA2 的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8 位数据宽度/存储器增量模式
//DMA_CHx
MA 通道 CHx
//cpar:外设地址
//cmar:存储器地址
//cndtr:数据传输量
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC->AHBENR|=1<<1; //开启 DMA2 时钟
delay_ms(5); //等待 DMA 时钟稳定
DMA_CHx->CPAR=cpar; //DMA2 外设地址
DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址
DMA2_MEM_LEN=cndtr; //保存 DMA 传输数据量
DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量
DMA_CHx->CCR=0X00000000; //复位
DMA_CHx->CCR|=0<<4; //从外设读
DMA_CHx->CCR|=1<<5; //循环模式
DMA_CHx->CCR|=0<<6; //外设地址非增量模式
DMA_CHx->CCR|=1<<7; //存储器增量模式
DMA_CHx->CCR|=0<<8; //外设数据宽度为 8 位
DMA_CHx->CCR|=0<<10; //存储器数据宽度 8 位
DMA_CHx->CCR|=1<<12; //中等优先级
DMA_CHx->CCR|=0<<14; //非存储器到存储器模式
}
//开启一次 DMA 传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
DMA_CHx->CCR&=~(1<<0); //关闭 DMA 传输
DMA_CHx->CNDTR=DMA2_MEM_LEN; //DMA2,传输数据量
DMA_CHx->CCR|=1<<0; //开启 DMA 传输
}
//***********************************************
//************************************************
//初始化IO 串口4
//pclk2
CLK2时钟频率(Mhz)
//bound:波特率
//************************************************
#if EN_UART4_RX //如果使能了接收
u8 UART4_RX_BUF[UART4_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
u16 UART4_RX_STA=0; //接收状态标记
void UART4_IRQHandler(void)
{
u8 res=0;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(UART4->SR&(1<<5)) //接收到数据
{
res = UART4->DR;
if((UART4_RX_STA&0x4000)==0)//还未接收完毕
{
if(UART4_RX_STA&0x8000) //已经接收到包头
{
UART4_RX_STA++; //增加数据个数
UART4_RX_BUF[UART4_RX_STA&0x0FFF]=res;//数据储存
if((UART4_RX_STA&0x0FFF)==32) //32个说明一帧接收完成
UART4_RX_STA|=0x4000;//置结束标志位
}
else if( UART4_RX_STA & 0x2000 ) //接收到加速度标志
{
if(res==0x51) //如果已经置包头标志
{
UART4_RX_STA&=~(0x2000);//清出标志
UART4_RX_STA|=0x8000;//成功接收包头
UART4_RX_BUF[UART4_RX_STA&0x0FFF]=res;
}
else
UART4_RX_STA=0;//重新接收
}
else if(res == 0x55) //接收到包头
{
UART4_RX_STA|=0x2000; //置包头标志?
UART4_RX_BUF[UART4_RX_STA&0x0FFF]=res;
UART4_RX_STA++; //USART2_RX_STA=1;
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
#endif
//****************************************************
//初始化IO 串口4
//pclk2
CLK2时钟频率(Mhz)
//bound:波特率
//****************************************************
void uart4_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*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位停止,无校验位..
#if EN_UART4_RX //如果使能了接收
//使能接收中断
UART4->CR1|=1<<5; //???????????
MY_NVIC_Init(3,3,UART4_IRQn,2);//组2,最低优先级
#endif
// UART4->CR3|=1<<6; //DMA
}
主要是因为看了那个中文手册是错的
一周热门 更多>