论坛元老
 
- 积分
- 3347
- 金钱
- 3347
- 注册时间
- 2013-4-10
- 在线时间
- 333 小时
|
发表于 2016-10-23 16:32:09
|
显示全部楼层
本帖最后由 likunxue 于 2016-10-24 09:27 编辑
是的!前提是你要设置正确, DMA,会根据串口的发送状态自会发送数据,
/***************************************************************************************
函 数 名: DMA1的各通道配置
这里的传输形式是固定的,这点要根据不同的情况来修改
从存储器->外设模式/8位数据宽度/存储器增量模式
调 用: UART_DMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar)
参 数: DMA_CHx MA通道CHx
cpar:外设地址
cmar:存储器地址
返 回 值: 无
***************************************************************************************/
void UART_DMA_Config(u32 cpar,u32 cmar)
{
RCC->AHBENR |= 1<<0; //开启DMA1时钟
delay_us(20);
DMA1_Channel7->CPAR = cpar; //DMA1 外设地址
DMA1_Channel7->CMAR = cmar; //DMA1,存储器地址
DMA1_Channel7->CCR = 0x00000000; //复位
BIT_ADM(DMA1_Channel7->CCR, 4) = 1; //从存储器读
BIT_ADM(DMA1_Channel7->CCR, 5) = 0; //普通模式
BIT_ADM(DMA1_Channel7->CCR, 6) = 0; //外设地址非增量模式
BIT_ADM(DMA1_Channel7->CCR, 7) = 1; //存储器增量模式
BIT_ADM(DMA1_Channel7->CCR, 8) = 0; //外设数据宽度为8位
BIT_ADM(DMA1_Channel7->CCR,10) = 0; //存储器数据宽度8位
BIT_ADM(DMA1_Channel7->CCR,12) = 1; //中等优先级
BIT_ADM(DMA1_Channel7->CCR,14) = 0; //非存储器到存储器模式
MY_NVIC_Init(5,0,DMA1_Channel7_IRQn,4); //配置DMA中断配置
BIT_ADM(DMA1_Channel7->CCR, 1) = 1; //使能传输完成中断
}
/**************************************************************************************
函 数 名: DMA1 通道7 中断服务函数
调 用: 无
参 数: 无
返 回 值: 无
***************************************************************************************/
void DMA1_Channel7_IRQHandler(void)
{
if(BIT_ADM(DMA1->ISR,25) == 1) //DMA1通道7中断完成
{
BIT_ADM(DMA1->IFCR,25) = 1; //清除中断完成标志
while((USART2->SR & 0x40)==0); //等待发送结束
SR485_FASONGSHINENG = 0; //禁止发送(让出总线)
}
}
/*************************************************************************************
函 数 名: 初始化IO 串口2
调 用: 无
参 数: pclk1 CLK1时钟频率(Mhz)
bound:波特率
反 回 值: 无
函数编写:
**************************************************************************************/
void RS485_Init(u32 pclk1,u32 bound)
{
float temp;
u16 i, mantissa,fraction;
for(i =0; i< SUA_SIZE; i++){RX_Buf = 0; TX_Buf = 0;}//接收缓存区
RX_DAT = 0; //串口接收中的低7位数据寄存器
RX_QianZhiLing = 0; //串口接收中的低位接收标志位
RX_STR = 0; //串口接收缓存区指针
temp=(float)(pclk1*1000000)/(bound*16); //得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR |= 1<<2; //使能PORTA口时钟
GPIOA->CRL &= 0xFFFF00FF; //IO状态设置
GPIOA->CRL |= 0x00008B00; //IO状态设置
RCC->APB1ENR |= 1<<17; //使能串口时钟
RCC->APB1RSTR |= 1<<17; //复位串口2
RCC->APB1RSTR &= ~(1<<17); //停止复位
//波特率设置
USART2->BRR = mantissa; //波特率设置
USART2->CR1 |= 1<<13; //串口2使能(UE,USATR)
USART2->CR1 |= 1<<2; //接收使能(RE)
USART2->CR1 |= 1<<3; //发送使能(TE)
USART2->CR1 |= 1<<8; //PE中断使能
USART2->CR1 |= 1<<5; //接收缓冲区非空中断使能
USART2->CR3 |= 1<<7; //使能串口2的DMA发送
//DMA1通道7,外设为串口2,存储器为TX_BUF
UART_DMA_Config((u32)&USART2->DR,(u32)TX_Buf); //初始化DMA
MY_NVIC_Init(2,0,USART2_IRQn,4); //抢占5,子优先级0,组4
MOTOR_TIM7_Init(); //初始化单脉冲输出定时器7
SR485_FASONGSHINENG = 0; //禁止发送
TX_LED_OFF(); //关工作指示灯
}
/*************************************************************************************
函 数 名: 发送光栅数据
调 用: FASONGGUANGSHANSHUJU(u8 rr1)
参 数: rr1 驱动器编号
反 回 值: 无
**************************************************************************************/
void FASONGGUANGSHANSHUJU(u8 rr1)
{
if(MO_BIAOZHI[rr1] == 0xe5)
{
u16 BYTE = GUANGSHAN_CNT;
u8 S0 = (u8)BYTE;
u8 S1 = (u8)(BYTE >> 8);
while(DMA1_Channel7->CNDTR != 0); //等待通道7传输完成
SR485_FASONGSHINENG = 1; //使能发送
BIT_ADM(DMA1_Channel7->CCR ,0) = 0; //关闭DMA传输
TX_Buf[0] = S0 & 0x7f; //发送低7位
TX_Buf[1] = ((S0 >> 7) & 0x07)|0x88; //初始化指令码
TX_Buf[2] = S1 & 0x7f; //发送低7位
TX_Buf[3] = ((S1 >> 7) & 0x07)|0x98; //结束码,并使能读取
DMA1_Channel7->CNDTR = 4; //DMA1,传输数据量(4个字节)
BIT_ADM(DMA1_Channel7->CCR ,0) = 1; //开启DMA传输
}
}
红色部份代码是通过DMA,将 TX_BUF[N] 缓存区的数据通过串口发送出去
|
|