打印
[STM32F4]

【转】stm32f407之MyDebugger(操作寄存器)

[复制链接]
363|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一代掌门|  楼主 | 2016-9-10 20:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
已经学习了usart和DMA,因为后面的学习,最好有一个直观点的人性化的显示终端。可以通过串口将数据和文字信息发送往电脑,然后在上位机软件上观察数据以及调试信息。为此,我写了一个文件,以供日后调试之用,命名为MyDebugger。
         首先,参照之前的程序,略加修改,将USART的接收功能全部去掉,DMA的配置分开,独立写成一个配置DMA的函数USART3_DMA_config(),把发送的部分写到MyDebugger_Message(char *str_address, unsigned int str_len)函数内,很简单地实现了一个发送字符消息的函数。然后写一个操作板子上指示灯的函数,用以日后指示调试信息。具体的实现,请看下程序(实现MyDebugger的验证程序)。
         把验证程序分离写成头文件形式。方便以后其他工程使用。把程序稍作修改,利用条件编译,为以后可能的添加其他通信方式提供方便。要使用USART3作为调试通信方式,必须先定义宏MyDebug_with_USART3,如下图所示:



实现MyDebugger的验证程序:

[plain] view plain copy


  • /*********************************************  
  •     标题:MyDebugger  
  •     软件平台:IAR for ARM6.21  
  •     硬件平台:stm32f4-discovery  
  •     主频:168M  
  •       
  •     描述:实现一个调试工具  
  •             
  •     author:小船  
  •     data:2012-02-04  
  • **********************************************/  
  • #include <stm32f4xx.h>   
  • #include <stdbool.h>  
  •   
  • /******LED宏定义*******/  
  • #define green 0x00001000  
  • #define orange 0x00002000  
  • #define red 0x00004000  
  • #define blue 0x00008000  
  •   
  • /******全局变量及类型声明*******/  
  • bool USART_DMA_Completed;  
  • enum LED_State {on, off, turn};  
  •   
  • /******函数声明*******/  
  • void LEDs_Init(void);  
  • void USART3_DMA_config(void);  
  • void USART3_config(void);  
  • bool MyDebugger_Message(char *str_address, unsigned int str_len);  
  • void MyDebugger_LEDs(uint32_t LED, enum LED_State state);  
  •   
  • void main ()  
  • {   
  •   SysTick_Config(SystemCoreClock / 1000); //设置systemtick一毫秒中断  
  •   SCB->AIRCR = 0x05FA0000 | 0x400;  //中断优先级分组 抢占:响应=3:1  
  •   LEDs_Init();  
  •   USART3_DMA_config();  
  •   USART3_config();  
  •    
  •   USART_DMA_Completed = 1;  
  •    
  •   while(1)  
  •   {   
  •     MyDebugger_Message("My name is Xian Yongwen\n",   
  •                             sizeof("My name is Xian Yongwen\n")/sizeof(char));  
  •       
  •     MyDebugger_Message("广东石油化工学院\n",   
  •                             sizeof("广东石油化工学院\n")/sizeof(char));  
  •   }  
  • }  
  •   
  • /*********************************************  
  •   函数名:MyDebugger_Message  
  •   参数:char *str_address  :要发送的字符串地址  
  •         unsigned int str_len  :字符串的长度  
  •   返回值:bool  是否操作成功  
  •   功能:通过USART3发送信息  
  • **********************************************/  
  • bool MyDebugger_Message(char *str_address, unsigned int str_len)  
  • {   
  •     if( USART_DMA_Completed )  //之前数据已经发送完成  
  •     {   
  •       DMA1_Stream3->CR &= 0xFFFFFFFE;   //除能DMA1_Stream3  
  •       while(DMA1_Stream3->CR & 0x00000001); //确保DMA可以被设置      
  •       DMA1->LIFCR |= 0x0f800000;  //传送前清空DMA1_Stream3所有中断标志   
  •       DMA1_Stream3->M0AR = (uint32_t)str_address; //设置内存地址  
  •       if((USART3->SR & (1<<7))) //发送数据寄存器空  
  •       {  
  •         USART3->CR3 &= ~(1<<7);//usart3 dma发送模式除能  
  •         USART_DMA_Completed = 0;  
  •         DMA1_Stream3->NDTR = str_len; //设置dma传输数据的数量  
  •         DMA1_Stream3->CR |= 1;//使能dma  
  •         USART3->CR3 |= (1<<7);//usart3 dma发送模式使能  
  •         return true;  
  •       }   
  •     }   
  •     return false;  
  • }  
  •   
  • /****************************************  
  •   函数名:MyDebugger_LEDs  
  •   参数:uint32_t LED  :要操作哪些LED  
  •         enum LED_State state  :作何操作  
  •   返回值:无  
  •   功能:改变LED的状态  
  • ****************************************/  
  • void MyDebugger_LEDs(uint32_t LED, enum LED_State state)  
  • {  
  •   uint32_t tmp;  
  •   switch (state)  
  •   {  
  •     case on:  
  •       {  
  •         GPIOD->BSRRL |= LED;   
  •         break;  
  •       }  
  •     case off:  
  •       {  
  •         GPIOD->BSRRH |= LED;  
  •         break;  
  •       }  
  •     case turn:  
  •       {  
  •         tmp = (~GPIOD->ODR) & LED;     
  •         GPIOD->ODR &= ~LED;  
  •         GPIOD->ODR |= tmp;  
  •         break;  
  •       }   
  •   }  
  • }  
  •   
  • /****************************************  
  •   函数名:USART3_DMA_config  
  •   参数:无  
  •   返回值:无  
  •   功能:DMA1数据流3与usart3关联的相关配置  
  • ****************************************/  
  • void USART3_DMA_config(void)  
  • {  
  •   RCC->AHB1ENR |= (1<<21); //使能DMA1时钟  
  •   DMA1_Stream3->CR &= 0xFFFFFFFE; //除能DMA1_Stream3  
  •   while(DMA1_Stream3->CR & 0x00000001);//确保DMA可以被设置  
  •    
  •   DMA1->LIFCR |= 0x0f800000;//传送前清空DMA1_Stream3所有中断标志  
  •    
  •   DMA1_Stream3->PAR = (uint32_t)&USART3->DR;//设置外设地址USART3->DR地址0x40004804  
  •                                              //设置内存地址  
  •   DMA1_Stream3->FCR &= 0x00000000;  
  •   DMA1_Stream3->FCR |= (1<<7);//设置fifo  
  •   /*  
  •     设置dma通道4,即usart3tx  
  •     优先级最高  
  •     传输方向内存到外设  
  •     内存递增模式  
  •     传输完成中断使能  
  •   */  
  •   DMA1_Stream3->CR |= (0x08000000 | 0x00030000 | (1<<6)  
  •                        | (1<<10) | (1<<4) | (1<<2)|(1<<1));   
  •    
  •   NVIC->IP[14] = 0xA0;  
  •   NVIC->ISER[0] |= (1<<14);  
  •    
  • }  
  •   
  • /**************************  
  •   函数名:USART3_config  
  •   参数:无  
  •   返回值:无  
  •   功能:配置usart3  
  • ************************/  
  • void USART3_config(void)  
  • {  
  •   RCC->APB1ENR |= (1<<18);  //使能usart3时钟  
  •   RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟  
  •   USART3->BRR = 0x0000016C;   //波特率115200  
  •   /*  
  •    使能usart3  
  •   usart3发送使能  
  •   8bit  
  •   一位停止位  
  •   无校验  
  •   */  
  •   USART3->CR1 |= ( ( 1<<13 ) | ( 1<<3 ) );   
  •    
  •   GPIOD->AFR[1] |= 0x00000077;//选择PD8,9复用功能   
  •    
  •   GPIOD->MODER &= 0xFFF0FFFF; //设置PD8,9,复用模式  
  •   GPIOD->MODER |= 0x000A0000;   
  •       
  •   GPIOD->OSPEEDR &= 0xFFFCFFFF; //PD8速度50m  
  •   GPIOD->OSPEEDR |= 0x00020000;  
  •    
  •   GPIOD->PUPDR &= 0xFFFCFFFF; //PD8  
  •   GPIOD->PUPDR |= 0x00010000;  
  • }  
  •   
  • /****************************************  
  •   函数名:LEDs_Init  
  •   参数:无  
  •   返回值:无  
  •   功能:初始化板子上的LED  
  • ****************************************/  
  • void LEDs_Init(void)  
  • {  
  •   RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟  
  •    
  •   GPIOD->MODER &= 0x00FFFFFF; //设置PD12,13,14,15输出  
  •   GPIOD->MODER |= 0x55000000;   
  •    
  •   GPIOD->OTYPER &= 0xFFFF0FFF; //设置PD12,13,14,15推挽输出  
  •    
  •   GPIOD->OSPEEDR &= 0x00FFFFFF; //PD12,13,14,15 速度100m  
  •    
  •   GPIOD->PUPDR &= 0x00FFFFFF;  //PD12,13,14,15 无上拉无下拉  
  •    
  •   GPIOD->BSRRH = 0xf000;  //reset register GPIOx_BSRRH, write only  
  •                           //set register GPIOx_BSRRL, write only  
  • }  
  •   
  • void DMA1_Stream3_IRQHandler(void)  
  • {  
  •   if(DMA1->LISR & 0x08000000)//DMA传输完成  
  •   {  
  •     USART_DMA_Completed = 1;  
  •     DMA1->LIFCR |= 0x08000000;//清除中断标志  
  •   }  
  •   if(DMA1->LISR & 0x03000000)     //如果发生传输错误或直接模式错误,亮橙色LED  
  •   {  
  •     MyDebugger_LEDs( orange, on);  
  •     DMA1->LIFCR |= 0x03000000;  
  •   }  
  •   if(DMA1->LISR & (1<<22))  //如果发生fifo错误,亮红色指示灯  
  •   {  
  •     MyDebugger_LEDs( red, on);  
  •     DMA1->LIFCR |= (1<<22);  
  •   }  
  • }  



实用程序:

头文件:MyDebugger.h
[plain] view plain copy


  • <p>// file:MyDebugger.h</p>#ifndef __MyDebugger_H  
  • #define __MyDebugger_H  
  •   
  • #include <stm32f4xx.h>   
  • #include <stdbool.h>  
  •   
  • /******LED宏定义*******/  
  • #define green 0x00001000  
  • #define orange 0x00002000  
  • #define red 0x00004000  
  • #define blue 0x00008000  
  •   
  • /******全局变量及类型声明*******/  
  • enum LED_State {on, off, turn};  
  •   
  • /******函数声明*******/  
  • void MyDebugger_Init(void);  
  • bool MyDebugger_Message(char *str_address, unsigned int str_len);  
  • void MyDebugger_LEDs(uint32_t LED, enum LED_State state);  
  •   
  • #endif  



源文件:MyDebugger.c

[plain] view plain copy


  • // file:MyDebugger.c  
  • #include <MyDebugger.h>   
  •   
  • #ifdef MyDebug_with_USART3  
  •   
  • bool USART_DMA_Completed = true;  
  •   
  • /****************************************  
  •   函数名:USART3_DMA_config  
  •   参数:无  
  •   返回值:无  
  •   功能:DMA1数据流3与usart3关联的相关配置  
  • ****************************************/  
  • void USART3_DMA_config(void)  
  • {  
  •   RCC->AHB1ENR |= (1<<21); //使能DMA1时钟  
  •   DMA1_Stream3->CR &= 0xFFFFFFFE; //除能DMA1_Stream3  
  •   while(DMA1_Stream3->CR & 0x00000001);//确保DMA可以被设置  
  •    
  •   DMA1->LIFCR |= 0x0f800000;//传送前清空DMA1_Stream3所有中断标志  
  •    
  •   DMA1_Stream3->PAR = (uint32_t)&USART3->DR;//设置外设地址USART3->DR地址0x40004804  
  •                                              //设置内存地址  
  •   DMA1_Stream3->FCR &= 0x00000000;  
  •   DMA1_Stream3->FCR |= (1<<7);//设置fifo  
  •   /*  
  •     设置dma通道4,即usart3tx  
  •     优先级最高  
  •     传输方向内存到外设  
  •     内存递增模式  
  •     传输完成中断使能  
  •   */  
  •   DMA1_Stream3->CR |= (0x08000000 | 0x00030000 |   
  •                         (1<<6) | (1<<10) | (1<<4));   
  •    
  •   NVIC->IP[14] = 0xA0;  
  •   NVIC->ISER[0] |= (1<<14);  
  • }  
  •   
  • /**************************  
  •   函数名:USART3_config  
  •   参数:无  
  •   返回值:无  
  •   功能:配置usart3  
  • ************************/  
  • void USART3_config(void)  
  • {  
  •   RCC->APB1ENR |= (1<<18);  //使能usart3时钟  
  •   RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟  
  •   USART3->BRR = 0x0000016C;   //波特率115200  
  •   /*  
  •    使能usart3  
  •   usart3发送使能  
  •   8bit  
  •   一位停止位  
  •   无校验  
  •   */  
  •   USART3->CR1 |= ( ( 1<<13 ) | ( 1<<3 ) );   
  •    
  •   GPIOD->AFR[1] |= 0x00000077;//选择PD8,9复用功能   
  •    
  •   GPIOD->MODER &= 0xFFF0FFFF; //设置PD8,9,复用模式  
  •   GPIOD->MODER |= 0x000A0000;   
  •    
  • //  GPIOD->OTYPER &= 0xFFFFDFFF; //设置PD9推挽输出  
  •    
  •   GPIOD->OSPEEDR &= 0xFFFCFFFF; //PD8速度50m  
  •   GPIOD->OSPEEDR |= 0x00020000;  
  •    
  •   GPIOD->PUPDR &= 0xFFFCFFFF; //PD8  
  •   GPIOD->PUPDR |= 0x00010000;  
  • }  
  •   
  • void DMA1_Stream3_IRQHandler(void)  
  • {  
  •   if(DMA1->LISR & 0x08000000)//DMA传输完成  
  •   {  
  •     USART_DMA_Completed = 1;  
  •     DMA1->LIFCR |= 0x08000000;//清除中断标志  
  •   }  
  • }  
  • #endif  
  •   
  • /*********************************************  
  •   函数名:MyDebugger_Message  
  •   参数:char *str_address  :要发送的字符串地址  
  •         unsigned int str_len  :字符串的长度  
  •   返回值:bool  是否操作成功  
  •   功能:通过USART3发送信息  
  • **********************************************/  
  • bool MyDebugger_Message(char *str_address, unsigned int str_len)  
  • {     
  • #ifdef MyDebug_with_USB  
  •     bool USB_Actioned;  
  • #endif  
  •       
  • #ifdef MyDebug_with_USART3  
  •     bool USART3_Actioned;  
  •     if( USART_DMA_Completed )  //之前数据已经发送完成  
  •     {   
  •       DMA1_Stream3->CR &= 0xFFFFFFFE;   //除能DMA1_Stream3  
  •       while(DMA1_Stream3->CR & 0x00000001); //确保DMA可以被设置      
  •       DMA1->LIFCR |= 0x0f800000;  //传送前清空DMA1_Stream3所有中断标志   
  •       DMA1_Stream3->M0AR = (uint32_t)str_address; //设置内存地址  
  •       if((USART3->SR & (1<<7))) //发送数据寄存器空  
  •       {  
  •         USART3->CR3 &= ~(1<<7);//usart3 dma发送模式除能  
  •         USART_DMA_Completed = 0;  
  •         DMA1_Stream3->NDTR = str_len; //设置dma传输数据的数量  
  •         DMA1_Stream3->CR |= 1;//使能dma  
  •         USART3->CR3 |= (1<<7);//usart3 dma发送模式使能  
  •         USART3_Actioned = 1;  
  •       }   
  •     }  
  • #endif  
  •       
  • #ifdef MyDebug_with_USB  
  • //以后或许实现用USB发送调试信息的代码  
  •       
  •        //如果操作USB成功  
  •         USB_Actioned = 1;  
  • #endif  
  •   
  • #ifdef MyDebug_with_USART3  
  •   #ifndef MyDebug_with_USB      
  •     return USART3_Actioned;  
  •   #endif   
  • #endif  
  •   
  • #ifdef MyDebug_with_USB  
  •   #ifndef MyDebug_with_USART3      
  •     return USB_Actioned;  
  •   #endif   
  • #endif  
  •   
  • #ifdef MyDebug_with_USART3  
  •   #ifdef MyDebug_with_USB      
  •     return (USART3_Actioned | USB_Actioned);  
  •   #endif  
  • #endif      
  • }  
  •   
  • /****************************************  
  •   函数名:LEDs_Init  
  •   参数:无  
  •   返回值:无  
  •   功能:初始化板子上的LED  
  • ****************************************/  
  • void LEDs_Init(void)  
  • {  
  •   RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟  
  •    
  •   GPIOD->MODER &= 0x00FFFFFF; //设置PD12,13,14,15输出  
  •   GPIOD->MODER |= 0x55000000;   
  •    
  •   GPIOD->OTYPER &= 0xFFFF0FFF; //设置PD12,13,14,15推挽输出  
  •    
  •   GPIOD->OSPEEDR &= 0x00FFFFFF; //PD12,13,14,15 速度100m  
  •    
  •   GPIOD->PUPDR &= 0x00FFFFFF;  //PD12,13,14,15 无上拉无下拉  
  •    
  •   GPIOD->BSRRH = 0xf000;  //reset register GPIOx_BSRRH, write only  
  •                           //set register GPIOx_BSRRL, write only  
  • }  
  •   
  • /****************************************  
  •   函数名:MyDebugger_LEDs  
  •   参数:uint32_t LED  :要操作哪些LED  
  •         enum LED_State state  :作何操作  
  •   返回值:无  
  •   功能:改变LED的状态  
  • ****************************************/  
  • void MyDebugger_LEDs(uint32_t LED, enum LED_State state)  
  • {  
  •   uint32_t tmp;  
  •   switch (state)  
  •   {  
  •     case on:  
  •       {  
  •         GPIOD->BSRRL |= LED;   
  •         break;  
  •       }  
  •     case off:  
  •       {  
  •         GPIOD->BSRRH |= LED;  
  •         break;  
  •       }  
  •     case turn:  
  •       {  
  •         tmp = (~GPIOD->ODR) & LED;     
  •         GPIOD->ODR &= ~LED;  
  •         GPIOD->ODR |= tmp;  
  •         break;  
  •       }   
  •   }  
  • }  
  •   
  • /*********************************************  
  •   函数名:MyDebugger_Init  
  •   参数:无  
  •   返回值:无  
  •   功能:初始化MyDebugger  
  • **********************************************/  
  • void MyDebugger_Init(void)  
  • {  
  •   LEDs_Init();  
  •    
  • #ifdef MyDebug_with_USART3  
  •   USART3_DMA_config();  
  •   USART3_config();  
  • #endif  
  • }  




主程序文件:main.c

[plain] view plain copy


  • /*********************************************  
  •     标题:MyDebugger  
  •     软件平台:IAR for ARM6.21  
  •     硬件平台:stm32f4-discovery  
  •     主频:168M  
  •       
  •     描述:实现一个调试工具  
  •             
  •     author:小船  
  •     data:2012-02-04  
  • **********************************************/  
  • #include <stm32f4xx.h>   
  • #include <MyDebugger.h>   
  •   
  • uint32_t Gb_TimingDelay;  
  •   
  • void Delay(uint32_t nTime);  
  •   
  • void main ()  
  • {   
  •   SysTick_Config(SystemCoreClock / 1000); //设置systemtick一毫秒中断  
  •   //char test[15] = {0, 1, 2, 3, 4,  10, 11, 12, 13, 14, 15, 0xfe, 0xf0, 0x07, 0x09};  
  •   SCB->AIRCR = 0x05AF0000 | 0x400;  //中断优先级分组 抢占:响应=3:1  
  •   MyDebugger_Init();  
  •   while(1)  
  •   {   
  •     MyDebugger_Message("My name is Xian Yongwen\n\r",   
  •                             sizeof("My name is Xian Yongwen\n\r")/sizeof(char));  
  •       
  •     MyDebugger_LEDs(blue, on);  
  •     Delay(500);  
  •       
  •     MyDebugger_Message("广东石油化工学院\n\r",   
  •                             sizeof("广东石油化工学院\n\r")/sizeof(char));  
  •       
  •     MyDebugger_LEDs(blue, off);  
  •     Delay(500);  
  •   }  
  • }  
  •   
  • void Delay(uint32_t nTime)  
  • {   
  •   Gb_TimingDelay = nTime;  
  •   
  •   while(Gb_TimingDelay != 0);  
  • }  
  •   
  • void SysTick_Handler(void)  
  • {  
  •   if (Gb_TimingDelay != 0x00)  
  •   {   
  •     Gb_TimingDelay--;  
  •   }  
  • }  




运行结果:


发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

69

主题

191

帖子

4

粉丝