已经学习了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--;
- }
- }
运行结果:
|
|