打印
[N32L4xx]

测试开发板的GPIO输入输出,以及printf重定向到串口

[复制链接]
793|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 suncat0504 于 2022-2-11 16:27 编辑

#申请原创# #有奖活动#  @21小跑堂

前面我已经测试开发板的开发环境、下载环境。这个帖子,我将继续进行开发板的GPIO测试,主要是进行常规的输入输出测试,通俗点说,就是测试诸如键盘、LED,以及以printf这种方式通过串口输出数据的重定向测试。
这次我不再以N32G425那个开发板的模式建立工程,而是准备在RT-Thread Studio开发环境下,导入Keil建立的工程为例。闲话少说,马上操作。首先打开RT-Thread Studio开发界面,
“项目资源管理器”视图中,点击鼠标右键(当然也可以通过菜单中的文件->导入来操作),
点击“导入”
选择MDK项目到工作空间”,点击“下一步”,
在这个窗体中,我们要输入三个项目,
1、Keil工程文件,可以通过浏览选择你的Keil工程文件
2、KeilUV4.exe,可以通过浏览找到,一般就是在Keil安装目录下的UV4目录下
3、RT-Thread Studio中的工程名,可以是任意合法的名称,不需要和Keil工程名一致
我们就以LED闪烁的那个工程为例。在导入之前,需要说明的是,需要您下载国民技术提供的“通用MCU资料”,因为这里面会提供基于你的开发板所使用的微处理器对应的资料,包括例程。我这里要导入的例程,就是来自于国民技术提供的例程。下载地址在我前面的帖子里已经说明,这里我再强调一下:https://pan.baidu.com/s/1ckXJSocAKQtOyqjnreWN4w 提取码: mxxx 。记住,一定是和你的开发板MCU一致的工程。不一致的情况,我没测试,不敢说会是什么结果,也许编译不出问题,但是下载以及在开发板上能否执行,不确认。
点击“选择工程文件”行所在的“浏览”,找到“LedBlink”工程,并打开。
点击“MDK执行文件”行所在的“浏览”,找到UV4.EXE,点击“打开”,
“工程名称 ”中输入RT-Thread Studio中的工程名称,我这里以“LedBlinkDemo”为新名称。
点击“完成”,导入完成后,RT-Thread Studio开发环境会有提示信息,同时新工程也会出现在“项目资源管理器”中。
啥也不用改,直接编译试试,选中新导入的工程,右侧会出Active - Debug”提示,点击“小榔头”进行编译。编译成功后,“控制台”视图中依然会有提示信息,
这里我要专门说明一下工程里的资源参照问题,因为是导入MDK工程,在MDK工程中用到的一些文件,在RT-Thread Studio中是以参照的形式引入的,不是实体文件。比如主执行文件main.c,鼠标右键点击这个文件,选择弹出菜单中最下面的“属性”,在新弹出窗体中
显示这个main.c”文件的类型为“链接文件”,这意味着这个文件并不存在于RT-Thread Studioworkspace中,而还是在原来Keil工程目录中,在RT-Thread Studio中修改这个文件,相当于直接修改Keil工程中的这个文件。你可以用Keil打开原来的那个工程看看,是不是被修改了。
编译过程中可能会有警告信息,暂时不予理会,只要能生成烧写文件(BINelf)及没问题。为了确认是否真的生成了,可以展开“工程资源管理器”的“Debug”文件夹,看看在它下面能否找到“rtthreae.bin”这个文件。
这里显然是生成好了。接下来我们下载测试程序是否能正常跑起来。先确认下工程配置,点击“打开调试配置”图标,
找到Download”,如果你选择用BIN方式下载,请务必输入起始地址为“0x08000000”,这个地址你可以参照Keil中的配置,一般就是0x08000000。确定起始地址。如果想以HEX方式下载,你需要保证你的工程要能生成HEX文件。选择HEX方式,不需要设置地址,因为HEX格式的文件中已经包含了地址信息。选好后,点击“确定”,保存配置。
连接开发板到计算机,检查所在串口标号。点击RT-Thread Studio的下载图标的右侧下拉三角,确认使用的是DAP-LINK方式下载,如果不是请选择它。
之后我们直接下载试试,
咦,失败了啊。没关系,我们重新用Keil方式打开那个工程,
打开工程配置
选中Output,确认“Create HEX File”被勾选
选中Debug
修改LINK模式为CMSIS-DAP Debugger(CMSIS-DAP LINK的安装,在我之前的帖子里已经说明)
确认它的配置中和下载地址有关的信息
点击“确定”,回到Keil主界面,编译工程并下载
Keil下编译、下载成功了。
按下开发板的复位按钮,如果PB5对应的绿灯闪烁了,说明程序运行了。
再回到RT-Thread Studio执行下载,
也成功了。按下开发板的复位按钮,如果PB5对应的绿灯闪烁了,说明程序运行了。这样,我们就可以放心地在RT-Thread Studio下继续进行下一步的开发了。
下一步我们把串口的调试加进来。
在主函数的代码中找到LED1_PIN,选中。按F3功能键,目的是打开main.h文件(因为是链接文件,没法直接打开头文件),追加以下代码:
#define _USART1_COM_
#define USARTx            USART1
#define USARTx_GPIO       GPIOA
#define USARTx_CLK        RCC_APB2_PERIPH_USART1
#define USARTx_GPIO_CLK   RCC_APB2_PERIPH_GPIOA
#define USARTx_RxPin      GPIO_PIN_10
#define USARTx_TxPin      GPIO_PIN_9
#define USARTx_Rx_GPIO_AF GPIO_AF4_USART1
#define USARTx_Tx_GPIO_AF GPIO_AF4_USART1

#define GPIO_APBxClkCmd   RCC_EnableAPB2PeriphClk
#define USART_APBxClkCmd  RCC_EnableAPB2PeriphClk

void RCC_Configuration(void);
void GPIO_Configuration_USART(void);
void init(void);

main.c#include下面追加以下代码:

// 串口通讯用到的数据结构
USART_InitType USART_InitStructure;

在代码的最后面追加以下代码:
void init(void) {
    /* System Clocks Configuration */
    RCC_Configuration();

    /* Configure the GPIO ports */
    GPIO_Configuration_USART();

    /* USARTy and USARTz configuration ------------------------------------------------------*/
    USART_StructInit(&USART_InitStructure);
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;

    /* Configure USARTx */
    USART_Init(USARTx, &USART_InitStructure);
    /* Enable the USARTx */
    USART_Enable(USARTx, ENABLE);
}

/**
* @brief  Configures the different system clocks.
*/
void RCC_Configuration(void) {
    /* Enable GPIO clock */
    GPIO_APBxClkCmd(USARTx_GPIO_CLK, ENABLE);
    /* Enable USARTx Clock */
    USART_APBxClkCmd(USARTx_CLK, ENABLE);
}

/**
* @brief  Configures the different GPIO ports.
*/
void GPIO_Configuration_USART(void) {
    GPIO_InitType GPIO_InitStructure;

    /* Initialize GPIO_InitStructure */
    GPIO_InitStruct(&GPIO_InitStructure);

    /* Configure USARTx Tx as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTx_TxPin;
    GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = USARTx_Tx_GPIO_AF;
    GPIO_InitPeripheral(USARTx_GPIO, &GPIO_InitStructure);

    /* Configure USARTx Rx as alternate function push-pull and pull-up */
    GPIO_InitStructure.Pin            = USARTx_RxPin;
    GPIO_InitStructure.GPIO_Pull      = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Alternate = USARTx_Rx_GPIO_AF;
    GPIO_InitPeripheral(USARTx_GPIO, &GPIO_InitStructure);
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE* f) {
    USART_SendData(USARTx, (uint8_t)ch);
    while (USART_GetFlagStatus(USARTx, USART_FLAG_TXDE) == RESET) ;

    return (ch);
}
main主函数的while(1)循环之前加入以下代码:
    /* 初始化串口 */
init();

在主循环中加入以下代码:
        /* 输出启动信息 */
        printf("test the USART\n\r");
现在保存工程,进行编译。编译没有问题了,为了减少警告信息,把FWLB下的两个连接文件删除。编译工程,
下载
接下来,我们打开终端,用来观察开发板是否能向串口输出信息。
指定好各项参数,确定
出现
Unable to open connection:
Unable to configure serial port
说明串口打开失败了。没关系,我们可以拔下USB电缆重新接上,然后我们就会看到:
看到test the USART”,说明串口信息已经输出,printf的重定向没有问题。
接下来,我们继续加入按键的处理。
打开main.h文件,init函数的下面加上按键处理的初始化函数的声明:

void KeyInputInit(GPIO_Module* GPIOx, uint16_t Pin);

main.c文件的加上以下代码:
// 按键处理初始化
void KeyInputInit(GPIO_Module* GPIOx, uint16_t Pin)
{
    GPIO_InitType GPIO_InitStructure;

    /* Check the parameters */
    assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

    GPIO_InitStruct(&GPIO_InitStructure);
    /* Enable the GPIO Clock */
    if (GPIOx == GPIOA)
    {
        RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
    }
    else if (GPIOx == GPIOB)
    {
        RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
    }
    else if (GPIOx == GPIOC)
    {
        RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE);
    }
    else
    {
        if (GPIOx == GPIOD)
        {
            RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOD, ENABLE);
        }
    }

    /* Configure the GPIO pin as input floating*/
    if (Pin <= GPIO_PIN_ALL)
    {
        GPIO_InitStructure.Pin        = Pin;
        GPIO_InitStructure.GPIO_Pull    = GPIO_No_Pull;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Input;
        GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);
    }
}

main函数的开头加入以下代码:
    /* 初始化按键所在GPIO口模式:GPIO_Mode_Input */
KeyInputInit(GPIOA, GPIO_PIN_4);

while循环中用以下代码代替之前那个printf语句
/* 按键按下,输出信息 */
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_4) == Bit_SET) {
            printf("Key is pressed.\n\r");
    }

代码GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_4) == Bit_SET用来判断按键是否按下,不同开发板要用不同的条件,我这里用的是Bit_SET,按键对用于GPIOA口的PIN4,可能你的开发板要重新指定正确的GPIO口和PIN管脚,要用Bit_RESET来判断,具体根据开发板调整。


编译、下载。打开终端显示,按下开发板上的复位按钮
看到PB5对应的绿色LED闪烁,此时轻按KEY1PA4)按钮,终端显示区会出现“Key is pressed.”信息,说明按键的处理也已经OK了。
到这里,按键、LEDUSART的调试就完成了。附上测试图片和视频。

测试视频.zip (1.44 MB)


使用特权

评论回复
沙发
七毛钱| | 2022-2-6 16:14 | 只看该作者
学习学习,讲解很详细

使用特权

评论回复
板凳
N32MCU| | 2022-2-6 17:49 | 只看该作者
谢谢楼主的详细分享, 再补充几张硬件的使用图片就完美啦

使用特权

评论回复
地板
suncat0504|  楼主 | 2022-2-7 09:05 | 只看该作者
N32MCU 发表于 2022-2-6 17:49
谢谢楼主的详细分享, 再补充几张硬件的使用图片就完美啦

收到,

使用特权

评论回复
5
单片小菜| | 2022-2-8 16:36 | 只看该作者
这个帖子还是不错的,感谢楼主的分享。

使用特权

评论回复
6
豌豆爹| | 2022-2-9 09:53 | 只看该作者
很棒的测试贴

使用特权

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

本版积分规则

认证:大连伊飞特信息技术有限公司软件工程师
简介:本人于1993年毕业于大连理工大学。毕业后从事单片机开发工作5年,之后转入软件开发工作至今。

119

主题

3676

帖子

5

粉丝