九、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的验证程序:
/*********************************************
标题:MyDebugger
软件平台:IAR for ARM6.21
硬件平台:stm32f4-discovery
主频:168M
描述:实现一个调试工具
author:小船
data:2012-02-04
**********************************************/
#include
#include
/******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 plaincopy
// file:MyDebugger.h
#ifndef __MyDebugger_H#define __MyDebugger_H
#include
#include
/******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 plaincopy
// file:MyDebugger.c
#include
#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 plaincopy
/*********************************************
标题:MyDebugger
软件平台:IAR for ARM6.21
硬件平台:stm32f4-discovery
主频:168M
描述:实现一个调试工具
author:小船
data:2012-02-04
**********************************************/
#include
#include
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--;
}
}
运行结果:
上一篇:STM32F4xx 取得摄像头数据并进行处理
下一篇:stm32f407之DMA(操作寄存器)
推荐阅读
史海拾趣
2013年,ELESTA公司更名为ELESTA GmbH,这一品牌重塑标志着公司进入了新的发展阶段。同时,ELESTA也开始实施全球化战略,积极拓展国际市场,通过不断提升产品质量和服务水平,赢得了全球客户的信赖和认可。
1997年,ELESTA继电器有限公司正式成立,专注于制造符合IEC 61810-3标准的强制导向触点继电器。这一战略举措进一步巩固了ELESTA在电子继电器领域的领先地位,并为公司的长期发展奠定了坚实的基础。
在实现了从贸易到制造的转变后,依必安派特并没有停止前进的步伐。在2012年,依必安派特亚太研发中心正式落户上海,开始了本土化研发之路。这一举措使得依必安派特能够更好地了解中国市场的需求和趋势,为中国客户提供更加符合其需求的产品和解决方案。同时,本土化研发也加速了依必安派特在中国市场的创新步伐,推动了公司业务的快速发展。
为了进一步满足中国市场的本地化需求,依必安派特在2005年成立了依必安派特电机(上海)有限公司,开始了国产化进程。这一举措不仅提高了产品的性价比,还缩短了交货周期,使得依必安派特在中国市场的竞争力得到了显著提升。随着国产化产品的快速增长,依必安派特在中国的前十年市场业绩突飞猛进,为后续的飞跃发展打下了坚实基础。
为了进一步扩大市场份额和提升品牌影响力,Catalyst / ON Semiconductor公司开始实施全球扩张战略。公司先后在多个国家和地区设立了分支机构和研发中心,以便更好地服务当地客户并吸引优秀人才。同时,公司还积极与其他知名企业进行战略合作,共同推动半导体技术的创新和应用。
BusBoard公司的创始人李明,是一位具有远见卓识的电子工程师。他看到电子行业正处于飞速发展的阶段,但市场上缺乏一种高效、灵活的电路板解决方案。于是,他毅然决然地创立了BusBoard公司,致力于研发和生产标准化的电路板总线板,为电子设备制造商提供便捷的定制和升级服务。通过不懈努力,BusBoard公司的产品在市场上获得了广泛认可,为公司的发展奠定了坚实基础。
usb-blaster出现的怪问题,高手帮忙看一下,谢谢啦! 自己所用usb-blaster以前效果很好,有一次接到板子上后,下载线的芯片发热(时间有点久),最后拔下来后,再去试时,在设备管理器中可以看见发现了下载线,但是下载时以致出现以下错误,大家帮忙看看吧!!… 查看全部问答∨ |
|
我的工控机装的是XP系统,需要一个看门狗,所以需要我的程序对IO进行操作,但是XP下是不允许应用程序直接对IO进行操作的!那应该怎么做?请高手指教思路,是要自己写IO的驱动吗,一点思路都没有,请高手指教思路。谢谢… 查看全部问答∨ |
|
MSP-EXP430FR5739 USB Experimenter’s Board US14.5 剛剛從TI DEAL 中看到這則優惠,轉過來讓大家看看。http://tideals.com/有需要的可以直接買喔~… 查看全部问答∨ |
|