rtthread系统 - 普中stm32开发板 - 数码管驱动

数码管设备

前面系统移植时候,已经将数码管的小数点位作为系统指示灯,所以在这的数码管设备就屏蔽掉小数点位,保持独立。

数码管IO配置

先看硬件原理图
在这里插入图片描述
在这里插入图片描述

数码管是共阳数码管,另一脚接到PC0~PC7,PC7已经用来做系统指示灯,把对应引脚电平拉低,对应数码管段就点亮。GPIO在RT-thread中已经默认注册,只需在驱动中初始化IO口模式即可。

数码管设备配置

数码管属于板上设备,接下来要干三件事,创建驱动文件、添加Kconfig配置项、修改SConscript文件依赖。
在对应bsp的“\board\ports”目录下(没有“ports”文件夹就自行创建)创建“drv_digitron.c”和“drv_digitron.h”文件,作为驱动文件,驱动内容后面写。
打开对应bsp的“\board”目录下的“Kconfig”文件,在以下的菜单目录下

menu “Onboard Peripheral Drivers”

添加以下字段

config BSP_USING_DIGITRON
    bool "Enable DIGITRON"
    select BSP_USING_GPIO
    default n 

打开对应bsp的“\board”目录下的“SConscript”文件,在这个字眼后面

src = Split('''
board.c
CubeMX_Config/Src/stm32f1xx_hal_msp.c
''')

添加文件依赖

if GetDepend(['BSP_USING_DIGITRON']):
    src += Glob('ports/drv_digitron.c')

如果没有包含“ports”头文件路径,则需要在“path”定义的字眼后面添加头文件路径

path += [cwd + '/ports']

这三件事做完后,就打开图形化配置工具

menuconfig

进入到以下目录

Hardware Drivers Config
—> Onboard Peripheral Drivers

选中刚才新增“Enable DIGITRON”项,保存配置,退出,重新生成工程。

scons --target=mdk5

打开工程,发现工程中添加了刚才新创建的“drv_digitron.c”和“drv_digitron.h”文件,编译,没有报错,接下来就是完成驱动的编写。

数码管驱动编写

驱动头文件中,首先就包含以下三个驱动必备的头文件

#include <rtthread.h>
#include "rtdevice.h"
#include <drv_common.h>

然后就是定义数码管设备结构体,因为数码管设备简单,直接继承设备通用类即可

struct drv_digitron_device
{
    struct rt_device parent;
};

源文件首先添加以下东西

#include <rtthread.h>

#include "drv_gpio.h"					// 是从gpio驱动衍生出来的数码管驱动
#include "drv_digitron.h"

#define DBG_TAG "drv.digitron"
#include <drv_log.h>

然后定义一个单例静态设备实体

static struct drv_digitron_device _digitron;

接下来就根据通用设备的函数操作集来完成相应的函数

/**
 * operations set for device object
 */
struct rt_device_ops
{
    /* common device interface */
    rt_err_t  (*init)   (rt_device_t dev);
    rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
    rt_err_t  (*close)  (rt_device_t dev);
    rt_size_t (*read)   (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
    rt_size_t (*write)  (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
    rt_err_t  (*control)(rt_device_t dev, int cmd, void *args);
};

在数码管设备里面,目前需要用到的函数,就只有初始化和写,控制函数的话也可以根据情况添加。
首先是初始化函数,初始化函数里面需要完成的一般是两部分内容,一个是硬件的初始化,一个是软件的初始化(这个软件的初始化可以适当的在有打开函数里面完成)。参考如下

void digitron_pin_init(void)
{
    rt_pin_mode(GET_PIN(C, 0), PIN_MODE_OUTPUT);
    rt_pin_mode(GET_PIN(C, 1), PIN_MODE_OUTPUT);
    rt_pin_mode(GET_PIN(C, 2), PIN_MODE_OUTPUT);
    rt_pin_mode(GET_PIN(C, 3), PIN_MODE_OUTPUT);
    rt_pin_mode(GET_PIN(C, 4), PIN_MODE_OUTPUT);
    rt_pin_mode(GET_PIN(C, 5), PIN_MODE_OUTPUT);
    rt_pin_mode(GET_PIN(C, 6), PIN_MODE_OUTPUT);

    digitron_show(0);
}

把这个初始化函数放在标准接口里面调用即可。其中显示函数如下

// 0~F
uint8_t digitron_ascii_map[16] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};

void digitron_show(uint8_t data)
{
    uint8_t i = 0;

    if ((0 <= data && data < sizeof(digitron_ascii_map) / sizeof(digitron_ascii_map[0])) || 
        data == 0xFF)
    {
        for (i = 0; i < 7; i++) // 小数点做系统灯,不用处理
        {
            rt_pin_write(GET_PIN(C, i), ((digitron_ascii_map[data] >> i) & 1) == 1 ? PIN_LOW : PIN_HIGH);
        }
    } 
}

然后写函数,参考如下

static rt_size_t drv_digitron_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
    RT_ASSERT(dev);
    RT_ASSERT(size <= sizeof(uint8_t));

    uint8_t data = (uint8_t)buffer;

    digitron_show(data);

    return sizeof(data);
}

就是“buffer”传进什么数字就显示什么数字。
控制函数,参考如下

static rt_err_t drv_digitron_control(rt_device_t dev, int cmd, void *args)
{
    struct drv_digitron_device *digitron = (struct drv_digitron_device *)dev;

    switch (cmd)
    {
    case DIGITRON_CTRL_SET_SHOW:
    {
        uint8_t data = (uint8_t)args;
        uint8_t i = 0;

        for (i = 0; i < 7; i++) // 小数点做系统灯,不用处理
        {
            rt_pin_write(GET_PIN(C, i), ((data >> i) & 1) == 1 ? PIN_LOW : PIN_HIGH);
        }
    }
    break;
    }

    return RT_EOK;
}

控制函数,“DIGITRON_CTRL_SET_SHOW”命令可以控制数码管显示特定内容。
最后就是将设备注册到系统。

#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops digitron_ops = {
    drv_digitron_init,
    RT_NULL,
    RT_NULL,
    RT_NULL,
    drv_digitron_write,
    drv_digitron_control
};
#endif

int drv_digitron_hw_init(void)
{
    rt_err_t result = RT_EOK;
    struct rt_device *device = &_digitron.parent;

    /* memset _digitron to zero */
    rt_memset(&_digitron, 0x00, sizeof(_digitron));

    device->type = RT_Device_Class_Miscellaneous;
#ifdef RT_USING_DEVICE_OPS
    device->ops = &digitron_ops;
#else
    device->init = drv_digitron_init;
    device->write = drv_digitron_write;
    device->control = drv_digitron_control;
#endif
    device->user_data = RT_NULL;
    /* register digitron device */
    result = rt_device_register(device, "digitron", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
    if (result != RT_EOK)
    {
        LOG_E("digitron register err code: %d", result);
        return result;
    }
    LOG_I("digitron register success");

    return result;
}
INIT_DEVICE_EXPORT(drv_digitron_hw_init);

文件链接

驱动文件链接

结尾

rtthread学习中,打开主页查看更多笔记

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值