RT-Thread中的數碼管顯示Demo

因爲數碼管顯示的過程中,經常會使用延時函數,在裸機中實現起來常常會長時間佔用CPU。
使用rt-thread的rt_thread_mdelay可以通過線程調度的方法,合理使用cpu資源。

新建一個smg.c文件:

/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-03-18     ShineRoyal       the first version
 */
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>

////74HC138操作線
#define LED_A0      GET_PIN(C,10) //A0地址線
#define LED_A1      GET_PIN(C,11) //A1地址線
#define LED_A2      GET_PIN(C,12) //A2地址線

////74HC595操作線
#define LED_DS      GET_PIN(B,3) //數據線
#define LED_LCLK    GET_PIN(B,4) //鎖存時鐘線
#define LED_SCK     GET_PIN(B,5) //時鐘線

//0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, .,全滅
const static rt_uint8_t smg_num[] = { 0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6, 0xee, 0x3e, 0x9c,
        0x7a, 0x9e, 0x8e, 0x01, 0x00 };

static uint32_t smg_value[8] = { 0 };    //數碼管顯示值

static int rt_hw_smg_init()
{
    rt_pin_mode(LED_A0, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_A1, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_A2, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_DS, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_LCLK, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_SCK, PIN_MODE_OUTPUT);
    return 0;
}
INIT_BOARD_EXPORT(rt_hw_smg_init);

static void smg_set_pos(rt_uint8_t num)
{
    rt_pin_write(LED_A0, (num & 0x01) >> 0);
    rt_pin_write(LED_A1, (num & 0x02) >> 1);
    rt_pin_write(LED_A2, (num & 0x04) >> 2);
}

static void smg_set_refresh(void)
{
    rt_pin_write(LED_LCLK, PIN_HIGH);
    rt_pin_write(LED_LCLK, PIN_LOW);
}

static void smg_set_data(rt_uint8_t data)
{
    rt_uint8_t i;
    for (i = 0; i < 8; i++)
    {
        rt_pin_write(LED_DS, (data >> i) & 0x01);
        rt_pin_write(LED_SCK, PIN_LOW);
        rt_pin_write(LED_SCK, PIN_HIGH);
    }
    smg_set_refresh();
}

void smg_set_value(uint32_t value)
{
    for (int i = 7; i >= 0; i--)
    {
        smg_value[i] = value % 10;
        value /= 10;
    }
}

static int smg_refresh_entry(void *param)
{
    uint8_t curpos = 0;
    while (1)
    {
    	//處理前導0的顯示
        for (curpos = 0; curpos < 7; curpos++)
        {
            if (smg_value[curpos] != 0)
                break;
            smg_set_data(0);
            smg_set_pos(curpos);
            smg_set_data(0);
            rt_thread_mdelay(2);
        }
        for (; curpos < 8; curpos++)
        {
            smg_set_data(0);
            smg_set_pos(curpos);
            smg_set_data(smg_num[smg_value[curpos]]);
            rt_thread_mdelay(2);
        }

    }
}

static int smg_refresh_init()
{
    rt_thread_t tid;
    tid = rt_thread_create("smg", smg_refresh_entry, RT_NULL, 1024, 20, 10);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }
    else
    {
        rt_kprintf("smg thread create failed\n");
    }
}
INIT_APP_EXPORT(smg_refresh_init);

在需要調用的地方進行外部聲明及調用:

/*
 * Copyright (c) 2006-2019, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2019-09-09     RT-Thread    first version
 */

#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

/* PLEASE DEFINE the LED0 pin for your board, such as: PA5 */
#define LED0_PIN    GET_PIN(C, 0)

extern void smg_set_value(uint32_t value);
int main(void)
{
    int count = 1;
    /* set LED0 pin mode to output */
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
    LOG_D("Hello RT-Thread!");
    while (count++)
    {
        /* set LED0 pin level to high or low */
        rt_pin_write(LED0_PIN, count % 2);
        smg_set_value(count);
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}

即可實現數碼管對數的顯示。

附程序中的數碼管接線圖:
數碼管硬件電路設計圖如下:
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章