AI8051U学习打卡(七)
7. 数码管驱动


“AS"代表单色,而“BS”代表双色。


因为我只有擎天柱开发板,没有实验箱,所以数码管驱动看不到实际效果,只能玩一下擎天柱开发板的仿真了。
7.1. LED仿真

#include "task.h"
#include "gpio.h"
Task_Struct My_Task[]=
{
// {0,10,10,KEY_Task},
// {0,300,300,LED0_Blink},
// {0,600,600,LED1_Blink},
// {0,900,900,LED2_Blink},
// {0,1000,1000,Seg_Task},
{0,1000,1000,PLED_40},
};
uint8_t Task_Max = sizeof(My_Task)/sizeof(My_Task[0]);
//任务状态标记函数,放在定时器1ms中断函数里面
void Task_Run_Time(void)
{
uint8_t i;
for(i=0;i<Task_Max;i++)//扫描每一个任务列表
{
if(My_Task[i].tim_cnt)//任务执行周期有值
{
My_Task[i].tim_cnt--;
if(My_Task[i].tim_cnt == 0)//任务执行周期到了
{
My_Task[i].tim_cnt = My_Task[i].tim_newcnt;//重新赋值周期
My_Task[i].task_state = 1;//标记任务可执行状态
}
}
}
}
//任务回调函数处理
void Task_Callback_Handler(void)
{
uint8_t i;
for(i=0;i<Task_Max;i++)
{
if(My_Task[i].task_state)
{
My_Task[i].task_state = 0;
My_Task[i].task_callback();
}
}
}
#include "gpio.h"
uint8_t Seg_Num[]=
{
0x3F, /*'0', 0*/
0x06, /*'1', 1*/
0x5B, /*'2', 2*/
0x4F, /*'3', 3*/
0x66, /*'4', 4*/
0x6D, /*'5', 5*/
0x7D, /*'6', 6*/
0x07, /*'7', 7*/
0x7F, /*'8', 8*/
0x6F, /*'9', 9*/
0x77, /*'A', 10*/
0x7C, /*'B', 11*/
0x39, /*'C', 12*/
0x5E, /*'D', 13*/
0x79, /*'E', 14*/
0x71, /*'F', 15*/
0x40, /*'-', 16*/
0x00, /*' ', 17*/
0x80, /*'.', 18*/
};
uint8_t Seg_Com[]=
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
};
uint8_t led0_state=0;
uint8_t led1_state=0;
uint8_t led2_state=0;
uint8_t KEY_press = 0;//按键扫描消抖变量
void LED0_Blink(void)
{
led0_state ^= 1;
P00 = led0_state;
}
void LED1_Blink(void)
{
led1_state ^= 1;
P01 = led1_state;
}
void LED2_Blink(void)
{
led2_state ^= 1;
P02 = led2_state;
}
void KEY_Task(void)
{
if(P32 == 0)
{
KEY_press++;
if(KEY_press >= 10)
{
KEY_press = 0;
printf("按键按下\r\n");
}
}
else
{
KEY_press = 0;
}
}
void HC595_Init(void)
{
HC595_SER = 0;
HC595_RCK = 0;
HC595_SCK = 0;
}
void SendData_to595(uint8_t dat)
{
uint8_t i;
for(i=0;i<8;i++)
{
dat <<= 1;//DAT = (DAT<<1); CY
HC595_SER = CY;//先把数据写到引脚上
HC595_SCK = 1;//输出上升沿时钟信号
HC595_SCK = 0;
}
}
void Display_Seg(uint8_t com,uint8_t dat)
{
SendData_to595(com);//数码管段码输出,高电平点亮
SendData_to595(dat);//数码管位码输出,低电平点亮
HC595_RCK = 1; //数据输出
HC595_RCK = 0;
}
void Seg_Task(void)
{
Display_Seg(Seg_Num[0],~Seg_Com[0]);
}
uint8_t LED_pos = 0;
void PLED_40(void)
{
uint8_t cod[8];
cod[0] = 0x0f;//表示开启P0-P3
cod[1] = Seg_Com[LED_pos];//P0
cod[2] = Seg_Com[LED_pos];//P1
cod[3] = Seg_Com[LED_pos];//P2
cod[4] = Seg_Com[LED_pos];//P3
LED40_SendData(cod,5);
P0 = ~Seg_Com[LED_pos];
P1 = ~Seg_Com[LED_pos];
P2 = ~Seg_Com[LED_pos];
P3 = ~Seg_Com[LED_pos];
if(++LED_pos >= 8)LED_pos =0;
}
#ifndef _LED_H
#define _LED_H
#include "system.h"
#define HC595_SER P34
#define HC595_RCK P35
#define HC595_SCK P32
void LED0_Blink(void);
void LED1_Blink(void);
void LED2_Blink(void);
void KEY_Task(void);
void HC595_Init(void);
void Seg_Task(void);
void PLED_40(void);
#endif

(也侧面印证了我上面那排led焊反了)
7.2. 数码管仿真

#include "gpio.h"
uint8_t Seg_Num[]=
{
0x3F, /*'0', 0*/
0x06, /*'1', 1*/
0x5B, /*'2', 2*/
0x4F, /*'3', 3*/
0x66, /*'4', 4*/
0x6D, /*'5', 5*/
0x7D, /*'6', 6*/
0x07, /*'7', 7*/
0x7F, /*'8', 8*/
0x6F, /*'9', 9*/
0x77, /*'A', 10*/
0x7C, /*'B', 11*/
0x39, /*'C', 12*/
0x5E, /*'D', 13*/
0x79, /*'E', 14*/
0x71, /*'F', 15*/
0x40, /*'-', 16*/
0x00, /*' ', 17*/
0x80, /*'.', 18*/
};
uint8_t Seg_Com[]=
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
};
uint8_t led0_state=0;
uint8_t led1_state=0;
uint8_t led2_state=0;
uint8_t KEY_press = 0;//按键扫描消抖变量
void LED0_Blink(void)
{
led0_state ^= 1;
P00 = led0_state;
}
void LED1_Blink(void)
{
led1_state ^= 1;
P01 = led1_state;
}
void LED2_Blink(void)
{
led2_state ^= 1;
P02 = led2_state;
}
void KEY_Task(void)
{
if(P32 == 0)
{
KEY_press++;
if(KEY_press >= 10)
{
KEY_press = 0;
printf("按键按下\r\n");
}
}
else
{
KEY_press = 0;
}
}
void HC595_Init(void)
{
HC595_SER = 0;
HC595_RCK = 0;
HC595_SCK = 0;
}
void SendData_to595(uint8_t dat)
{
uint8_t i;
for(i=0;i<8;i++)
{
dat <<= 1;//DAT = (DAT<<1); CY
HC595_SER = CY;//先把数据写到引脚上
HC595_SCK = 1;//输出上升沿时钟信号
HC595_SCK = 0;
}
}
void Display_Seg(uint8_t com,uint8_t dat)
{
SendData_to595(com);//数码管段码输出,高电平点亮
SendData_to595(dat);//数码管位码输出,低电平点亮
HC595_RCK = 1; //数据输出
HC595_RCK = 0;
}
void Seg_Task(void)
{
Display_Seg(Seg_Num[0],~Seg_Com[0]);
}
uint8_t LED_pos = 0;
void PLED_40(void)
{
uint8_t cod[8];
cod[0] = 0x0f;//表示开启P0-P3
cod[1] = Seg_Com[LED_pos];//P0
cod[2] = Seg_Com[LED_pos];//P1
cod[3] = Seg_Com[LED_pos];//P2
cod[4] = Seg_Com[LED_pos];//P3
LED40_SendData(cod,5);
P0 = ~Seg_Com[LED_pos];
P1 = ~Seg_Com[LED_pos];
P2 = ~Seg_Com[LED_pos];
P3 = ~Seg_Com[LED_pos];
if(++LED_pos >= 8)LED_pos =0;
}
uint8_t shi = 0;
uint8_t fen = 0;
uint8_t miao =0;
void TIMcnt_Task(void)
{
miao++;
if(miao > 59)
{
miao = 0;
fen++;
if(fen > 59)
{
fen = 0;
shi++;
if(shi > 23)
{
shi = 0;
}
}
}
}
void SEG_PC(void)
{
uint8_t cod[8];
cod[0] = Seg_Num[shi/10];//小时数码管段码
cod[1] = Seg_Num[shi%10];
cod[2] = Seg_Num[16];
cod[3] = Seg_Num[fen/10];
cod[4] = Seg_Num[fen%10];
cod[5] = Seg_Num[16];
cod[6] = Seg_Num[miao/10];
cod[7] = Seg_Num[miao%10];
SEG7_ShowCode(cod);
}
