该驱动可实现任意位开关显示、任意位闪烁、任意位小数点开关显示。稍微修改代码可以扩展更多位数码管。
#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 */
}
|