STM32-USART DMA_Interrupt例程的学习

简介:

这是固件库里的一个例程,决定从这里入手依次学习一下外设,下面是这个例程的介绍:

 

This example provides a basic communication between USART1 and USART2 using DMA 

capability, flags and interrupts.

 

First, the DMA transfers data from TxBuffer2 buffer to USART2 Transmit data register,

then this data is sent to USART1. Data received by USART1 is transferred using 

RXNE flag and stored in RxBuffer1 then compared with the sent ones and

the result of this comparison is stored in the "TransferStatus1" variable.

 

In the same time, the DMA transfers data from TxBuffer1 buffer to USART1 Transmit

data register, then this data is sent to USART2. Data received by USART2 is

transferred using Receive interrupt and stored in RxBuffer2 then compared with

the sent ones and the result of this comparison is stored in the "TransferStatus2"

variable. 

按照意思无非是串口传输的数据和DMA传输的数据进行比对,然后返回状态,程序比较简单,很多地方我加了注释。
  1. /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 
  2. * File Name          : main.c 
  3. * Author             : MCD Application Team 
  4. * Version            : V2.0.1 
  5. * Date               : 06/13/2008 
  6. * Description        : Main program body 
  7. ******************************************************************************** 
  8. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 
  9. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 
  10. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 
  11. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 
  12. * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 
  13. * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 
  14. *******************************************************************************/  
  15. /* Includes ------------------------------------------------------------------*/  
  16. #include "stm32f10x_lib.h"  
  17. #include "platform_config.h"  
  18. /* Private typedef -----------------------------------------------------------*/  
  19. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;  
  20. /* Private define ------------------------------------------------------------*/  
  21. #define USART1_DR_Base  0x40013804  
  22. #define USART2_DR_Base  0x40004404  
  23. #define TxBufferSize1   (countof(TxBuffer1) - 1)  
  24. #define TxBufferSize2   (countof(TxBuffer2) - 1)  
  25. /* Private macro -------------------------------------------------------------*/  
  26. #define countof(a)   (sizeof(a) / sizeof(*(a)))  
  27. /* Private variables ---------------------------------------------------------*/  
  28. USART_InitTypeDef USART_InitStructure;  
  29. u8 TxBuffer1[] = "USART DMA Interrupt: USART1 -> USART2 using DMA Tx and Rx Flag";  
  30. u8 TxBuffer2[] = "USART DMA Interrupt: USART2 -> USART1 using DMA Tx and Rx Interrupt";  
  31. u8 RxBuffer1[TxBufferSize2];  
  32. u8 RxBuffer2[TxBufferSize1];  
  33. u8 NbrOfDataToRead = TxBufferSize1;  
  34. u8 index = 0;  
  35. volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = FAILED;    
  36. ErrorStatus HSEStartUpStatus;  
  37. /* Private function prototypes -----------------------------------------------*/  
  38. void RCC_Configuration(void);  
  39. void GPIO_Configuration(void);  
  40. void NVIC_Configuration(void);  
  41. void DMA_Configuration(void);  
  42. TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength);  
  43.     
  44. /* Private functions ---------------------------------------------------------*/  
  45. /******************************************************************************* 
  46. * Function Name  : main 
  47. * Description    : Main program 
  48. * Input          : None 
  49. * Output         : None 
  50. * Return         : None 
  51. *******************************************************************************/  
  52. int main(void)  
  53. {  
  54. #ifdef DEBUG  
  55.   debug();  
  56. #endif  
  57.   /* System Clocks Configuration */  
  58.   RCC_Configuration();  
  59.          
  60.   /* NVIC configuration */  
  61.   NVIC_Configuration();  
  62.   /* Configure the GPIO ports */  
  63.   GPIO_Configuration();  
  64.   /* Configure the DMA */  
  65.   DMA_Configuration();  
  66. /* USART1 and USART2 configuration ------------------------------------------------------*/  
  67.   /* USART and USART2 configured as follow: 
  68.         - BaudRate = 230400 baud  波特率设置 
  69.         - Word Length = 8 Bits    数据位 
  70.         - One Stop Bit            停止位 
  71.         - No parity               无奇偶校验 
  72.         - Hardware flow control disabled (RTS and CTS signals)无硬件流控制 
  73.         - Receive and transmit enabled 接收和发送使能 
  74.   */  
  75.   USART_InitStructure.USART_BaudRate = 230400;  
  76.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
  77.   USART_InitStructure.USART_StopBits = USART_StopBits_1;  
  78.   USART_InitStructure.USART_Parity = USART_Parity_No;  
  79.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
  80.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
  81.     
  82.   /* Configure USART1 */  
  83.   USART_Init(USART1, &USART_InitStructure);  
  84.   /* Configure USART2 */  
  85.   USART_Init(USART2, &USART_InitStructure);  
  86.  /*********************使能相应的DMA通道**************************/  
  87.   /* Enable USART1 DMA TX request */  
  88.   USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);  
  89.   /* Enable USART2 DMA TX request */  
  90.   USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);  
  91.   /* Enable the USART2 Receive Interrupt */  
  92.   USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  
  93.   /* Enable DMA1 Channel4 */  
  94.   DMA_Cmd(DMA1_Channel4, ENABLE);  
  95.   /* Enable DMA1 Channel7 */  
  96.   DMA_Cmd(DMA1_Channel7, ENABLE);  
  97.   /* Enable the USART1 */  
  98.   USART_Cmd(USART1, ENABLE);  
  99.   /* Enable the USART2 */  
  100.   USART_Cmd(USART2, ENABLE);  
  101.   /* Receive the TxBuffer2 */  
  102.   while(index < TxBufferSize2)  
  103.   {  
  104.      while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) //检查接收标志位,如果一直没有接收到就在这儿循环  
  105.      {  
  106.      }  
  107.      RxBuffer1[index++] = USART_ReceiveData(USART1);    
  108.   }  
  109.   /* Wait until DMA1_Channel 4 Transfer Complete */  
  110.   while (DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)  
  111.   {  
  112.   }  
  113.   /* Wait until DMA1_Channel 7 Transfer Complete */  
  114.   while (DMA_GetFlagStatus(DMA1_FLAG_TC7) == RESET)  
  115.   {  
  116.   }  
  117.     
  118.   /* Check the received data with the send ones */  
  119.   TransferStatus1 = Buffercmp(TxBuffer2, RxBuffer1, TxBufferSize2);  
  120.   /* TransferStatus1 = PASSED, if the data transmitted from USART2 and   
  121.      received by USART1 are the same */  
  122.   /* TransferStatus1 = FAILED, if the data transmitted from USART2 and  
  123.      received by USART1 are different */  
  124.   TransferStatus2 = Buffercmp(TxBuffer1, RxBuffer2, TxBufferSize1);  
  125.   /* TransferStatus2 = PASSED, if the data transmitted from USART1 and   
  126.      received by USART2 are the same */  
  127.   /* TransferStatus2 = FAILED, if the data transmitted from USART1 and  
  128.      received by USART2 are different */  
  129.   while (1)  
  130.   {  
  131.   }  
  132. }  
  133. /******************************************************************************* 
  134. * Function Name  : RCC_Configuration 
  135. * Description    : Configures the different system clocks. 
  136. * Input          : None 
  137. * Output         : None 
  138. * Return         : None 
  139. *******************************************************************************/  
  140. void RCC_Configuration(void)  
  141. {  
  142.   /* RCC system reset(for debug purpose) */  
  143.   RCC_DeInit();  
  144.   /* Enable HSE */  
  145.   RCC_HSEConfig(RCC_HSE_ON);  
  146.   /* Wait till HSE is ready */  
  147.   HSEStartUpStatus = RCC_WaitForHSEStartUp();  
  148.   if(HSEStartUpStatus == SUCCESS)  
  149.   {  
  150.     /* Enable Prefetch Buffer */  
  151.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  
  152.     /* Flash 2 wait state */  
  153.     FLASH_SetLatency(FLASH_Latency_2);  
  154.    
  155.     /* HCLK = SYSCLK */  
  156.     RCC_HCLKConfig(RCC_SYSCLK_Div1);   
  157.     
  158.     /* PCLK2 = HCLK */  
  159.     RCC_PCLK2Config(RCC_HCLK_Div1);   
  160.     /* PCLK1 = HCLK/2 */  
  161.     RCC_PCLK1Config(RCC_HCLK_Div2);  
  162.     /* PLLCLK = 8MHz * 9 = 72 MHz */  
  163.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  
  164.     /* Enable PLL */   
  165.     RCC_PLLCmd(ENABLE);  
  166.     /* Wait till PLL is ready */  
  167.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  
  168.     {  
  169.     }  
  170.     /* Select PLL as system clock source */  
  171.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  
  172.     /* Wait till PLL is used as system clock source */  
  173.     while(RCC_GetSYSCLKSource() != 0x08)  
  174.     {  
  175.     }  
  176.   }  
  177.       
  178.   /* DMA clock enable */  
  179.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  
  180.   /* Enable USART1, GPIOA, GPIOx and AFIO clocks */  
  181.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA |  
  182.                          RCC_APB2Periph_GPIOx | RCC_APB2Periph_AFIO, ENABLE);  
  183.   /* Enable USART2 clock */  
  184.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  
  185. }  
  186. /******************************************************************************* 
  187. * Function Name  : GPIO_Configuration 
  188. * Description    : Configures the different GPIO ports. 
  189. * Input          : None 
  190. * Output         : None 
  191. * Return         : None 
  192. *******************************************************************************/  
  193. void GPIO_Configuration(void)  
  194. {  
  195.   GPIO_InitTypeDef GPIO_InitStructure;  
  196. #ifdef USE_STM3210B_EVAL  
  197.   /* Enable the USART2 Pins Software Remapping  
  198.   引脚重映射,在STM32中很多外设和相关的引脚可以重映射到其他引脚上*/  
  199.   GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);  
  200. #endif  
  201.   /* Configure USART1 Rx (PA.10) as input floating 
  202.   串口的接收引脚使用浮空输入的模式具体配置为什么形式需要查找技术手册 */  
  203.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  
  204.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  205.   GPIO_Init(GPIOA, &GPIO_InitStructure);  
  206.   /* Configure USART2 Rx as input floating */  
  207.   GPIO_InitStructure.GPIO_Pin = GPIO_RxPin;  
  208.   GPIO_Init(GPIOx, &GPIO_InitStructure);  
  209.     
  210.   /* Configure USART1 Tx (PA.09) as alternate function push-pull  
  211.   发送引脚使用复用推挽输出*/  
  212.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  
  213.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  214.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  215.   GPIO_Init(GPIOA, &GPIO_InitStructure);  
  216.   /* Configure USART2 Tx as alternate function push-pull */  
  217.   GPIO_InitStructure.GPIO_Pin = GPIO_TxPin;  
  218.   GPIO_Init(GPIOx, &GPIO_InitStructure);  
  219. }  
  220. /******************************************************************************* 
  221. * Function Name  : NVIC_Configuration 
  222. * Description    : Configures the nested vectored interrupt controller. 
  223. * Input          : None 
  224. * Output         : None 
  225. * Return         : None 
  226. *******************************************************************************/  
  227. void NVIC_Configuration(void)  
  228. {  
  229.    NVIC_InitTypeDef NVIC_InitStructure;  
  230. #ifdef  VECT_TAB_RAM    
  231.   /* Set the Vector Table base location at 0x20000000 */   
  232.   NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);   
  233. #else  /* VECT_TAB_FLASH  */  
  234.   /* Set the Vector Table base location at 0x08000000 */   
  235.   NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);     
  236. #endif   
  237.   /* Enable the USART2 Interrupt */  
  238.   NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel;  
  239.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  240.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  241.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  242.   NVIC_Init(&NVIC_InitStructure);  
  243. }  
  244. /******************************************************************************* 
  245. * Function Name  : DMA_Configuration 
  246. * Description    : Configures the DMA. 
  247. * Input          : None 
  248. * Output         : None 
  249. * Return         : None 
  250. *******************************************************************************/  
  251. void DMA_Configuration(void)  
  252. {  
  253.   DMA_InitTypeDef DMA_InitStructure;  
  254.   /* DMA1 Channel4 (triggered by USART1 Tx event) Config  
  255.   每个通道都有固定的外设请求,因此在需要传输外设数据时需要选择对应的通道*/  
  256.   DMA_DeInit(DMA1_Channel4);  
  257.   DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; //定义了外设地址  
  258.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)TxBuffer1; //定义了目的地址  
  259.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;    //外设作为数据的目的地  
  260.   DMA_InitStructure.DMA_BufferSize = TxBufferSize1;     //传送数据缓存大小  
  261.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //定义地址在传送后是否会递增  
  262.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存到内存后地址递增  
  263.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  
  264.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//数据宽度是8位  
  265.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;   //工作在正常缓存模式,还有一种是循环缓存模式  
  266.   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //通道拥有高优先级  
  267.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//用来设置是否是内存到内存传输  
  268.   DMA_Init(DMA1_Channel4, &DMA_InitStructure);  
  269.     
  270.   /* DMA1 Channel7 (triggered by USART2 Tx event) Config  
  271.   通道7的工作模式只需要把不一样的部分设置一下就可以,其他的还和上面一样*/  
  272.   DMA_DeInit(DMA1_Channel7);  
  273.   DMA_InitStructure.DMA_PeripheralBaseAddr = USART2_DR_Base;  
  274.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)TxBuffer2;  
  275.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  
  276.   DMA_InitStructure.DMA_BufferSize = TxBufferSize2;  
  277.   DMA_Init(DMA1_Channel7, &DMA_InitStructure);  
  278. }  
  279. /******************************************************************************* 
  280. * Function Name  : Buffercmp 
  281. * Description    : Compares two buffers. 
  282. * Input          : - pBuffer1, pBuffer2: buffers to be compared. 
  283. *                : - BufferLength: buffer's length 
  284. * Output         : None 
  285. * Return         : PASSED: pBuffer1 identical to pBuffer2 
  286. *                  FAILED: pBuffer1 differs from pBuffer2 
  287. 用来比较两段是否相同 
  288. *******************************************************************************/  
  289. TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength)  
  290. {  
  291.   while(BufferLength--)  
  292.   {  
  293.     if(*pBuffer1 != *pBuffer2)  
  294.     {  
  295.       return FAILED;  
  296.     }  
  297.     pBuffer1++;  
  298.     pBuffer2++;  
  299.   }  
  300.   return PASSED;  
  301. }  
  302. #ifdef  DEBUG  
  303. /******************************************************************************* 
  304. * Function Name  : assert_failed 
  305. * Description    : Reports the name of the source file and the source line number 
  306. *                  where the assert_param error has occurred. 
  307. * Input          : - file: pointer to the source file name 
  308. *                  - line: assert_param error line source number 
  309. * Output         : None 
  310. * Return         : None 
  311. *******************************************************************************/  
  312. void assert_failed(u8* file, u32 line)  
  313. {   
  314.   /* User can add his own implementation to report the file name and line number, 
  315.      ex: printf("Wrong parameters value: file %s on line %d/r/n", file, line) */  
  316.   /* Infinite loop */  
  317.   while (1)  
  318.   {  
  319.   }  
  320. }  
  321. #endif  
  322. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/  
 本文转自emouse博客园博客,原文链接:http://www.cnblogs.com/emouse/archive/2010/12/01/2198199.html,如需转载请自行联系原作者
相关文章
|
18天前
|
芯片
stm32f4外设学习篇(代码集合)(一)
stm32f4外设学习篇(代码集合)
|
1月前
|
存储 C语言 芯片
C/C++ stm32基础知识超详细讲解(系统性学习day14)
C/C++ stm32基础知识超详细讲解(系统性学习day14)
|
1月前
|
IDE 编译器 开发工具
学习STM32,该用哪款开发工具?
学习STM32,该用哪款开发工具?
49 1
|
12天前
|
存储 编译器 API
大神们分享STM32的学习方法
大神们分享STM32的学习方法
47 0
|
7月前
|
存储 算法 API
stm32cubeMX学习、SD卡虚拟U盘实验
stm32cubeMX学习、SD卡虚拟U盘实验
285 0
|
7月前
|
存储 Linux C语言
stm32cubeMX学习、USB DFU(Download Firmware Update)固件更新
stm32cubeMX学习、USB DFU(Download Firmware Update)固件更新
347 1
|
8月前
|
存储 数据采集 芯片
No.4 STM32F429IGT6 GPIO相关学习总结(STM32F429/F767/H743)
No.4 STM32F429IGT6 GPIO相关学习总结(STM32F429/F767/H743)
|
10月前
stm32学习第四天
stm32学习第四天
|
10月前
|
10月前
|
存储 内存技术