分享

stm32f407之MyDebugger(操作寄存器)

 戴维图书馆 2014-04-08

九、MyDebugger

         已经学习了usart和DMA,因为后面的学习,最好有一个直观点的人性化的显示终端。可以通过串口将数据和文字信息发送往电脑,然后在上位机软件上观察数据以及调试信息。为此,我写了一个文件,以供日后调试之用,命名为MyDebugger。

         首先,参照之前的程序,略加修改,将USART的接收功能全部去掉,DMA的配置分开,独立写成一个配置DMA的函数USART3_DMA_config(),把发送的部分写到MyDebugger_Message(char *str_address, unsigned int str_len)函数内,很简单地实现了一个发送字符消息的函数。然后写一个操作板子上指示灯的函数,用以日后指示调试信息。具体的实现,请看下程序(实现MyDebugger的验证程序)。

         把验证程序分离写成头文件形式。方便以后其他工程使用。把程序稍作修改,利用条件编译,为以后可能的添加其他通信方式提供方便。要使用USART3作为调试通信方式,必须先定义宏MyDebug_with_USART3,如下图所示:


实现MyDebugger的验证程序:

  1. /*********************************************  
  2.     标题:MyDebugger  
  3.     软件平台:IAR for ARM6.21  
  4.     硬件平台:stm32f4-discovery  
  5.     主频:168M  
  6.       
  7.     描述:实现一个调试工具  
  8.             
  9.     author:小船  
  10.     data:2012-02-04  
  11. **********************************************/  
  12. #include <stm32f4xx.h>   
  13. #include <stdbool.h>  
  14.   
  15. /******LED宏定义*******/  
  16. #define green 0x00001000  
  17. #define orange 0x00002000  
  18. #define red 0x00004000  
  19. #define blue 0x00008000  
  20.   
  21. /******全局变量及类型声明*******/  
  22. bool USART_DMA_Completed;  
  23. enum LED_State {on, off, turn};  
  24.   
  25. /******函数声明*******/  
  26. void LEDs_Init(void);  
  27. void USART3_DMA_config(void);  
  28. void USART3_config(void);  
  29. bool MyDebugger_Message(char *str_address, unsigned int str_len);  
  30. void MyDebugger_LEDs(uint32_t LED, enum LED_State state);  
  31.   
  32. void main ()  
  33. {   
  34.   SysTick_Config(SystemCoreClock / 1000); //设置systemtick一毫秒中断  
  35.   SCB->AIRCR = 0x05FA0000 | 0x400;  //中断优先级分组 抢占:响应=3:1  
  36.   LEDs_Init();  
  37.   USART3_DMA_config();  
  38.   USART3_config();  
  39.     
  40.   USART_DMA_Completed = 1;  
  41.     
  42.   while(1)  
  43.   {   
  44.     MyDebugger_Message("My name is Xian Yongwen\n",   
  45.                             sizeof("My name is Xian Yongwen\n")/sizeof(char));  
  46.       
  47.     MyDebugger_Message("广东石油化工学院\n",   
  48.                             sizeof("广东石油化工学院\n")/sizeof(char));  
  49.   }  
  50. }  
  51.   
  52. /*********************************************  
  53.   函数名:MyDebugger_Message  
  54.   参数:char *str_address  :要发送的字符串地址  
  55.         unsigned int str_len  :字符串的长度  
  56.   返回值:bool  是否操作成功  
  57.   功能:通过USART3发送信息  
  58. **********************************************/  
  59. bool MyDebugger_Message(char *str_address, unsigned int str_len)  
  60. {   
  61.     if( USART_DMA_Completed )  //之前数据已经发送完成  
  62.     {    
  63.       DMA1_Stream3->CR &= 0xFFFFFFFE;   //除能DMA1_Stream3  
  64.       while(DMA1_Stream3->CR & 0x00000001); //确保DMA可以被设置       
  65.       DMA1->LIFCR |= 0x0f800000;  //传送前清空DMA1_Stream3所有中断标志    
  66.       DMA1_Stream3->M0AR = (uint32_t)str_address; //设置内存地址  
  67.       if((USART3->SR & (1<<7))) //发送数据寄存器空  
  68.       {  
  69.         USART3->CR3 &= ~(1<<7);//usart3 dma发送模式除能  
  70.         USART_DMA_Completed = 0;  
  71.         DMA1_Stream3->NDTR = str_len; //设置dma传输数据的数量  
  72.         DMA1_Stream3->CR |= 1;//使能dma  
  73.         USART3->CR3 |= (1<<7);//usart3 dma发送模式使能  
  74.         return true;  
  75.       }   
  76.     }   
  77.     return false;  
  78. }  
  79.   
  80. /****************************************  
  81.   函数名:MyDebugger_LEDs  
  82.   参数:uint32_t LED  :要操作哪些LED  
  83.         enum LED_State state  :作何操作  
  84.   返回值:无  
  85.   功能:改变LED的状态  
  86. ****************************************/  
  87. void MyDebugger_LEDs(uint32_t LED, enum LED_State state)  
  88. {  
  89.   uint32_t tmp;  
  90.   switch (state)  
  91.   {  
  92.     case on:  
  93.       {  
  94.         GPIOD->BSRRL |= LED;   
  95.         break;  
  96.       }  
  97.     case off:  
  98.       {  
  99.         GPIOD->BSRRH |= LED;  
  100.         break;  
  101.       }  
  102.     case turn:  
  103.       {  
  104.         tmp = (~GPIOD->ODR) & LED;     
  105.         GPIOD->ODR &= ~LED;  
  106.         GPIOD->ODR |= tmp;  
  107.         break;  
  108.       }   
  109.   }  
  110. }  
  111.   
  112. /****************************************  
  113.   函数名:USART3_DMA_config  
  114.   参数:无  
  115.   返回值:无  
  116.   功能:DMA1数据流3与usart3关联的相关配置  
  117. ****************************************/  
  118. void USART3_DMA_config(void)  
  119. {  
  120.   RCC->AHB1ENR |= (1<<21); //使能DMA1时钟  
  121.   DMA1_Stream3->CR &= 0xFFFFFFFE; //除能DMA1_Stream3  
  122.   while(DMA1_Stream3->CR & 0x00000001);//确保DMA可以被设置  
  123.     
  124.   DMA1->LIFCR |= 0x0f800000;//传送前清空DMA1_Stream3所有中断标志  
  125.     
  126.   DMA1_Stream3->PAR = (uint32_t)&USART3->DR;//设置外设地址USART3->DR地址0x40004804  
  127.                                              //设置内存地址  
  128.   DMA1_Stream3->FCR &= 0x00000000;  
  129.   DMA1_Stream3->FCR |= (1<<7);//设置fifo  
  130.   /*  
  131.     设置dma通道4,即usart3tx  
  132.     优先级最高  
  133.     传输方向内存到外设  
  134.     内存递增模式  
  135.     传输完成中断使能  
  136.   */  
  137.   DMA1_Stream3->CR |= (0x08000000 | 0x00030000 | (1<<6)  
  138.                        | (1<<10) | (1<<4) | (1<<2)|(1<<1));   
  139.     
  140.   NVIC->IP[14] = 0xA0;  
  141.   NVIC->ISER[0] |= (1<<14);  
  142.     
  143. }  
  144.   
  145. /**************************  
  146.   函数名:USART3_config  
  147.   参数:无  
  148.   返回值:无  
  149.   功能:配置usart3  
  150. ************************/  
  151. void USART3_config(void)  
  152. {  
  153.   RCC->APB1ENR |= (1<<18);  //使能usart3时钟  
  154.   RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟  
  155.   USART3->BRR = 0x0000016C;   //波特率115200  
  156.   /*  
  157.    使能usart3  
  158.   usart3发送使能  
  159.   8bit  
  160.   一位停止位  
  161.   无校验  
  162.   */  
  163.   USART3->CR1 |= ( ( 1<<13 ) | ( 1<<3 ) );   
  164.     
  165.   GPIOD->AFR[1] |= 0x00000077;//选择PD8,9复用功能   
  166.     
  167.   GPIOD->MODER &= 0xFFF0FFFF; //设置PD8,9,复用模式  
  168.   GPIOD->MODER |= 0x000A0000;   
  169.       
  170.   GPIOD->OSPEEDR &= 0xFFFCFFFF; //PD8速度50m  
  171.   GPIOD->OSPEEDR |= 0x00020000;  
  172.     
  173.   GPIOD->PUPDR &= 0xFFFCFFFF; //PD8  
  174.   GPIOD->PUPDR |= 0x00010000;  
  175. }  
  176.   
  177. /****************************************  
  178.   函数名:LEDs_Init  
  179.   参数:无  
  180.   返回值:无  
  181.   功能:初始化板子上的LED  
  182. ****************************************/  
  183. void LEDs_Init(void)  
  184. {  
  185.   RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟  
  186.     
  187.   GPIOD->MODER &= 0x00FFFFFF; //设置PD12,13,14,15输出  
  188.   GPIOD->MODER |= 0x55000000;   
  189.     
  190.   GPIOD->OTYPER &= 0xFFFF0FFF; //设置PD12,13,14,15推挽输出  
  191.     
  192.   GPIOD->OSPEEDR &= 0x00FFFFFF; //PD12,13,14,15 速度100m  
  193.     
  194.   GPIOD->PUPDR &= 0x00FFFFFF;  //PD12,13,14,15 无上拉无下拉  
  195.     
  196.   GPIOD->BSRRH = 0xf000;  //reset register GPIOx_BSRRH, write only  
  197.                           //set register GPIOx_BSRRL, write only  
  198. }  
  199.   
  200. void DMA1_Stream3_IRQHandler(void)  
  201. {  
  202.   if(DMA1->LISR & 0x08000000)//DMA传输完成  
  203.   {  
  204.     USART_DMA_Completed = 1;  
  205.     DMA1->LIFCR |= 0x08000000;//清除中断标志  
  206.   }  
  207.   if(DMA1->LISR & 0x03000000)     //如果发生传输错误或直接模式错误,亮橙色LED  
  208.   {  
  209.     MyDebugger_LEDs( orange, on);  
  210.     DMA1->LIFCR |= 0x03000000;  
  211.   }  
  212.   if(DMA1->LISR & (1<<22))  //如果发生fifo错误,亮红色指示灯  
  213.   {  
  214.     MyDebugger_LEDs( red, on);  
  215.     DMA1->LIFCR |= (1<<22);  
  216.   }  
  217. }  

实用程序:

头文件:MyDebugger.h

  1. <p>// file:MyDebugger.h</p>#ifndef __MyDebugger_H  
  2. #define __MyDebugger_H  
  3.   
  4. #include <stm32f4xx.h>   
  5. #include <stdbool.h>  
  6.   
  7. /******LED宏定义*******/  
  8. #define green 0x00001000  
  9. #define orange 0x00002000  
  10. #define red 0x00004000  
  11. #define blue 0x00008000  
  12.   
  13. /******全局变量及类型声明*******/  
  14. enum LED_State {on, off, turn};  
  15.   
  16. /******函数声明*******/  
  17. void MyDebugger_Init(void);  
  18. bool MyDebugger_Message(char *str_address, unsigned int str_len);  
  19. void MyDebugger_LEDs(uint32_t LED, enum LED_State state);  
  20.   
  21. #endif  


源文件:MyDebugger.c

  1. // file:MyDebugger.c  
  2. #include <MyDebugger.h>   
  3.   
  4. #ifdef MyDebug_with_USART3  
  5.   
  6. bool USART_DMA_Completed = true;  
  7.   
  8. /****************************************  
  9.   函数名:USART3_DMA_config  
  10.   参数:无  
  11.   返回值:无  
  12.   功能:DMA1数据流3与usart3关联的相关配置  
  13. ****************************************/  
  14. void USART3_DMA_config(void)  
  15. {  
  16.   RCC->AHB1ENR |= (1<<21); //使能DMA1时钟  
  17.   DMA1_Stream3->CR &= 0xFFFFFFFE; //除能DMA1_Stream3  
  18.   while(DMA1_Stream3->CR & 0x00000001);//确保DMA可以被设置  
  19.     
  20.   DMA1->LIFCR |= 0x0f800000;//传送前清空DMA1_Stream3所有中断标志  
  21.     
  22.   DMA1_Stream3->PAR = (uint32_t)&USART3->DR;//设置外设地址USART3->DR地址0x40004804  
  23.                                              //设置内存地址  
  24.   DMA1_Stream3->FCR &= 0x00000000;  
  25.   DMA1_Stream3->FCR |= (1<<7);//设置fifo  
  26.   /*  
  27.     设置dma通道4,即usart3tx  
  28.     优先级最高  
  29.     传输方向内存到外设  
  30.     内存递增模式  
  31.     传输完成中断使能  
  32.   */  
  33.   DMA1_Stream3->CR |= (0x08000000 | 0x00030000 |   
  34.                         (1<<6) | (1<<10) | (1<<4));   
  35.     
  36.   NVIC->IP[14] = 0xA0;  
  37.   NVIC->ISER[0] |= (1<<14);  
  38. }  
  39.   
  40. /**************************  
  41.   函数名:USART3_config  
  42.   参数:无  
  43.   返回值:无  
  44.   功能:配置usart3  
  45. ************************/  
  46. void USART3_config(void)  
  47. {  
  48.   RCC->APB1ENR |= (1<<18);  //使能usart3时钟  
  49.   RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟  
  50.   USART3->BRR = 0x0000016C;   //波特率115200  
  51.   /*  
  52.    使能usart3  
  53.   usart3发送使能  
  54.   8bit  
  55.   一位停止位  
  56.   无校验  
  57.   */  
  58.   USART3->CR1 |= ( ( 1<<13 ) | ( 1<<3 ) );   
  59.     
  60.   GPIOD->AFR[1] |= 0x00000077;//选择PD8,9复用功能   
  61.     
  62.   GPIOD->MODER &= 0xFFF0FFFF; //设置PD8,9,复用模式  
  63.   GPIOD->MODER |= 0x000A0000;   
  64.     
  65. //  GPIOD->OTYPER &= 0xFFFFDFFF; //设置PD9推挽输出  
  66.     
  67.   GPIOD->OSPEEDR &= 0xFFFCFFFF; //PD8速度50m  
  68.   GPIOD->OSPEEDR |= 0x00020000;  
  69.     
  70.   GPIOD->PUPDR &= 0xFFFCFFFF; //PD8  
  71.   GPIOD->PUPDR |= 0x00010000;  
  72. }  
  73.   
  74. void DMA1_Stream3_IRQHandler(void)  
  75. {  
  76.   if(DMA1->LISR & 0x08000000)//DMA传输完成  
  77.   {  
  78.     USART_DMA_Completed = 1;  
  79.     DMA1->LIFCR |= 0x08000000;//清除中断标志  
  80.   }  
  81. }  
  82. #endif  
  83.   
  84. /*********************************************  
  85.   函数名:MyDebugger_Message  
  86.   参数:char *str_address  :要发送的字符串地址  
  87.         unsigned int str_len  :字符串的长度  
  88.   返回值:bool  是否操作成功  
  89.   功能:通过USART3发送信息  
  90. **********************************************/  
  91. bool MyDebugger_Message(char *str_address, unsigned int str_len)  
  92. {     
  93. #ifdef MyDebug_with_USB  
  94.     bool USB_Actioned;  
  95. #endif  
  96.       
  97. #ifdef MyDebug_with_USART3  
  98.     bool USART3_Actioned;  
  99.     if( USART_DMA_Completed )  //之前数据已经发送完成  
  100.     {    
  101.       DMA1_Stream3->CR &= 0xFFFFFFFE;   //除能DMA1_Stream3  
  102.       while(DMA1_Stream3->CR & 0x00000001); //确保DMA可以被设置       
  103.       DMA1->LIFCR |= 0x0f800000;  //传送前清空DMA1_Stream3所有中断标志    
  104.       DMA1_Stream3->M0AR = (uint32_t)str_address; //设置内存地址  
  105.       if((USART3->SR & (1<<7))) //发送数据寄存器空  
  106.       {  
  107.         USART3->CR3 &= ~(1<<7);//usart3 dma发送模式除能  
  108.         USART_DMA_Completed = 0;  
  109.         DMA1_Stream3->NDTR = str_len; //设置dma传输数据的数量  
  110.         DMA1_Stream3->CR |= 1;//使能dma  
  111.         USART3->CR3 |= (1<<7);//usart3 dma发送模式使能  
  112.         USART3_Actioned = 1;  
  113.       }   
  114.     }  
  115. #endif  
  116.       
  117. #ifdef MyDebug_with_USB  
  118. //以后或许实现用USB发送调试信息的代码  
  119.       
  120.        //如果操作USB成功  
  121.         USB_Actioned = 1;  
  122. #endif  
  123.   
  124. #ifdef MyDebug_with_USART3  
  125.   #ifndef MyDebug_with_USB      
  126.     return USART3_Actioned;  
  127.   #endif    
  128. #endif  
  129.   
  130. #ifdef MyDebug_with_USB  
  131.   #ifndef MyDebug_with_USART3      
  132.     return USB_Actioned;  
  133.   #endif    
  134. #endif  
  135.   
  136. #ifdef MyDebug_with_USART3  
  137.   #ifdef MyDebug_with_USB      
  138.     return (USART3_Actioned | USB_Actioned);  
  139.   #endif  
  140. #endif      
  141. }  
  142.   
  143. /****************************************  
  144.   函数名:LEDs_Init  
  145.   参数:无  
  146.   返回值:无  
  147.   功能:初始化板子上的LED  
  148. ****************************************/  
  149. void LEDs_Init(void)  
  150. {  
  151.   RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟  
  152.     
  153.   GPIOD->MODER &= 0x00FFFFFF; //设置PD12,13,14,15输出  
  154.   GPIOD->MODER |= 0x55000000;   
  155.     
  156.   GPIOD->OTYPER &= 0xFFFF0FFF; //设置PD12,13,14,15推挽输出  
  157.     
  158.   GPIOD->OSPEEDR &= 0x00FFFFFF; //PD12,13,14,15 速度100m  
  159.     
  160.   GPIOD->PUPDR &= 0x00FFFFFF;  //PD12,13,14,15 无上拉无下拉  
  161.     
  162.   GPIOD->BSRRH = 0xf000;  //reset register GPIOx_BSRRH, write only  
  163.                           //set register GPIOx_BSRRL, write only  
  164. }  
  165.   
  166. /****************************************  
  167.   函数名:MyDebugger_LEDs  
  168.   参数:uint32_t LED  :要操作哪些LED  
  169.         enum LED_State state  :作何操作  
  170.   返回值:无  
  171.   功能:改变LED的状态  
  172. ****************************************/  
  173. void MyDebugger_LEDs(uint32_t LED, enum LED_State state)  
  174. {  
  175.   uint32_t tmp;  
  176.   switch (state)  
  177.   {  
  178.     case on:  
  179.       {  
  180.         GPIOD->BSRRL |= LED;   
  181.         break;  
  182.       }  
  183.     case off:  
  184.       {  
  185.         GPIOD->BSRRH |= LED;  
  186.         break;  
  187.       }  
  188.     case turn:  
  189.       {  
  190.         tmp = (~GPIOD->ODR) & LED;     
  191.         GPIOD->ODR &= ~LED;  
  192.         GPIOD->ODR |= tmp;  
  193.         break;  
  194.       }   
  195.   }  
  196. }  
  197.   
  198. /*********************************************  
  199.   函数名:MyDebugger_Init  
  200.   参数:无  
  201.   返回值:无  
  202.   功能:初始化MyDebugger  
  203. **********************************************/  
  204. void MyDebugger_Init(void)  
  205. {  
  206.   LEDs_Init();  
  207.     
  208. #ifdef MyDebug_with_USART3  
  209.   USART3_DMA_config();  
  210.   USART3_config();  
  211. #endif  
  212. }  


主程序文件:main.c

  1. /*********************************************  
  2.     标题:MyDebugger  
  3.     软件平台:IAR for ARM6.21  
  4.     硬件平台:stm32f4-discovery  
  5.     主频:168M  
  6.       
  7.     描述:实现一个调试工具  
  8.             
  9.     author:小船  
  10.     data:2012-02-04  
  11. **********************************************/  
  12. #include <stm32f4xx.h>   
  13. #include <MyDebugger.h>   
  14.   
  15. uint32_t Gb_TimingDelay;  
  16.   
  17. void Delay(uint32_t nTime);  
  18.   
  19. void main ()  
  20. {   
  21.   SysTick_Config(SystemCoreClock / 1000); //设置systemtick一毫秒中断  
  22.   //char test[15] = {0, 1, 2, 3, 4,  10, 11, 12, 13, 14, 15, 0xfe, 0xf0, 0x07, 0x09};  
  23.   SCB->AIRCR = 0x05AF0000 | 0x400;  //中断优先级分组 抢占:响应=3:1  
  24.   MyDebugger_Init();  
  25.   while(1)  
  26.   {   
  27.     MyDebugger_Message("My name is Xian Yongwen\n\r",   
  28.                             sizeof("My name is Xian Yongwen\n\r")/sizeof(char));  
  29.       
  30.     MyDebugger_LEDs(blue, on);  
  31.     Delay(500);  
  32.       
  33.     MyDebugger_Message("广东石油化工学院\n\r",   
  34.                             sizeof("广东石油化工学院\n\r")/sizeof(char));  
  35.       
  36.     MyDebugger_LEDs(blue, off);  
  37.     Delay(500);  
  38.   }  
  39. }  
  40.   
  41. void Delay(uint32_t nTime)  
  42. {   
  43.   Gb_TimingDelay = nTime;  
  44.   
  45.   while(Gb_TimingDelay != 0);  
  46. }  
  47.   
  48. void SysTick_Handler(void)  
  49. {  
  50.   if (Gb_TimingDelay != 0x00)  
  51.   {   
  52.     Gb_TimingDelay--;  
  53.   }  
  54. }  


运行结果:









更多 0

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多