因为数码管显示的过程中,经常会使用延时函数,在裸机中实现起来常常会长时间占用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;
}
即可实现数码管对数的显示。
附程序中的数码管接线图:
数码管硬件电路设计图如下: