打印
[技术讨论]

分享一个4位时间数码管的驱动

[复制链接]
122|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qinlu123|  楼主 | 2024-4-8 10:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
该驱动可实现任意位开关显示、任意位闪烁、任意位小数点开关显示。稍微修改代码可以扩展更多位数码管。
#include "Dig_pipe.h"

#define MAXNUM 4 //数码管位数

struct Dig DigAll;
/*0,1,2,3,4,5,6,7,8,9*/
static uint8_t Display_Data[10]={
                                                 0x3f,0x06,0x5b,0x4f,0x66,
                                                 0x6d,0x7d,0x07,0x7f,0x6f,
                                               };

static void Data_display(uint8_t Data)
{
        Dig_A(Data & 0x01);
        Dig_B((Data>>1) & 0x01);
        Dig_C((Data>>2) & 0x01);
        Dig_D((Data>>3) & 0x01);
        Dig_E((Data>>4) & 0x01);
        Dig_F((Data>>5) & 0x01);
        Dig_G((Data>>6) & 0x01);
        Dig_dp((Data>>7) & 0x01);
}
/*
若要扩展数码管位数,公共控制端IO需要增加
*/
static void AllOff(void)
{
        DIG1 = 1;
        DIG2 = 1;
        DIG3 = 1;
        DIG4 = 1;
        Data_display(0);
}
static void Dig1(uint8_t a)
{
        if(a!=0)
        {
                DIG1=0;
        }
        else
        {
                DIG1=1;
        }
}
static void Dig2(uint8_t a)
{
        if(a!=0)
        {
                DIG2=0;
        }
        else
        {
                DIG2=1;
        }
}
static void Dig3(uint8_t a)
{
        if(a!=0)
        {
                DIG3=0;
        }
        else
        {
                DIG3=1;
        }
}
static void Dig4(uint8_t a)
{
        if(a!=0)
        {
                DIG4=0;
        }
        else
        {
                DIG4=1;
        }
}
/*
        数码管显示逻辑
*/
static void DigSingleDisplay(void (*Dig)(uint8_t a),uint8_t ZeroDead,uint16_t Count,uint8_t ID,uint8_t Data)
{
        uint8_t DisData;
       
        /*关掉所有数码管*/
        AllOff();
        /*判断该位数码管本次需不需要显示*/
        if(((DigAll.OnOff>>(MAXNUM-ID))&0x01) != 0)
        {
                /*判断该位数码管需不需要灭零*/
                if((ZeroDead==0) || (Data!=0))
                {
                        /*判断该位数码管需不需要打开小数点*/
                        if(((DigAll.Point>>(MAXNUM-ID))&0x01) != 0)
                        {
                                DisData = (Display_Data[Data] | 0x80);
                                Data_display(0x80);
                        }
                        else
                        {
                                DisData = Display_Data[Data];
                        }
                        /*判断该位数码管需不需要闪烁*/
                        if(((DigAll.Blink>>(MAXNUM-ID))&0x01) != 0)
                        {
                                if(((Count/250)%2) !=0 )
                                {
                                        Data_display(DisData);
                                }
                        }
                        else
                        {
                                Data_display(DisData);
                        }
                }
                /*打开该位公共控制端*/
                Dig(1);
        }
}
/*
        数码管扫描
*/
void DigDisplay(uint16_t TimeTick_Count)
{
        static uint8_t count = 0;
       
        switch(count)
        {
                case 0:
                {
                        /*
                                若需要灭零,灭零逻辑放在这里
                        */
                        DigSingleDisplay(Dig1,1,TimeTick_Count,1,DigAll.NumH/10);
                        count++;
                }break;
                case 1:
                {
                        /*
                                若需要灭零,灭零逻辑放在这里
                        */
                        DigSingleDisplay(Dig2,0,TimeTick_Count,2,DigAll.NumH%10);
                        count++;
                }break;
                case 2:
                {
                        /*
                                若需要灭零,灭零逻辑放在这里
                        */
                        DigSingleDisplay(Dig3,0,TimeTick_Count,3,DigAll.NumL/10);
                        count++;
                }break;
                case 3:
                {
                        /*
                                若需要灭零,灭零逻辑放在这里
                        */
                        DigSingleDisplay(Dig4,0,TimeTick_Count,4,DigAll.NumL%10);
                        count=0;
                }break;
                /*
                        若需要扩展数码管位数需要继续增加case
                */
                default:
                {
                        count=0;
                }break;
        }
        /*
                时间标志":"控制
        */
        if(((DigAll.OnOff>>MAXNUM)&0x01) == 0)
        {
                TIMEFLAG = 0;
        }
        else if(((DigAll.Blink>>MAXNUM)&0x01) != 0)
        {
                if(((TimeTick_Count/500)%2) != 0)
                {
                        TIMEFLAG = 0;
                }
                else
                {
                        TIMEFLAG = 1;
                }
        }
        else
        {
                TIMEFLAG = 1;
        }
}
/*
        数码管显示数据及亮灭控制
*/
void Dig_Config(uint8_t NumH,uint8_t NumL,uint8_t OnOff,uint8_t Blink,uint8_t Point)
{
        DigAll.NumH = NumH;
        DigAll.NumL = NumL;
        DigAll.OnOff = OnOff;
        DigAll.Blink = Blink;
        DigAll.Point = Point;
}


以下是"Dig_pipe.h"内容

#ifndef __DIG_H
#define __DIG_H

#include "Header.h"

#define LED1 PAout(15)
#define LED2 PBout(3)
#define LED3 PBout(4)
#define LED4 PBout(5)

#define Dig_A(a) {PAout(12)=a;}
#define Dig_B(a) {PAout(8)=a;}
#define Dig_C(a) {PBout(13)=a;}
#define Dig_D(a) {PAout(9)=a;}
#define Dig_E(a) {PAout(11)=a;}
#define Dig_F(a) {PAout(10)=a;}
#define Dig_G(a) {PBout(12)=a;}
#define Dig_dp(a) {PBout(15)=a;}

#define DIG1 PBout(1)
#define DIG2 PBout(2)
#define DIG3 PBout(10)
#define DIG4 PBout(11)

#define TIMEFLAG PBout(14)

struct Dig
{
        uint8_t NumH,NumL;//若要扩展数码管位数需要增加要显示的变量或者直接改成数组
        uint32_t OnOff;//每一个bit控制一个数码管的开关,该变量和数码管实物采用右对齐方式
        uint32_t Blink;//每一个bit控制一个数码管的闪烁,该变量和数码管实物采用右对齐方式
        uint16_t Point;//每一个bit控制一个小数点的开关,该变量和数码管实物采用右对齐方式
};
extern struct Dig DigAll;
extern struct MoveFilPara MF_PFB;

void DigDisplay(uint16_t TimeTick_Count);
void Dig_Config(uint8_t NumH,uint8_t NumL,uint8_t OnOff,uint8_t Blink,uint8_t Point);

#endif


以下是任务调度
#include "TaskMgr.h"

uint8_t Sys_Status=0;
uint16_t Item_OverTime_Count=0;
uint16_t TimeTick_Count=0;
uint8_t Task_1ms_EN=0,Task_2ms_EN=0,Task_5ms_EN=0,Task_10ms_EN=0,Task_20ms_EN=0,Task_50ms_EN=0,Task_100ms_EN=0,Task_500ms_EN=0,Task_1000ms_EN=0,Task_5000ms_EN=0;
uint8_t TCL=0;
/**************************************************/

static void SysTimeTikeCounting(void)
{
        TCL = 1;
        if(TimeTick_Count>60000)
        {
                TimeTick_Count=1;
        }
        else
        {
                TimeTick_Count++;
        }
}
static void Task_1ms(void)
{
        DigDisplay(TimeTick_Count);
}
static void Task_2ms(void)
{
       
}
static void Task_5ms(void)
{
       
}
static void Task_10ms(void)
{
}
static void Task_20ms(void)
{
       
}
static void Task_50ms(void)
{
}
static void Task_100ms(void)
{
       
}
static void Task_500ms(void)
{
       
}
static void Task_1000ms(void)
{
}
static void Task_5000ms(void)
{
}
static void TaskPolls(void)
{
        if(TCL)
        {
                TCL = 0;
               
                if((TimeTick_Count%1)==0)
                {
                        Task_1ms_EN=1;
                }
                if((TimeTick_Count%2)==0)
                {
                        Task_2ms_EN=1;
                }
                if((TimeTick_Count%5)==0)
                {
                        Task_5ms_EN=1;
                }
                if((TimeTick_Count%10)==0)
                {
                        Task_10ms_EN=1;
                }
                if((TimeTick_Count%20)==0)
                {
                        Task_20ms_EN=1;
                }
                if((TimeTick_Count%50)==0)
                {
                        Task_50ms_EN=1;
                }
                if((TimeTick_Count%100)==0)
                {
                        Task_100ms_EN=1;
                }
                if((TimeTick_Count%500)==0)
                {
                        Task_500ms_EN=1;
                }
                if((TimeTick_Count%1000)==0)
                {
                        Task_1000ms_EN=1;
                }
                if((TimeTick_Count%5000)==0)
                {
                        Task_5000ms_EN=1;
                }
        }
       
        if(Task_1ms_EN)
        {
                Task_1ms_EN=0;
                Task_1ms();
        }
        if(Task_2ms_EN)
        {
                Task_2ms_EN=0;
                Task_2ms();
        }
        if(Task_5ms_EN)
        {
                Task_5ms_EN=0;
                Task_5ms();
        }
        if(Task_10ms_EN)
        {
                Task_10ms_EN=0;
                Task_10ms();
        }
        if(Task_20ms_EN)
        {
                Task_20ms_EN=0;
                Task_20ms();
        }
        if(Task_50ms_EN)
        {
                Task_50ms_EN=0;
                Task_50ms();
        }
        if(Task_100ms_EN)
        {
                Task_100ms_EN=0;
                Task_100ms();
        }
        if(Task_500ms_EN)
        {
                Task_500ms_EN=0;
                Task_500ms();
        }
        if(Task_1000ms_EN)
        {
                Task_1000ms_EN=0;
                Task_1000ms();
        }
        if(Task_5000ms_EN)
        {
                Task_5000ms_EN=0;
                Task_5000ms();
        }
}
void Sys_INIT(void)
{
        /* USER CODE BEGIN PV */
       
        /* USER CODE END PV */
}
/*
  1ms滴答调用
*/
void SYSTICK_Callback(void)
{
        SysTimeTikeCounting();
        /* USER CODE BEGIN PV */

        /* USER CODE END PV */
}
/*
  大循环调用
*/
void SystemRun(void)
{       
        TaskPolls();
        /* USER CODE BEGIN PV */
        Dig_Config(12,34,0x1f,0x03,0x02);
        /* USER CODE END PV */
}



使用特权

评论回复

相关帖子

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

本版积分规则

144

主题

1326

帖子

11

粉丝