//#define DMA2_Stream7_Tx1 DMA2_Stream7
//#define DMA2_Stream2_Rx1 DMA2_Stream2
void uart1_dma_tx(void)
{
u8 len=50;
u8 crc=0x33;
u8 i;
//******数据发送位******
//包头
g_TxBuffer1[0]=0xBB;
g_TxBuffer1[1]=0x66;
g_TxBuffer1[2]=0x15;
g_TxBuffer1[3]=len;
//数据区
//包尾
g_TxBuffer1[49]=crc;
//******数据发送******
uart1_send_dma(g_TxBuffer1, len);
}
//
//
void Ctr_Modbus1(void)
{
u8 i;
u8 Command = 0;
u8 board=0;
u8 Cmd_length=0;
if (g_UartState1 == UART_RECV1) //接收完成
{
i = Ctr_DataLength1;//10长度
/*******包头*****/
if( (Ctr_Rx_Buffer1[0] != 0xBB) || (Ctr_Rx_Buffer1[1] != 0x66))
return ;
/*******板子连接类型*****/
board=Ctr_Rx_Buffer1[2];//长度
/*******cmd*****/
Command = Ctr_Rx_Buffer1[3];//指令
Cmd_length=Ctr_Rx_Buffer1[4];//长度
switch (Command)
{
}
}
g_UartState1 = UART_IDLE1;
}
e1 = UART_IDLE1;}
stm32f405串口 DMA+空闲中断 不定长数据收发代码
#include "sys.h"
#include "usart.h"
#include
#include "led.h"
//
//
/*
//1,串口通信
UART1_TX PA9 DMA2_Stream7
UART1_RX PA10 DMA2_Stream2
UART2_TX PA2 DMA1_Stream6
UART2_RX PA3 DMA1_Stream5
UART3_TX PB10 DMA1_Stream3
UART3_RX PB11 DMA1_Stream1
UART4_TX PC10 DMA1_Stream4
UART4_RX PC11 DMA1_Stream2
UART5_TX PC12 DMA1_Stream7
UART5_RX PD2 DMA1_Stream0
UART6_TX PC6 DMA2_Stream6
UART6_RX PC7 DMA2_Stream1
*/
#define DMA2_Stream7_Tx1 DMA2_Stream7
#define DMA2_Stream2_Rx1 DMA2_Stream2
#define DMA1_Stream6_Tx2 DMA1_Stream6
#define DMA1_Stream5_Rx2 DMA1_Stream5
#define DMA1_Stream3_Tx3 DMA1_Stream3
#define DMA1_Stream1_Rx3 DMA1_Stream1
#define DMA1_Stream4_Tx4 DMA1_Stream4
#define DMA1_Stream2_Rx4 DMA1_Stream2
#define DMA1_Stream7_Tx5 DMA1_Stream7
#define DMA1_Stream0_Rx5 DMA1_Stream0
#define DMA2_Stream6_Tx6 DMA2_Stream6
#define DMA2_Stream1_Rx6 DMA2_Stream1
//
//
//串口1数据
uint8_t g_RxBuffer1[UART_BUF_SIZE1]; //接收缓冲1
uint8_t g_TxBuffer1[UART_BUF_SIZE1]; //发送缓冲1
uint8_t volatile g_UartState1; //UART1工作状态标记
//通讯1数据缓存
u8 Ctr_Rx_Buffer1[UART_BUF_SIZE1]; //通信用缓冲区
u8 Ctr_Tx_Buffer1[UART_BUF_SIZE1]; //通信用缓冲区
uint16_t Ctr_DataLength1;
///
///
void DMA_Configuration1(void);
void uart1_dma_init(uint16_t BaudRate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 1.使能PA口时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* 2.管脚映射 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); /* GPIOA9复用为USART2 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); /* GPIOA10复用为USART2 */
/* 4.配置串口1的PA9和PA10管脚 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure); /* TXIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure); /* RXIO */
/* 5.配置串口工作模式 */
USART_DeInit(USART1);
USART_InitStructure.USART_BaudRate = BaudRate*100;//接电机控制
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* 6.设置中断 */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* 7.配置串口中断 */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// USART_ITConfig(USART1, USART_IT_TC, DISABLE);
// USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);/* 使能IDLE中断 */
/* 8.使能串口 */
USART_Cmd(USART1, ENABLE);//使能串口
/* 9.DMA配置*/
DMA_Configuration1();
g_UartState1 = UART_IDLE1;
}
///
//*********************串口1DMA设置********************//
//#define DMA2_Stream7_Tx1 DMA2_Stream7
//#define DMA2_Stream2_Rx1 DMA2_Stream2
//uint8_t g_RxBuffer1[UART_BUF_SIZE1]; //接收缓冲1
//uint8_t g_TxBuffer1[UART_BUF_SIZE1]; //发送缓冲1
//uint8_t volatile g_UartState1; //UART1工作状态标记
void DMA_Configuration1(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* 1.使能DMA2时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* 2.配置使用DMA发送数据 */
DMA_DeInit(DMA2_Stream7_Tx1);
DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 配置DMA通道 */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR)); /* 目的 */
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)g_TxBuffer1; /* 源 雷达的数据*/
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /* 方向 */
DMA_InitStructure.DMA_BufferSize = UART_BUF_SIZE1; /* 长度 */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址是否自增 */
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 内存地址是否自增 */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; /* 目的数据带宽 */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* 源数据宽度 */
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 单次传输模式/循环传输模式 */
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; /* DMA优先级 */
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式/直接模式 */
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 单次传输 */
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
/* 3. 配置DMA */
DMA_Init(DMA2_Stream7_Tx1, &DMA_InitStructure);
/* 4.使能DMA中断 */
// DMA_ITConfig(DMA2_Stream7_Tx1, DMA_IT_TC, ENABLE);
// DMA_ITConfig(DMA2_Stream7_Tx1, DMA_IT_TE, ENABLE);
/* 5.使能串口的DMA发送接口 */
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
/* 7.不使能DMA */
DMA_Cmd(DMA2_Stream7_Tx1, DISABLE);
/* 2.配置使用DMA接收数据 */
DMA_DeInit(DMA2_Stream2_Rx1);
DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 配置DMA通道 */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR)); /* 目的 */
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)g_RxBuffer1; /* 源 雷达的数据*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /* 方向 */
DMA_InitStructure.DMA_BufferSize = UART_BUF_SIZE3; /* 长度 */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址是否自增 */
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 内存地址是否自增 */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; /* 目的数据带宽 */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* 源数据宽度 */
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 单次传输模式/循环传输模式 */
DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* DMA优先级 */
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式/直接模式 */
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 单次传输 */
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
/* 3. 配置DMA */
DMA_Init(DMA2_Stream2_Rx1, &DMA_InitStructure);
/* 4.使能DMA中断 */
// DMA_ITConfig(DMA2_Stream2_Rx1, DMA_IT_TC, ENABLE);
// DMA_ITConfig(DMA2_Stream2_Rx1, DMA_IT_TE, ENABLE);
// DMA_ITConfig(DMA2_Stream2_Rx1, DMA_IT_HT, ENABLE);
/* 5.使能串口的DMA发送接口 */
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
/* 7.使能DMA */
DMA_Cmd(DMA2_Stream2_Rx1, ENABLE);
}
//
//
extern u32 wcntCK_uartrx_over[6];//接收超时
extern u8 uflagCK_uartrx_over[6];//接收超时
u8 uflagCK_Ctr_Modbus[6];//接收超时
void Ctr_Modbus1(void);
//空闲中断
void USART1_IRQHandler(void)
{
u16 data, i;
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
//读SR后读DR清除Idle,下面2行代码不能少,也不能用USART_ClearITPendingBit(USART1, USART_IT_IDLE);来代替
data = USART1->SR;
data = USART1->DR;
//关闭DMA,防止处理其间有数据
DMA_Cmd(DMA2_Stream2_Rx1, DISABLE); //关闭DMA,防止处理其间有数据
//读数据
Ctr_DataLength1 =UART_BUF_SIZE1 - DMA_GetCurrDataCounter(DMA2_Stream2_Rx1);
//处理数据
if (Ctr_DataLength1 > 0)
{
for (i = 0; i < Ctr_DataLength1; i++) //将数据送DMA存储地址
{
Ctr_Rx_Buffer1 = g_RxBuffer1;
}
}
//重新开始接受DMA数据
DMA_Cmd(DMA2_Stream2_Rx1, DISABLE); //改变datasize前先要禁止通道工作
DMA_ClearFlag(DMA2_Stream2_Rx1, DMA_FLAG_TCIF2 | DMA_FLAG_FEIF2 | DMA_FLAG_DMEIF2 | DMA_FLAG_TEIF2 | DMA_FLAG_HTIF2); //清除DMA2_Steam7传输完成标志
DMA_SetCurrDataCounter(DMA2_Stream2_Rx1, UART_BUF_SIZE1);
DMA_Cmd(DMA2_Stream2_Rx1, ENABLE);
g_UartState1 = UART_RECV1;
// Ctr_Modbus1();//控制通讯 放入主定时循环里
}
}
//
//#define DMA2_Stream7_Tx1 DMA2_Stream7
//#define DMA2_Stream2_Rx1 DMA2_Stream2
//发送完成中断
void DMA2_Stream7_IRQHandler(void)
{
u16 data, i;
//清除标志
if(DMA_GetFlagStatus(DMA2_Stream7_Tx1, DMA_FLAG_TCIF7) != RESET) //等待DMA2_Steam7传输完成
{
DMA_ClearFlag(DMA2_Stream7_Tx1, DMA_FLAG_TCIF7); //清除DMA2_Steam7传输完成标志
}
}
//接收通道中断
void DMA2_Stream2_IRQHandler(void)
{
u16 data, i;
//清除标志
if(DMA_GetFlagStatus(DMA2_Stream2_Rx1, DMA_FLAG_TCIF2) != RESET) //等待DMA2_Steam7传输完成
{
DMA_ClearFlag(DMA2_Stream2_Rx1, DMA_FLAG_TCIF2); //清除DMA2_Steam7传输完成标志
}
}
//
//dma数据发送
//#define DMA2_Stream7_Tx1 DMA2_Stream7
//#define DMA2_Stream2_Rx1 DMA2_Stream2
void uart1_send_dma(uint8_t *buf, uint8_t len)
{
DMA_InitTypeDef DMA_InitStructure;
/* 1.使能DMA1时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* 2.配置使用DMA发送数据 */
DMA_DeInit(DMA2_Stream7_Tx1);
DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 配置DMA通道 */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR)); /* 目的 */
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buf;//数据 /* 源 雷达的数据*/
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /* 方向 */
DMA_InitStructure.DMA_BufferSize = len;//长度 /* 长度 */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址是否自增 */
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 内存地址是否自增 */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; /* 目的数据带宽 */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* 源数据宽度 */
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 单次传输模式/循环传输模式 */
DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* DMA优先级 */
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式/直接模式 */
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 单次传输 */
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream7_Tx1, &DMA_InitStructure);
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
DMA_ITConfig(DMA2_Stream7_Tx1, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA2_Stream7_Tx1, ENABLE);
}
//
//DMA发送多字节
//开启一次DMA传输
//数据:g_TxBuffer1
//#define DMA2_Stream7_Tx1 DMA2_Stream7
//#define DMA2_Stream2_Rx1 DMA2_Stream2
void uart1_dma_tx(void)
{
u8 len=50;
u8 crc=0x33;
u8 i;
//******数据发送位******
//包头
g_TxBuffer1[0]=0xBB;
g_TxBuffer1[1]=0x66;
g_TxBuffer1[2]=0x15;
g_TxBuffer1[3]=len;
//数据区
//包尾
g_TxBuffer1[49]=crc;
//******数据发送******
uart1_send_dma(g_TxBuffer1, len);
}
//
//
void Ctr_Modbus1(void)
{
u8 i;
u8 Command = 0;
u8 board=0;
u8 Cmd_length=0;
if (g_UartState1 == UART_RECV1) //接收完成
{
i = Ctr_DataLength1;//10长度
/*******包头*****/
if( (Ctr_Rx_Buffer1[0] != 0xBB) || (Ctr_Rx_Buffer1[1] != 0x66))
return ;
/*******板子连接类型*****/
board=Ctr_Rx_Buffer1[2];//长度
/*******cmd*****/
Command = Ctr_Rx_Buffer1[3];//指令
Cmd_length=Ctr_Rx_Buffer1[4];//长度
switch (Command)
{
}
}
g_UartState1 = UART_IDLE1;
}
e1 = UART_IDLE1;}
举报