具体原理我也不是很懂,经过不停的百度查阅资料最后终于成功了。
废话不多说,上代码:
1 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2 函数名称:DriveUsart1GpioInit 3 函数功能:串口1GPIO初始化 4 输入参数:BaudRate波特率 5 返回参数:无 6 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ 7 static void DriveUsart1GpioInit(uint32_t BaudRate) 8 { 9 GPIO_InitTypeDef GPIO_InitStruct; 10 USART_InitTypeDef USART_InitStruct; 11 NVIC_InitTypeDef NVIC_InitStructure; 12 /****************************************初始化端口***********************************/ 13 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE); //使能GPIOA时钟 14 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能USART1时钟 15 16 GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); //将端口进行复用 17 GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); 18 19 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; 20 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; 21 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; 22 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; 23 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 24 GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化端口 25 /****************************************初始化串口***********************************/ 26 USART_StructInit(&USART_InitStruct); 27 USART_InitStruct.USART_BaudRate = BaudRate; 28 USART_Init(USART1,&USART_InitStruct); //初始化串口 29 30 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //IRQ通道 31 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //主优先级 32 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级 33 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能通道 34 NVIC_Init(&NVIC_InitStructure); 35 USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //配置串口中断 36 USART_Cmd(USART1, ENABLE); 37 } 38 39 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 40 函数名称:DMA_USART1_TX_INIT 41 函数功能:USART1+DMA发送初始化 42 输入参数:无 43 返回参数:无 44 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ 45 static void DMA_USART1_TX_INIT(void) 46 { 47 DMA_InitTypeDef DMA_InitStructure; 48 NVIC_InitTypeDef NVIC_InitStructure; 49 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能 50 51 DMA_DeInit(DMA2_Stream7); 52 while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);//等待DMA可配置 53 54 /* 配置DMA2 Stream7,USART1发送 */ 55 DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道选择 56 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; //DMA外设地址 57 DMA_InitStructure.DMA_Memory0BaseAddr = (u32)DMA_USART1_TX_BUF; //DMA 存储器0地址 58 DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //存储器到外设模式 59 DMA_InitStructure.DMA_BufferSize = DMA_USART1_TX_BUF_LEN; //数据传输量 60 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式 61 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式 62 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位 63 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位 64 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //使用普通模式 65 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高等优先级 66 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; 67 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; 68 DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输 69 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输 70 71 DMA_Init(DMA2_Stream7, &DMA_InitStructure); //初始化DMA Stream7 72 DMA_ITConfig(DMA2_Stream7, DMA_IT_TC, ENABLE); //DMA2传输完成中断 73 USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //使能USART1DMA发送 74 75 NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream7_IRQn ;//串口1发送中断通道 76 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级 77 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级 78 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 79 NVIC_Init(&NVIC_InitStructure); 80 81 while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE){} 82 DMA_Cmd(DMA2_Stream7, DISABLE); //不使能 83 } 84 85 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 86 函数名称:DMA_USART1_RX_INIT 87 函数功能:USART1+DMA接收初始化 88 输入参数:无 89 返回参数:无 90 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ 91 static void DMA_USART1_RX_INIT(void) 92 { 93 DMA_InitTypeDef DMA_InitStructure; 94 NVIC_InitTypeDef NVIC_InitStructure; 95 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能 96 97 DMA_DeInit(DMA2_Stream5); 98 while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE);//等待DMA可配置 99 /* 配置 DMA2 Stream5,USART1接收 */ 100 DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道选择 101 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; //DMA外设地址 102 DMA_InitStructure.DMA_Memory0BaseAddr = (u32)DMA_USART1_RX_BUF; //DMA 存储器0地址 103 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到存储器模式 104 DMA_InitStructure.DMA_BufferSize = DMA_USART1_RX_BUF_LEN; //数据传输量 105 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式 106 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式 107 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位 108 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位 109 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //使用普通模式 110 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //中等优先级 111 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; 112 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; 113 DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输 114 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输 115 DMA_Init(DMA2_Stream5, &DMA_InitStructure); //初始化DMA Stream 116 117 USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能USART1DMA接收 118 119 while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE){} 120 DMA_Cmd(DMA2_Stream5, ENABLE); 121 } 122 123 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 124 函数名称:DriveUsart1Init 125 函数功能:USART1+DMA初始化 126 输入参数:BaudRate 127 返回参数:无 128 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ 129 void DriveUsart1Init(uint32_t BaudRate) 130 { 131 DriveUsart1GpioInit(BaudRate); 132 DMA_USART1_TX_INIT(); 133 DMA_USART1_RX_INIT(); 134 } 135 136 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 137 函数名称:USART1_IRQHandler 138 函数功能:USART1中断函数 139 输入参数:无 140 返回参数:无 141 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ 142 void USART1_IRQHandler(void) 143 { 144 if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET) 145 { 146 u8 clear=clear; 147 clear = USART1->SR; 148 clear = USART1->DR; 149 DMA_Cmd(DMA2_Stream5, DISABLE); //关闭DMA,防止处理其间有数据 150 USART_ClearFlag(USART1, USART_FLAG_IDLE); //清除IDLE标志 151 USART1_RX_LEN = DMA_USART1_RX_BUF_LEN - DMA_GetCurrDataCounter(DMA2_Stream5); 152 DMA_ClearFlag(DMA2_Stream5,DMA_FLAG_TCIF5 | DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5);//清除DMA2_Steam5传输完成标志 153 DMA_SetCurrDataCounter(DMA2_Stream5, DMA_USART1_RX_BUF_LEN); 154 DMA_Cmd(DMA2_Stream5, ENABLE); 155 } 156 157 if(USART_GetFlagStatus(USART1,USART_IT_TXE) == RESET) //串口发送完成 158 { 159 USART_ITConfig(USART1,USART_IT_TC,DISABLE); 160 } 161 } 162 163 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 164 函数名称:DMA2_Stream7_IRQHandler 165 函数功能:DMA中断 166 输入参数:无 167 返回参数:无 168 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ 169 void DMA2_Stream7_IRQHandler(void) 170 { 171 //清除标志 172 if(DMA_GetFlagStatus(DMA2_Stream7,DMA_FLAG_TCIF7)!=RESET) //等待DMA2_Steam7传输完成 173 { 174 DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7); //清除DMA2_Steam7传输完成标志 175 DMA_Cmd(DMA2_Stream7,DISABLE); 176 USART_ITConfig(USART1,USART_IT_TC,ENABLE); //打开串口发送完成中断 177 } 178 } 179 180 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 181 函数名称:DMA_USART1_Send 182 函数功能:串口发送数据 183 输入参数:data待发送数据 , size 发送数据字节数 184 返回参数:无 185 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ 186 void DMA_USART1_Send(u8 *data,u16 size) 187 { 188 memcpy(DMA_USART1_TX_BUF,data,size); //复制数据到DMA发送缓存区 189 while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE); //确保DMA可以被设置 190 DMA_SetCurrDataCounter(DMA2_Stream7,size); //设置数据传输长度 191 DMA_Cmd(DMA2_Stream7,ENABLE); //打开DMA数据流,开始发送 192 }
不出意外的话直接复制就可以使用。
参考文章: