mikeybie 发表于 2024-12-16 18:04:17

<h1>AI8051U学习打卡(七)</h1>
<h1>7. <strong>数码管驱动</strong></h1>
<p><img src="data/attachment/forum/202412/16/180339nj9333u3uvytf0jz.jpg" alt="" /><img src="data/attachment/forum/202412/16/180339aheir0bpg0ijwnid.jpg" alt="" /></p>
<p><strong>“AS&quot;代表单色,而“BS”代表双色。</strong></p>
<p><img src="data/attachment/forum/202412/16/180339ccp99dxaaajhnmup.jpg" alt="" /><img src="data/attachment/forum/202412/16/180339mhqrejhczxco9t37.jpg" alt="" /></p>
<p><strong>因为我只有擎天柱开发板,没有实验箱,所以数码管驱动看不到实际效果,只能玩一下擎天柱开发板的仿真了。</strong></p>
<h2>7.1. <strong>LED仿真</strong></h2>
<p><img src="data/attachment/forum/202412/16/180339v6d0jhbj3mzqz9jb.jpg" alt="" /></p>
<pre><code class="language-c">#include &quot;task.h&quot;
#include &quot;gpio.h&quot;

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);

//任务状态标记函数,放在定时器1ms中断函数里面
void Task_Run_Time(void)
{
    uint8_t i;
    for(i=0;i&lt;Task_Max;i++)//扫描每一个任务列表
    {
       if(My_Task.tim_cnt)//任务执行周期有值
       {
         My_Task.tim_cnt--;
         if(My_Task.tim_cnt == 0)//任务执行周期到了
         {
            My_Task.tim_cnt = My_Task.tim_newcnt;//重新赋值周期
            My_Task.task_state = 1;//标记任务可执行状态
         }
       }
    }
}

//任务回调函数处理
void Task_Callback_Handler(void)
{
   uint8_t i;
   for(i=0;i&lt;Task_Max;i++)
   {
      if(My_Task.task_state)
      {
      My_Task.task_state = 0;
      My_Task.task_callback();
      }      
   }
}
</code></pre>
<pre><code class="language-c">#include &quot;gpio.h&quot;

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 &gt;= 10)
   {
         KEY_press = 0;
         printf(&quot;按键按下\r\n&quot;);
   }
   }
   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&lt;8;i++)
    {
      dat &lt;&lt;= 1;//DAT = (DAT&lt;&lt;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,~Seg_Com);
}

uint8_t LED_pos = 0;
void PLED_40(void)
{
    uint8_t cod;
    cod = 0x0f;//表示开启P0-P3
    cod = Seg_Com;//P0
    cod = Seg_Com;//P1
    cod = Seg_Com;//P2
    cod = Seg_Com;//P3
    LED40_SendData(cod,5);

    P0 = ~Seg_Com;
    P1 = ~Seg_Com;
    P2 = ~Seg_Com;
    P3 = ~Seg_Com;

    if(++LED_pos &gt;= 8)LED_pos =0;
}
</code></pre>
<pre><code class="language-c">#ifndef _LED_H
#define _LED_H

#include &quot;system.h&quot;

#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
</code></pre>
<p><img src="data/attachment/forum/202412/16/180339u1srxsxirxc2kbrn.jpg" alt="" /><img src="data/attachment/forum/202412/16/180340wyl6565fkw8v533b.jpg" alt="" />(也侧面印证了我上面那排led焊反了)</p>
<h2>7.2. <strong>数码管仿真</strong></h2>
<p><img src="data/attachment/forum/202412/16/180340wtge88erp9x4yrgt.jpg" alt="" /></p>
<pre><code class="language-c">#include &quot;gpio.h&quot;

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 &gt;= 10)
   {
         KEY_press = 0;
         printf(&quot;按键按下\r\n&quot;);
   }
   }
   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&lt;8;i++)
    {
      dat &lt;&lt;= 1;//DAT = (DAT&lt;&lt;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,~Seg_Com);
}

uint8_t LED_pos = 0;
void PLED_40(void)
{
    uint8_t cod;
    cod = 0x0f;//表示开启P0-P3
    cod = Seg_Com;//P0
    cod = Seg_Com;//P1
    cod = Seg_Com;//P2
    cod = Seg_Com;//P3
    LED40_SendData(cod,5);

    P0 = ~Seg_Com;
    P1 = ~Seg_Com;
    P2 = ~Seg_Com;
    P3 = ~Seg_Com;

    if(++LED_pos &gt;= 8)LED_pos =0;
}

uint8_t shi = 0;
uint8_t fen = 0;
uint8_t miao =0;

void TIMcnt_Task(void)
{
   miao++;
   if(miao &gt; 59)
   {
       miao = 0;
       fen++;
       if(fen &gt; 59)
       {
         fen = 0;
         shi++;
         if(shi &gt; 23)
         {
               shi = 0;
         }
       }
   }
}

void SEG_PC(void)
{
   uint8_t cod;
   
    cod = Seg_Num;//小时数码管段码
    cod = Seg_Num;
    cod = Seg_Num;

    cod = Seg_Num;
    cod = Seg_Num;
    cod = Seg_Num;

    cod = Seg_Num;
    cod = Seg_Num;

    SEG7_ShowCode(cod);
}
</code></pre>
<p><img src="data/attachment/forum/202412/16/180339ao4251k5m7k858gm.jpg" alt="" /></p>
页: 1 [2]
查看完整版本: AI8051U学习打卡(一)