RT-Thread STM32F407星火一号开发板BSP说明

RT-Thread STM32F407星火一号开发板BSP说明

在这里插入图片描述

简介

本文档为 RT-Thread 开发团队为 STM32F407 星火1号开发板提供的 BSP (板级支持包) 说明。

主要内容如下:

  • 开发板资源介绍
  • BSP 快速上手
  • 进阶使用方法

通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。在进阶使用指南章节,将会介绍更多高级功能,帮助开发者利用 RT-Thread 驱动更多板载资源。

开发板介绍

星火号 STM32F407 是RT-THREAD推出的一款基于 ARM Cortex-M4 内核的开发板,最高主频为 168Mhz,该开发板具有丰富的板载资源,可以充分发挥 STM32F407 的芯片性能。

开发板外观如下图所示:
在这里插入图片描述

该开发板常用 板载资源 如下:

  • MCU:STM32F407ZGT6,主频 168MHz,1024KB FLASH ,192KB RAM
  • 外部 FLASH:W25Q128(SPI,16MB)
  • 常用外设
    • LED:2个,LED_R(红色,PF12),LED_B(绿色,PF11)
    • 按键,4个,KEY_UP(兼具唤醒功能,PIN:PC5),KEY_DOWN(PIN:PC1),KEY_LEFT(PIN:PC0),KEY_RIGHT(PIN:PC4)
  • 常用接口:USB 转串口、SD 卡接口、USB SLAVE、USB HOST
  • 调试接口,标准ST-LINK

开发板更多详细信息请参考官方文档 STM32 星火一号开发板介绍

外设支持

本 BSP 目前对外设的支持情况如下:

板载外设支持情况备注
USB 转串口(COM1)支持
COM2支持和以太网、PWM 冲突,如需使用该外设,请使用 CubeMX 重新配置 UART2 管脚
COM3支持
片上外设支持情况备注
UART支持UART1/2/3
SPI支持SPI1/2/3
ADC支持
RTC支持支持外部晶振和内部低速时钟
WDT支持

使用说明

使用说明分为如下两个章节:

  • 快速上手

    本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。

  • 进阶使用

    本章节是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。

快速上手

本 BSP 为开发者提供 MDK5 和 IAR 工程,并且支持 GCC 开发环境。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。

硬件连接

使用数据线连接开发板到 PC,打开电源开关。

编译下载

双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。

工程默认配置使用 JLink 下载程序,在通过 JLink 连接开发板的基础上,点击下载按钮即可下载程序到开发板

运行结果

下载程序成功之后,系统会自动运行,观察开发板上 LED 的运行效果,红色 LED 常亮、绿色 LED 会周期性闪烁。

连接开发板对应串口到 PC , 在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-Thread 的输出信息:


 \ | /
- RT -     Thread Operating System
 / | \     5.0.1 build Jul  4 2023 07:49:10
 2006 - 2022 Copyright by RT-Thread team
msh >

进阶使用

此 BSP 默认只开启了 GPIO 和 串口1 的功能,如果需使用 SD 卡、Flash 等更多高级功能,需要利用 ENV 工具对BSP 进行配置,步骤如下:

  1. 在 bsp 下打开 env 工具。

  2. 输入menuconfig命令配置工程,配置好之后保存退出。

  3. 输入pkgs --update命令更新软件包。

  4. 输入scons --target=mdk5/iar 命令重新生成工程。

本章节更多详细的介绍请参考 STM32 系列 BSP 外设驱动使用教程

注意事项

暂无

示例代码

…\components\drivers\i2c\i2c-bit-ops.c

static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus_device *bus, int ack)
{
    struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;

    if (ack)
        SET_SDA(ops, 0);
    i2c_delay(ops);
    if (SCL_H(ops) < 0)
    {
        LOG_E("ACK or NACK timeout.");

        return -RT_ETIMEOUT;
    }
    SCL_L(ops);

    return RT_EOK;
}

static rt_ssize_t i2c_recv_bytes(struct rt_i2c_bus_device *bus,
                                struct rt_i2c_msg        *msg)
{
    rt_int32_t val;
    rt_int32_t bytes = 0;   /* actual bytes */
    rt_uint8_t *ptr = msg->buf;
    rt_int32_t count = msg->len;
    const rt_uint32_t flags = msg->flags;

    while (count > 0)
    {
        val = i2c_readb(bus);
        if (val >= 0)
        {
            *ptr = val;
            bytes ++;
        }
        else
        {
            break;
        }

        ptr ++;
        count --;

        LOG_D("recieve bytes: 0x%02x, %s",
                val, (flags & RT_I2C_NO_READ_ACK) ?
                "(No ACK/NACK)" : (count ? "ACK" : "NACK"));

        if (!(flags & RT_I2C_NO_READ_ACK))
        {
            val = i2c_send_ack_or_nack(bus, count);
            if (val < 0)
                return val;
        }
    }

    return bytes;
}

static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus,
                                   rt_uint8_t                addr,
                                   rt_int32_t                retries)
{
    struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
    rt_int32_t i;
    rt_err_t ret = 0;

    for (i = 0; i <= retries; i++)
    {
        ret = i2c_writeb(bus, addr);
        if (ret == 1 || i == retries)
            break;
        LOG_D("send stop condition");
        i2c_stop(ops);
        i2c_delay2(ops);
        LOG_D("send start condition");
        i2c_start(ops);
    }

    return ret;
}

static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus,
                                     struct rt_i2c_msg        *msg)
{
    rt_uint16_t flags = msg->flags;
    rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
    struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;

    rt_uint8_t addr1, addr2;
    rt_int32_t retries;
    rt_err_t ret;

    retries = ignore_nack ? 0 : bus->retries;

    if (flags & RT_I2C_ADDR_10BIT)
    {
        addr1 = 0xf0 | ((msg->addr >> 7) & 0x06);
        addr2 = msg->addr & 0xff;

        LOG_D("addr1: %d, addr2: %d", addr1, addr2);

        ret = i2c_send_address(bus, addr1, retries);
        if ((ret != 1) && !ignore_nack)
        {
            LOG_W("NACK: sending first addr");

            return -RT_EIO;
        }

        ret = i2c_writeb(bus, addr2);
        if ((ret != 1) && !ignore_nack)
        {
            LOG_W("NACK: sending second addr");

            return -RT_EIO;
        }
        if (flags & RT_I2C_RD)
        {
            LOG_D("send repeated start condition");
            i2c_restart(ops);
            addr1 |= 0x01;
            ret = i2c_send_address(bus, addr1, retries);
            if ((ret != 1) && !ignore_nack)
            {
                LOG_E("NACK: sending repeated addr");

                return -RT_EIO;
            }
        }
    }
    else
    {
        /* 7-bit addr */
        addr1 = msg->addr << 1;
        if (flags & RT_I2C_RD)
            addr1 |= 1;
        ret = i2c_send_address(bus, addr1, retries);
        if ((ret != 1) && !ignore_nack)
            return -RT_EIO;
    }

    return RT_EOK;
}

static rt_ssize_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
                              struct rt_i2c_msg         msgs[],
                              rt_uint32_t               num)
{
    struct rt_i2c_msg *msg;
    struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
    rt_int32_t ret;
    rt_uint32_t i;
    rt_uint16_t ignore_nack;

    if (num == 0) return 0;

    for (i = 0; i < num; i++)
    {
        msg = &msgs[i];
        ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
        if (!(msg->flags & RT_I2C_NO_START))
        {
            if (i)
            {
                i2c_restart(ops);
            }
            else
            {
                LOG_D("send start condition");
                i2c_start(ops);
            }
            ret = i2c_bit_send_address(bus, msg);
            if ((ret != RT_EOK) && !ignore_nack)
            {
                LOG_D("receive NACK from device addr 0x%02x msg %d",
                        msgs[i].addr, i);
                goto out;
            }
        }
        if (msg->flags & RT_I2C_RD)
        {
            ret = i2c_recv_bytes(bus, msg);
            if (ret >= 1)
            {
                LOG_D("read %d byte%s", ret, ret == 1 ? "" : "s");
            }
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_EIO;
                goto out;
            }
        }
        else
        {
            ret = i2c_send_bytes(bus, msg);
            if (ret >= 1)
            {
                LOG_D("write %d byte%s", ret, ret == 1 ? "" : "s");
            }
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_ERROR;
                goto out;
            }
        }
    }
    ret = i;

out:
    if (!(msg->flags & RT_I2C_NO_STOP))
    {
        LOG_D("send stop condition");
        i2c_stop(ops);
    }

    return ret;
}

static const struct rt_i2c_bus_device_ops i2c_bit_bus_ops =
{
    i2c_bit_xfer,
    RT_NULL,
    RT_NULL
};

rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus_device *bus,
                            const char               *bus_name)
{
    bus->ops = &i2c_bit_bus_ops;

    return rt_i2c_bus_device_register(bus, bus_name);
}

源码下载

…\bsp\stm32\stm32f407-rt-spark\project.uvproj

在这里插入图片描述


RT-Thread STM32F407星火一号开发板BSP说明 源码下载


维护人:

RT-Thread作品秀】基于RT-Thread的智能家居-物联网作者:葫芦侠 概述(说明应用产生的背景、实现功能)智能家居是在互联网影响之下物联化的体现。智能家居通过物联网技术将家中的各种设备连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。与普通家居相比,智能家居不仅具有传统的居住功能,兼备建筑、网络通信、信息家电、设备自动化,提供全方位的信息交互功能。 本智能家居应用平台基于STM32F407和ESP8266为主芯片进行设计。主控平台以原子STM32F407开发板为核心,主要任务是通过以太网与设备节点和应用软件进行数据交互。 开发环境(所采用的软、硬件方案)硬件:原子STM32F407探索者、ESP8266、S17021、DS18B20、LED、130电机 RT-Thread版本:rt-thread-3.1.4 开发工具及版本:MDK 5.31,VS CODE,Qt Creator 4.11.1,NetAssist 4.3.26, UartAssist4.3.25 RT-Thread使用情况概述(简要总结下应用中RT-Thread使用情况:内核部分、组件部分、软件包部分、内核、其他)(1)、内核部分:调度器,消息队列。 调度器:创建tcp连接线程。 消息队列:用来实现线程之间的数据传递。 (2)组件部分:网络框架 网络框架:使用tcp/ip建立服务端,用于设备节点和上层控制软件接入。 (3)软件包:Cjson 硬件框架(概述应用所采用的硬件方案框图,并对核心部分做介绍)硬件方案图 智能家居应用平台方案框图如下图所示。主要由三部分组成,分别是主控平台、节点平台和应用软件平台。 系统介绍 主控平台平台与各个节点主控通信,主控通过网络控制和获取各个节点设备数据和状态。上位机应用软件通过网络发送数据到主控,获取设备状态和进行设备控制。 软件框架说明(介绍应用所采用的软件方案框图、流程图等,并加以解说)本项目采用的是STM32主控作为服务器,显示相关节点传感器数据。节点主控、上位机应用软件通过TCP/IP连接至主控。应用软件通过网络将指令发送到主控,主控将指令转发到节点主控,已达到设备控制。节点主控将采集到的数据通过网络发送到STM32主控,STM32显示相关数据,并将数据转发至上位机。 软件模块说明(介绍应用软件关键部分的逻辑、采用的实现方式等)主控平台软件: (1)4.3 TFFLCD (2)界面设计使用SteamWin (3)以太网 演示效果(演示效果请采用3张高清图片,并录制一段不少于1min视频解说应用所实现的效果,视频上传至B站或者腾讯视频或其他视频平台,给出链接即可视频: 比赛感悟(可以围绕这次比赛学到了什么,克服了哪些困难,有哪些收获,不低于200字)本次比赛发现自己的题目做大了,导致时间紧迫。需要完成STM32的代码,ESP8266代码,还有安卓代码。工作时,由于有大量的出差,导致项目一直不能按期推进。由于第一次使用rt-thread,调试多线程,网络、lcd显示花费大量时间。本来打算还要使用触摸屏,但是到最后发现时间已经不够了。由于屏幕使用了图片,下载调试速度慢,也花费了不少的时间。调试ESP8266使用vs code,编译下载特别慢,也花费了不少时间。三个平台之间的通信也是非常的耗费时间。 总之,作为一名技术人员,感觉调试花费的时间要比写代码花费的时间长。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华为奋斗者精神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值