飞行者 发表于 2025-7-8 11:04:16

06.IO输入输出


#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#include "math.h"
#include "stdio.h"


#define u8 unsigned char        //8位无符号变量(0-255)
        unsigned char LED_Count = 0;
       
u8 state = 0;                                //初始状态


void Delay20ms(void)        //@24.000MHz        Delay20ms( );
{
        unsigned long edata i;

        _nop_();
        _nop_();
        i = 119998UL;
        while (i) i--;
}

void main()
{
        WTST = 0;                                 //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                //扩展寄存器(XFR)访问使能
    CKCON = 0;                                //提高访问XRAM速度

   
   
    P0M1 = 0x00;   P0M0 = 0x00;
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;
   
    usb_init();                                     //USB CDC 接口配置
   
    EA = 1;

    while (1)
    {
      if (bUsbOutReady)
      {
//          USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
//                  printf_usb("1. Read Num:%d\n", OutNumber);
//                  printf_usb("2. Read Num:%d\n", OutNumber);
//                  printf_usb("3. Read Num:%d\n", OutNumber);
//                  printf_usb("4. Read Num:%d\n", OutNumber);
            
            usb_OUT_done();
      }
//                //任务1:按下P32按钮灯亮,松开P32按钮灯灭。
//                if(P32 == 0)                                        //判断按钮是否按下
//                {
//                        P20 = 0;
//                }
//                else
//                {
//                        P20 = 1;
//                }
               
//                //任务2:按下P32按钮灯灭,松开P32按钮灯亮。
//                if(P32 == 1)                                        //判断按钮是否按下
//                {
//                        P20 = 0;
//                }
//                else
//                {
//                        P20 = 1;
//                }       
//                //任务:按下P32按钮灯亮,按下P32按钮灯灭。
//                if(P32 == 0)                                        //判断按钮是否按下
//                {
//                        Delay20ms( );                                //延时20毫秒消抖
//                        if(P32 == 0)
//                        {
//                        state = !state;                                //变量取反
//                        P20 = state;
//                        printf("state %d\r\n", (int)state);
//                        while(P32 ==0 );
//                        }
//                }

//        //课后任务1:按一下P32按钮灯亮,按一下P33按钮灯灭。(按一下左边四个灯亮,右边四个灯灭,再按一下左边四个灯灭,右边四个灯亮。)
//                if(P32 == 0)                                        //判断按钮是否按下
//                {
//                        Delay20ms( );                                //延时20毫秒消抖
//                        if(P32 == 0)
//                        {
//                       
//                        P20 = 0;
//                        P21 = 0;
//                        P22 = 0;
//                        P23 = 0;
//                        P24 = 1;
//                        P25 = 1;
//                        P26 = 1;
//                        P27 = 1;
//                       
//                        while(P32 ==0 );
//                        }
//                }
//                if(P33 == 0)                                        //判断按钮是否按下
//                {
//                        Delay20ms( );                                //延时20毫秒消抖
//                        if(P33 == 0)
//                        {
//                       
//                        P20 = 1;
//                        P21 = 1;
//                        P22 = 1;
//                        P23 = 1;
//                        P24 = 0;
//                        P25 = 0;
//                        P26 = 0;
//                        P27 = 0;
//                       
//                        while(P33 ==0 );
//                        }
//                }
                        //课后任务2:按一下亮一颗灯,再按一下亮两颗灯,直到全亮(变量+加法和乘法)
                if(P32 == 0)                                        //判断按钮是否按下
                {
                        Delay20ms( );                                //延时20毫秒消抖
                       
                        if(P32 == 0)
                        {
                                //更新LED计数
                                LED_Count++;
                                if(LED_Count > 8)// 如果超过8个LED,则重置为1
                                {
                                        LED_Count = 1;
                                }
                               
                                //根据计数点亮相应数量的LED
                               
                                P2 = 0xFF << LED_Count;// 左移操作,点亮低LED_Count位
                                while(P32 ==0 );
                        }
                }
        }

}833

飞行者 发表于 2025-7-10 07:11:33

07 定时器中断

#include "ai8051u.h"                        //调用头文件
#include "stc32_stc8_usb.h"                //调用头文件
#include "intrins.h"                        //d调用头文件

#define u8unsigned char                //8位无符号变量(0-255)       
u8 state = 0;                                        //初始状态
u8 Run_State = 0;                                //运行状态


char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

void Delay20ms(void)        //@24.000MHzDelay20ms();
{
        unsigned long edata i;

        _nop_();
        _nop_();
        i = 119998UL;
        while (i) i--;
}

void Timer0_Init(void);                //3秒@24.000MHz 函数声明
       
void main(void)
{
        int count=1;                                                                        //按键计数变量
    WTST = 0;                                                                                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                 //提高访问XRAM速度
       
    P0M1 = 0x00;   P0M0 = 0x00;
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;
       
        usb_init();                                     //USB CDC 接口配置
       
//        Timer0_Init( );
    IE2 |= 0x80;                                    //使能USB中断
    EA = 1;                                                                                        //IE |= 0X80;
       
       
        while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
       
        while(1)
        {
               
      if (bUsbOutReady)                                                        //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();                                                        //
      }
               

               
                //任务1:LED灯三秒取反一次,这期间任意时刻按下按钮,串口打印按键次数。
//                if( P32 == 0 )                                                                //判断P32按钮是否按下
//                {
//                        Delay20ms();                                                        //延时20ms消抖
//                        if( P32 == 0 )
//                        {
//                                printf("按键按下次数\xfd:%d 次\r\n",(int)count);
//                                count++;
//                               
//                                while( P32 == 0 );                                        //等待P32松开
//                               
//                        }
//                }
               
                //任务2:灯按一下点亮三秒后熄灭。(延时关闭车灯)
//                if( P32 == 0 )                                                                //判断P32按钮是否按下
//                {
//                        Delay20ms();                                                        //延时20ms消抖
//                        if( P32 == 0 )
//                        {
//                               
//                                P23 = 0;                                                        //亮灯
//                                Timer0_Init( );                                                //调用定时函数
//                                while( P32 == 0 );                                        //等待P32松开
//                               
//                        }
//                }

                //任务3:救护车等控制器,按下报警按钮,红蓝交替闪烁(LED1和LED2表示红灯和蓝灯),再按一下报警按钮,红蓝灯停止。
                if( P32 == 0 )                                                                //判断P32按钮是否按下
                {
                        Delay20ms();                                                        //延时20ms消抖
                        if( P32 == 0 )
                        {
                                Run_State = !Run_State;                                //运行状态取反
                                                       
                                if(Run_State == 1)
                                {
                                        Timer0_Init();                                       
                                }
                                else
                                {
                                        TR0 = 0;                                                //关闭定时器
                                        P22 = 1;
                                        P23 = 1;
                                }
                               
                                while( P32 == 0 );                                        //等待P32松开
                               
                        }
                }
        }
}

//void Timer0_Init(void)                //3秒@24.000MHz
//{
//        TM0PS = 0x5B;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
//        AUXR &= 0x7F;                        //定时器时钟12T模式
//        TMOD &= 0xF0;                        //设置定时器模式
//        TL0 = 0x3F;                                //设置定时初始值
//        TH0 = 0x01;                                //设置定时初始值
//        TF0 = 0;                                //清除TF0标志
//        TR0 = 1;                                //定时器0开始计时
//        ET0 = 1;                                //使能定时器0中断
//}
void Timer0_Init(void)                //500毫秒@24.000MHz
{
        TM0PS = 0x0F;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0xDC;                                //设置定时初始值
        TH0 = 0x0B;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}

void Timer0_Isr(void) interrupt 1
{
        state = !state;                                       
        P22 = state;                               
        P23 = !state;                               
}835

飞行者 发表于 2025-7-12 11:32:23

07.定时器中断课后小练”电子功德箱“


// 课后小练:电子功德箱功能实现
/*
功能说明:
1. 按下按钮1(P32),串口切换显示"双倍功德时间"或"单倍功德时间"
2. 按下按钮2(P33),根据当前模式增加功德值:
   - 双倍模式:显示"功德+2 当前功德:xxx",LED点亮2秒
   - 单倍模式:显示"功德+1 当前功德:xxx",LED点亮1秒
3. LED通过P21引脚控制,点亮后定时熄灭
*/

// 按钮1(P32)检测与模式切换
if (P32 == 0) {                  // 检测按钮1是否按下(低电平有效)
    delay_ms(20);                // 延时20ms消抖,避免按键抖动误触发
    if (P32 == 0) {            // 二次检测,确认按钮按下
      state = !state;          // 切换模式标志位(0=单倍,1=双倍)
      if (state) {             // 双倍模式
            printf("双倍功德时间\r\n");
      } else {               // 单倍模式
            printf("单倍功德时间\r\n");
      }
      while (P32 == 0);       // 等待按钮释放,防止重复触发
    }
}

// 按钮2(P33)检测与功德值增加
if (P33 == 0) {                  // 检测按钮2是否按下
    delay_ms(20);                // 20ms消抖
    if (P33 == 0) {            // 二次确认按下
      if (state) {             // 双倍功德模式
            y = y + 2;         // 功德值+2
            P21 = 0;             // 点亮P21引脚LED(低电平有效,共阴极连接)
            printf("功德+2 当前功德 %u \r\n", y);// 串口输出功德值
            Timer0_Init_2();   // 初始化2秒定时器,用于LED熄灭控制
      } else {               // 单倍功德模式
            y++;               // 功德值+1
            printf("功德+1 当前功德 %u \r\n", y);
            P21 = 0;             // 点亮LED
            Timer0_Init_1();   // 初始化1秒定时器
      }
      while (P33 == 0);       // 等待按钮释放
    }
}

i++;                            // 计数器自增
if (i % 64 == 0) {            // 每64次循环(约320ms)
    P20 = !P20;               // 翻转P20引脚电平(可能用于调试或额外指示)
}
delay_ms(5);                  // 5ms延时,控制主循环频率


// 毫秒延时函数(依赖系统时钟MAIN_Fosc)
void delay_ms(u8 ms) {
    u16 i;
    do {
      i = MAIN_Fosc / 6000;    // 根据系统时钟计算延时参数(24MHz时i=4000)
      while (--i);             // 空循环延时
    } while (--ms);            // 循环ms次
}


// 定时器0初始化函数(1秒定时)
void Timer0_Init_1(void) {
    TM0PS = 0x1E;                // 定时器时钟预分频(24MHz/(0x1E+1)=24MHz/31≈774kHz)
    AUXR &= 0x7F;                // 定时器时钟12T模式(1个机器周期=12个时钟周期)
    TMOD &= 0xF0;                // 保留定时器0模式位(低4位不变)
    TL0 = 0xFC;                  // 定时初值低8位(配合TH0实现1ms定时)
    TH0 = 0x03;                  // 定时初值高8位
    TF0 = 0;                     // 清除定时器0溢出标志
    TR0 = 1;                     // 启动定时器0
    ET0 = 1;                     // 使能定时器0中断
}


// 定时器0初始化函数(2秒定时)
void Timer0_Init_2(void) {
    TM0PS = 0x3D;                // 预分频值更大(24MHz/(0x3D+1)=24MHz/62≈387kHz)
    AUXR &= 0x7F;                // 12T模式
    TMOD &= 0xF0;                // 定时器0模式
    TL0 = 0xFC;                  // 初值与1秒模式相同(通过预分频实现更长定时)
    TH0 = 0x03;                  
    TF0 = 0;
    TR0 = 1;
    ET0 = 1;
}


// 定时器0中断服务函数
void Timer0_Isr(void) interrupt 1 {
    P21 = 1;                     // 熄灭LED(高电平,共阴极连接)
    TR0 = 0;                     // 停止定时器0
}
836837

飞行者 发表于 2025-7-12 11:44:47

08.定时器周期性调度任务


#include "config.h"
#include "task.h"
#include "io.h"

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

void Delay10ms(void)        //@24.000MHz
{
        unsigned long edata i;

        _nop_();
        _nop_();
        i = 119998UL;
        while (i) i--;
}       
void main(void)
{
        int count=1;                                                                        //按键计数变量
   
        Sys_init();                                                                                //系统初始化(调用函数)
        usb_init();                                     //USB CDC 接口配置
       
        IE2 |= 0x80;                                    //使能USB中断
        Timer0_Init();                                                                        //定时器初始化
    EA = 1;                                                                                        //IE |= 0X80;
       
       
        while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
       
        while(1)
        {
               
      if (bUsbOutReady)                                                        //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
               
            usb_OUT_done();                                                        //
      }
                Task_Pro_Handler_Callback();                                //执行函数               
       }
}
void Timer0_Isr(void) interrupt 1
{
       
        Task_Marks_Handler_Callback();                        //系统计时;
}
838839

飞行者 发表于 2025-7-21 08:45:26

09.数码管


io.c代码
#include "io.h"

u8 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*/
};

u8 T_NUM =
{
      0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
};

//u8 State1 = 0;                                        //LED1初始状态
//u8 State2 = 0;                                        //LED2初始状态
//u8 State3 = 0;                                        //LED3初始状态

//u16 Key_Vol = 0;                              //按键按下持续时间(几个十秒)

//void LED0_Blink(void)
//{
//      State1 = !State1;
//      P20 = State1;
//}
//void LED1_Blink(void)
//{
//      State2 = !State2;
//      P21 = State2;
//}
//void LED2_Blink(void)
//{
//      State3 = !State3;
//      P22 = State3;
//}
//void Key_Task(void)
//{
//                if( P32 == 0 )
//                {
//                        Key_Vol++;
//                        if(Key_Vol == 5)
//                        {
//                              printf("按键单击\r\n");
//                        }      
//                }
//                else
//                {
//                        Key_Vol = 0;      
//                }
//}
//------------------------------------595函数定义-------------------------------------------------
void Init_595(void)
{
      HC595_SER= 0;
      HC595_RCK= 0;
      HC595_SCK= 0;
}

void Send_595( u8 dat )
{
      u8 i;
      for( i=0; i<8; i++ )
      {
                dat <<= 1;                        //数值左移一位
                HC595_SER= CY;      //数据写到引脚
            HC595_RCK= 1;                //输出上升沿的时钟信号
      HC595_SCK= 0;
      }
}

void Display_Seg( u8 HC595_1,u8 HC595_2)
{
      Send_595(HC595_1);                //数码管段码输出      高电平点亮
      Send_595(HC595_2);                //数码管位码输出      低电平点亮
      HC595_RCK= 1;                        //数据输出
      HC595_RCK= 0;
}

u8 Seg_no = 0;
u8 shi = 0;
u8 fen = 0;
u8 miao = 0;

void Seg_Task(void)
{
      u8 num = 0;
      if( Seg_no == 0 )                                                      //数码管小时十位
      {
                num = shi/10;
                Display_Seg( SEG_NUM, ~T_NUM);      //数码管段码和位码
      }
      else if(Seg_no == 1)                                                //小时的个位
      {
                num = shi%10;
                Display_Seg( SEG_NUM, ~T_NUM);      //数码管段码和位码
      }
      else if(Seg_no == 2)                                                //第一个横杠
      {
               
                Display_Seg( SEG_NUM,~T_NUM);      //数码管段码和位码
      }
      if( Seg_no == 3 )                                                      //数码管分十位
      {
                num = fen/10;
                Display_Seg( SEG_NUM, ~T_NUM);      //数码管段码和位码
      }
      else if(Seg_no == 4)                                                //分钟个位
      {
                num = fen%10;
                Display_Seg( SEG_NUM, ~T_NUM);      //数码管段码和位码
      }
      else if(Seg_no == 5)                                                //第二个横杠
      {
               
                Display_Seg( SEG_NUM,~T_NUM);      //数码管段码和位码
      }
      if( Seg_no == 6)                                                      //数码管秒十位
      {
                num = fen/10;
                Display_Seg( SEG_NUM, ~T_NUM);      //数码管段码和位码
      }
      else if(Seg_no == 7)                                                //秒的个位
      {
                num = fen%10;
                Display_Seg( SEG_NUM, ~T_NUM);      //数码管段码和位码
      }
      else                                                
      {
      }
      Seg_no ++;
      if( Seg_no>7 )
                Seg_no=0;
}

void TIMECOUNT_Task(void)
{
      miao ++;
      if( miao>60 )
      {
                miao = 0;
                fen ++;
                if(fen >60)
                {
                        fen = 0;
                        shi ++;
                        if( shi>24 )
                              shi = 0;
                }
      }
}

u8 state_now = 0;

void PLED_40(void)
{
      u8 cod;
      cod = 0x0f;                //表示开启P0-P3
      cod = 0x01;                //P0端口
      cod = 0x01;                //P1
      cod = ~T_NUM;                //P2
      cod = 0x01;                //P3
      LED40_SendData( cod, 5 );
      
      P2 = ~T_NUM;
      state_now++;
      if(state_now > 7)
                state_now = 0;
      
}

void SEG_PC(void)
{
                u8 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);      
}io.h代码
#ifndef __IO_H
#define __IO_H

#include "config.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);

//--------------------------------------------------74HC595控制函数声明-----------------------------------------------------
void Init_595(void);
void Send_595( u8 dat );
void Display_Seg( u8 HC595_1,u8 HC595_2);
void Seg_Task(void);
void TIMECOUNT_Task(void);
void PLED_40(void);
void SEG_PC(void);

#endiftask.c
#include "task.h"
#include "io.h"

//========================================================================
//                               本地变量声明
//========================================================================

static TASK_COMPONENTS Task_Comps[]=
{
//状态计数周期函数

//      {0, 300,   300,   LED0_Blink},   /* task 1 Period: 300ms */
//      {0, 600,   600,   LED1_Blink},      /* task 1 Period: 600ms */
//      {0, 900,   900,   LED2_Blink},      /* task 1 Period: 900ms */
//      {0, 10,   10,   Key_Task},      /* task 1 Period: 50ms */
      {0, 1,   1,       Seg_Task},      /* task 1 Period: 1ms */
      {0, 1000,   1000,   TIMECOUNT_Task},      /* task 1 Period: 1000ms */
      {0, 1000,   1000,    PLED_40},      /* task 1 Period: 500ms */
      {0, 1000,   1000,   SEG_PC},      /* task 1 Period: 1000ms */
      
};

u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);

//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.TIMCount)      /* If the time is not 0 */
      {
            Task_Comps.TIMCount--;   /* Time counter decrement */
            if(Task_Comps.TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps.TIMCount = Task_Comps.TRITime;
                Task_Comps.Run = 1;      /* The task can be run */
            }
      }
    }
}

//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.Run) /* If task can be run */
      {
            Task_Comps.Run = 0;      /* Flag clear 0 */
            Task_Comps.TaskHook();   /* Run task */
      }
    }
}

851

飞行者 发表于 2025-7-29 00:05:21

09数码管课后小练 简易10秒免单计数器 感谢国芯公司,已收到AI8051u试验箱。
此代码借鉴了坛友silas***的代码:

io.c
#include "io.h"
#include "task.h"
u8 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*/

};

u8 T_NUM =
{
        0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
};



u16 Key_Vol = 0;                                //按键按下持续时间(几个十秒)


//------------------------------------595函数定义-------------------------------------------------
void Init_595(void)
{
        HC595_SER= 0;
        HC595_RCK= 0;
        HC595_SCK= 0;
}

void Send_595( u8 dat )
{
        u8 i;
        for( i=0; i<8; i++ )
        {
                dat <<= 1;                        //数值左移一位
                HC595_SER= CY;        //数据写到引脚
          HC595_SCK= 1;                //输出上升沿的时钟信号
      HC595_SCK= 0;
        }
}

void Display_Seg( u8 HC595_1,u8 HC595_2)
{
        Send_595(HC595_1);                //数码管段码输出        高电平点亮
        Send_595(HC595_2);                //数码管位码输出        低电平点亮
       
        HC595_RCK= 1;                        //数据输出
        HC595_RCK= 0;
}

u8 Seg_no = 0;
u8 Seg_no_1 = 0;
u8 shi = 0;
u8 fen = 0;
u8 miao = 0;
u8 ms_10 =0;
u8 Run = 0;
//u8 Key_Vol =0;
bit win = 0;
bit key_Start =1;       
u8 Key_Tabe =0;


//计时函数
void TIMECOUNT_Task(void)
{
        if(key_Start==0)
        {
                ms_10 ++;
                if( ms_10>100 )
                {
                        ms_10 = 0;
                        miao++;
                        if(miao>15)
                        {
                                miao = 0;
                        }
                }
        }       
}
/**
* 10秒抢答模式显示函数
* 功能:特殊显示模式,固定前缀"10:00.",后4位显示当前秒和毫秒
* 用途:用于抢答场景,直观展示10秒倒计时窗口
*/
/**
* 10秒抢答模式显示函数(仅用if-else实现)
* 功能:特殊显示模式,固定前缀"10:00.",后4位显示当前秒和毫秒
*/
void Seg_Task_1(void)
{
        switch(Seg_no){
                case 0: Display_Seg( SEG_NUM, ~T_NUM );   break;//小时十位
                case 1: Display_Seg( SEG_NUM|SEG_NUM, ~T_NUM );   break;
                case 2: Display_Seg( SEG_NUM, ~T_NUM );   break;
                case 3: Display_Seg( SEG_NUM, ~T_NUM );   break;
                case 4: Display_Seg( SEG_NUM, ~T_NUM );   break;
                case 5: Display_Seg( SEG_NUM|SEG_NUM, ~T_NUM );   break;
                case 6: Display_Seg( SEG_NUM, ~T_NUM );   break;
                case 7: Display_Seg( SEG_NUM, ~T_NUM );   break;
        }
       
        Seg_no++;
        if(Seg_no>7){
        Seg_no=0;
        }

}


u8 state_now = 0;


//u8 Seg_no=0;



/*课后小练:简易10秒免单计数器.
1.在前四位数码管上显示目标时间,即“ 10. 00 ”表示定时时间10秒钟
2.后四位显示当前的计时00.00,最小单位为10msBuild started: Project: demo

3.按下开始按钮后,每10ms最末尾的数字+1;直到按下结束按钮后停止计数。
*/
//按键处理任务

void KEY_Task(void)
{
        if( P34 == 0)                        //检测到P34按键按下
        {
                Key_Vol++;                        //消抖计数累加
                if( Key_Vol == 5)        //连续检测到5次低电平(消抖完成)
                {
                        if(key_Start ==1)        // 当前是暂停状态,则切换到运行
                        {
                                key_Start = 0;
                        }               
                        else if(key_Start == 0)        //// 当前是运行状态,则切换到暂停
                        {
                                key_Start = 1;
                                // 判断是否在9.5-10.5秒之间按下,满足则判定为胜利
                if((miao == 10 && ms_10 > 50) || (miao == 9 && ms_10 > 50))
                                {
                                        win = 1;
                                       
                                }
                        }
                }
        }
        else if(P33 == 0)        // 检测到P33按键按下(复位键)       
        {
                Key_Vol++;
      if(Key_Vol == 5)       // 消抖完成
                {
                key_Start = 1;       // 暂停计时
      ms_10 = 0;      // 重置毫秒
      miao = 0;         // 重置秒
      win = 0;            // 清除胜利标志
                P0 = 0xFF;          // 关闭P0口控制的LED
                }

        }
        else
        {
                Key_Vol = 0;
        }
}
/**
* 胜利效果展示函数
* 功能:当win=1时,P0口8个LED依次点亮(流水灯效果)
*/
u8 led_eff=0;
void win_effect(void)
{
    if(win == 1)               // 胜利状态
    {
      P0 =~T_NUM;   // 点亮当前LED(低电平有效,取反后对应位为0)
      led_eff++;            // 切换到下一个LED
      if(led_eff > 7)
      {
                       
            led_eff = 0;      // 循环显示
      }
    }
}

void PLED_40(void)
{
        u8 cod;
        cod = 0x0f;                //表示开启P0-P3
        cod = 0x01;                //P0端口
        cod = 0x01;                //P1
        cod = ~T_NUM;                //P2
        cod = 0x01;                //P3
        LED40_SendData( cod, 5 );
       
        P2 = ~T_NUM;
        state_now++;
        if(state_now > 7)
                state_now = 0;
       
}

void SEG_PC(void)
{
                u8 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);       
}
io.h
#ifndef __IO_H
#define __IO_H

#include "config.h"        //调用头文件

//定义引脚名称
#define HC595_SER         P34
#define HC595_RCK         P35
#define HC595_SCK         P32



void Key_Task(void);

//--------------------------------------------------74HC595控制函数声明-----------------------------------------------------
void Init_595(void);
void Send_595( u8 dat );
void Display_Seg( u8 HC595_1,u8 HC595_2);
//void Seg_Task(void);
void TIMECOUNT_Task(void);
void PLED_40(void);
void SEG_PC(void);
void KEY_Task(void);

void Seg_Task_1(void);
void win_effect(void);

#endiftask.c
#include "task.h"
#include "io.h"

//========================================================================
//                               本地变量声明
//========================================================================

static TASK_COMPONENTS Task_Comps[]=
{
//状态计数周期函数


//        {0, 10,   10,   Key_Task},      /* task 1 Period: 50ms */
//        {0, 1,   1,       Seg_Task},      /* task 1 Period: 1ms */
        {0, 10,   10,   TIMECOUNT_Task},      /* task 1 Period: 1000ms */
//        {0, 1000,   1000,    PLED_40},      /* task 1 Period: 500ms */
//        {0, 1,   1,   SEG_PC},      /* task 1 Period: 1ms */
        {0, 10,   10,   KEY_Task},      /* task 1 Period: 1000ms */
        {0, 1,      1,   Seg_Task_1},      /* task 1 Period: 1ms */
        {0, 500,    200,   win_effect},      /* task 1 Period: 1ms */
       
};

u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);

//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.TIMCount)      /* If the time is not 0 */
      {
            Task_Comps.TIMCount--;   /* Time counter decrement */
            if(Task_Comps.TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps.TIMCount = Task_Comps.TRITime;
                Task_Comps.Run = 1;      /* The task can be run */
            }
      }
    }
}

//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.Run) /* If task can be run */
      {
            Task_Comps.Run = 0;      /* Flag clear 0 */
            Task_Comps.TaskHook();   /* Run task */
      }
    }
}

main.c
#include "config.h"
#include "task.h"
#include "io.h"



char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";


//void Delay10ms(void)        //@24.000MHz
//{
//        unsigned long edata i;

//        _nop_();
//        _nop_();
//        i = 119998UL;
//        while (i) i--;
//}       
void main(void)
{
        //int count=1;                                                                        //按键计数变量
   
        Sys_init();                                                                                //系统初始化(调用函数)
        usb_init();                                     //USB CDC 接口配置
       
        IE2 |= 0x80;                                    //使能USB中断
        Timer0_Init();                                                                        //定时器初始化
        Init_595();                                                                        //595端口电平初始化
    EA = 1;                                                                                        //IE |= 0X80;
       
        P40=0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
       
        while(1)
        {
               
      if (bUsbOutReady)                                                        //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
               
            usb_OUT_done();                                                        //
      }
                Task_Pro_Handler_Callback();                                //执行函数


               
       }
}
void Timer0_Isr(void) interrupt 1
{
       
        Task_Marks_Handler_Callback();                        //系统计时

}
880






飞行者 发表于 2025-7-29 07:33:12

09数码管课后小练 10s免单计数器 感谢国芯公司,已收到AI8051u试验箱 代码参考了坛友silas3082的代码

飞行者 发表于 2025-7-29 07:33:13

09数码管课后小练 10s免单计数器 感谢国芯公司,已收到AI8051u试验箱 代码参考了坛友silas3082的代码

io.c
#include "io.h"
#include "task.h"
u8 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*/

};

u8 T_NUM =
{
        0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
};



u16 Key_Vol = 0;                                //按键按下持续时间(几个十秒)


//------------------------------------595函数定义-------------------------------------------------
void Init_595(void)
{
        HC595_SER= 0;
        HC595_RCK= 0;
        HC595_SCK= 0;
}

void Send_595( u8 dat )
{
        u8 i;
        for( i=0; i<8; i++ )
        {
                dat <<= 1;                        //数值左移一位
                HC595_SER= CY;        //数据写到引脚
          HC595_SCK= 1;                //输出上升沿的时钟信号
      HC595_SCK= 0;
        }
}

void Display_Seg( u8 HC595_1,u8 HC595_2)
{
        Send_595(HC595_1);                //数码管段码输出        高电平点亮
        Send_595(HC595_2);                //数码管位码输出        低电平点亮
       
        HC595_RCK= 1;                        //数据输出
        HC595_RCK= 0;
}

u8 Seg_no = 0;
u8 Seg_no_1 = 0;
u8 shi = 0;
u8 fen = 0;
u8 miao = 0;
u8 ms_10 =0;
u8 Run = 0;
//u8 Key_Vol =0;
bit win = 0;
bit key_Start =1;       
u8 Key_Tabe =0;


//计时函数
void TIMECOUNT_Task(void)
{
        if(key_Start==0)
        {
                ms_10 ++;
                if( ms_10>100 )
                {
                        ms_10 = 0;
                        miao++;
                        if(miao>15)
                        {
                                miao = 0;
                        }
                }
        }       
}
/**
* 10秒抢答模式显示函数
* 功能:特殊显示模式,固定前缀"10:00.",后4位显示当前秒和毫秒
* 用途:用于抢答场景,直观展示10秒倒计时窗口
*/
/**
* 10秒抢答模式显示函数(仅用if-else实现)
* 功能:特殊显示模式,固定前缀"10:00.",后4位显示当前秒和毫秒
*/
void Seg_Task_1(void)
{
        switch(Seg_no){
                case 0: Display_Seg( SEG_NUM, ~T_NUM );   break;//小时十位
                case 1: Display_Seg( SEG_NUM|SEG_NUM, ~T_NUM );   break;
                case 2: Display_Seg( SEG_NUM, ~T_NUM );   break;
                case 3: Display_Seg( SEG_NUM, ~T_NUM );   break;
                case 4: Display_Seg( SEG_NUM, ~T_NUM );   break;
                case 5: Display_Seg( SEG_NUM|SEG_NUM, ~T_NUM );   break;
                case 6: Display_Seg( SEG_NUM, ~T_NUM );   break;
                case 7: Display_Seg( SEG_NUM, ~T_NUM );   break;
        }
       
        Seg_no++;
        if(Seg_no>7){
        Seg_no=0;
        }

}


u8 state_now = 0;


//u8 Seg_no=0;



/*课后小练:简易10秒免单计数器.
1.在前四位数码管上显示目标时间,即“ 10. 00 ”表示定时时间10秒钟
2.后四位显示当前的计时00.00,最小单位为10msBuild started: Project: demo

3.按下开始按钮后,每10ms最末尾的数字+1;直到按下结束按钮后停止计数。
*/
//按键处理任务

void KEY_Task(void)
{
        if( P34 == 0)                        //检测到P34按键按下
        {
                Key_Vol++;                        //消抖计数累加
                if( Key_Vol == 5)        //连续检测到5次低电平(消抖完成)
                {
                        if(key_Start ==1)        // 当前是暂停状态,则切换到运行
                        {
                                key_Start = 0;
                        }               
                        else if(key_Start == 0)        //// 当前是运行状态,则切换到暂停
                        {
                                key_Start = 1;
                                // 判断是否在9.5-10.5秒之间按下,满足则判定为胜利
                if((miao == 10 && ms_10 > 50) || (miao == 9 && ms_10 > 50))
                                {
                                        win = 1;
                                       
                                }
                        }
                }
        }
        else if(P33 == 0)        // 检测到P33按键按下(复位键)       
        {
                Key_Vol++;
      if(Key_Vol == 5)       // 消抖完成
                {
                key_Start = 1;       // 暂停计时
      ms_10 = 0;      // 重置毫秒
      miao = 0;         // 重置秒
      win = 0;            // 清除胜利标志
                P0 = 0xFF;          // 关闭P0口控制的LED
                }

        }
        else
        {
                Key_Vol = 0;
        }
}
/**
* 胜利效果展示函数
* 功能:当win=1时,P0口8个LED依次点亮(流水灯效果)
*/
u8 led_eff=0;
void win_effect(void)
{
    if(win == 1)               // 胜利状态
    {
      P0 =~T_NUM;   // 点亮当前LED(低电平有效,取反后对应位为0)
      led_eff++;            // 切换到下一个LED
      if(led_eff > 7)
      {
                       
            led_eff = 0;      // 循环显示
      }
    }
}

void PLED_40(void)
{
        u8 cod;
        cod = 0x0f;                //表示开启P0-P3
        cod = 0x01;                //P0端口
        cod = 0x01;                //P1
        cod = ~T_NUM;                //P2
        cod = 0x01;                //P3
        LED40_SendData( cod, 5 );
       
        P2 = ~T_NUM;
        state_now++;
        if(state_now > 7)
                state_now = 0;
       
}

void SEG_PC(void)
{
                u8 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);       
}
io.h
#ifndef __IO_H
#define __IO_H

#include "config.h"        //调用头文件

//定义引脚名称
#define HC595_SER         P34
#define HC595_RCK         P35
#define HC595_SCK         P32



void Key_Task(void);

//--------------------------------------------------74HC595控制函数声明-----------------------------------------------------
void Init_595(void);
void Send_595( u8 dat );
void Display_Seg( u8 HC595_1,u8 HC595_2);
//void Seg_Task(void);
void TIMECOUNT_Task(void);
void PLED_40(void);
void SEG_PC(void);
void KEY_Task(void);

void Seg_Task_1(void);
void win_effect(void);

#endiftaskl.c
#include "task.h"
#include "io.h"

//========================================================================
//                               本地变量声明
//========================================================================

static TASK_COMPONENTS Task_Comps[]=
{
//状态计数周期函数


//        {0, 10,   10,   Key_Task},      /* task 1 Period: 50ms */
//        {0, 1,   1,       Seg_Task},      /* task 1 Period: 1ms */
        {0, 10,   10,   TIMECOUNT_Task},      /* task 1 Period: 1000ms */
//        {0, 1000,   1000,    PLED_40},      /* task 1 Period: 500ms */
//        {0, 1,   1,   SEG_PC},      /* task 1 Period: 1ms */
        {0, 10,   10,   KEY_Task},      /* task 1 Period: 1000ms */
        {0, 1,      1,   Seg_Task_1},      /* task 1 Period: 1ms */
        {0, 500,    200,   win_effect},      /* task 1 Period: 1ms */
       
};

u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);

//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.TIMCount)      /* If the time is not 0 */
      {
            Task_Comps.TIMCount--;   /* Time counter decrement */
            if(Task_Comps.TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps.TIMCount = Task_Comps.TRITime;
                Task_Comps.Run = 1;      /* The task can be run */
            }
      }
    }
}

//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.Run) /* If task can be run */
      {
            Task_Comps.Run = 0;      /* Flag clear 0 */
            Task_Comps.TaskHook();   /* Run task */
      }
    }
}

main.c
#include "config.h"
#include "task.h"
#include "io.h"



char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";


//void Delay10ms(void)        //@24.000MHz
//{
//        unsigned long edata i;

//        _nop_();
//        _nop_();
//        i = 119998UL;
//        while (i) i--;
//}       
void main(void)
{
        //int count=1;                                                                        //按键计数变量
   
        Sys_init();                                                                                //系统初始化(调用函数)
        usb_init();                                     //USB CDC 接口配置
       
        IE2 |= 0x80;                                    //使能USB中断
        Timer0_Init();                                                                        //定时器初始化
        Init_595();                                                                        //595端口电平初始化
    EA = 1;                                                                                        //IE |= 0X80;
       
        P40=0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
       
        while(1)
        {
               
      if (bUsbOutReady)                                                        //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
               
            usb_OUT_done();                                                        //
      }
                Task_Pro_Handler_Callback();                                //执行函数


               
       }
}
void Timer0_Isr(void) interrupt 1
{
       
        Task_Marks_Handler_Callback();                        //系统计时

}
881




飞行者 发表于 2025-7-29 07:44:07

10虚拟LED和shu码管


io.c
#include "io.h"

//u8 State1 = 0;                                        //LED1初始状态
//u8 State2 = 0;                                        //LED2初始状态
//u8 State3 = 0;                                        //LED3初始状态

u16 Key_Vol = 0;                                //按键按下持续时间(几个十秒)
u16 Key_Vol_2 = 0;

//void LED0_Blink(void)
//{
//        State1 = !State1;
//        P20 = State1;
//}
//void LED1_Blink(void)
//{
//        State2 = !State2;
//        P21 = State2;
//}
//void LED2_Blink(void)
//{
//        State3 = !State3;
//        P22 = State3;
//}

u16 KEY1_COUNT = 0;                //P32按钮计数
u16 KEY2_COUNT = 0;         //P33按钮计数

void Key_Task(void)
{
//-------------------P32按钮计数-------------------
                if( P32 == 0 )
                {
                        Key_Vol++;
                        if(Key_Vol == 5)
                        {
                                KEY1_COUNT++;
                        }       
                }
                else
                {
                        Key_Vol = 0;       
                }
//-------------------P33按钮计数-------------------               
                if( P33 == 0 )
                {
                        Key_Vol_2++;
                        if(Key_Vol_2 == 5)
                        {
                                KEY2_COUNT++;
                        }       
                }
                else
                {
                        Key_Vol_2 = 0;       
                }
}



//----------------任务1:P2口流水灯,P10闪烁------------------------------------
u8 P2_STATE = 0X01;

u8 P10_STATE = 0;

void TASK_1( void )
{
        LED40_SetPort( 2, ~P2_STATE );                //点亮P20端口
        P2_STATE = (P2_STATE<<1);                        //由低位向高位一位1000 0000->1 0000 0000
        if( P2_STATE == 0 )                                        //P2端口是否是0,
                P2_STATE = 1;                                        //否则赋值1
//-------------------------P10闪烁------------------------------------
        if( P10_STATE == 0 )
                LED40_SetBit(1,0);
        else
                LED40_ClrBit(1,0);
        P10_STATE = !P10_STATE;
}

//任务2:左边数码管显示P32按下次数,右边数码管显示P33按下次数



u32 KEY_Count =0;

void TASK_2( void )
{
        KEY_Count = KEY1_COUNT * 10000 + KEY2_COUNT;
       
        SEG7_ShowLong( KEY_Count ,10 );
}

//任务3:按下数字按键在数码管显示对应的按键数字!

u32 REC_NUM = 0;

void TASK_3( void )
{
        SEG7_ShowLong( REC_NUM ,10 );
}io.h
#ifndef __IO_H
#define __IO_H

#include "config.h"        //调用头文件

void LED0_Blink(void);
void LED1_Blink(void);
void LED2_Blink(void);

void Key_Task(void);
void TASK_1( void );
void TASK_2( void );
void TASK_3( void );

#endiftask.c
#include "task.h"
#include "io.h"

//========================================================================
//                               本地变量声明
//========================================================================

static TASK_COMPONENTS Task_Comps[]=
{
//状态计数周期函数

//        {0, 300,   300,   LED0_Blink},   /* task 1 Period: 300ms */
//        {0, 600,   600,   LED1_Blink},      /* task 1 Period: 600ms */
//        {0, 900,   900,   LED2_Blink},      /* task 1 Period: 900ms */
        {0, 10,   10,   Key_Task},      /* task 1 Period: 50ms */
        {0, 500,   500,   TASK_1},      /* task 1 Period: 500ms */
//        {0, 500,   500,   TASK_2},      /* task 1 Period: 500ms */
        {0, 500,   500,   TASK_3},      /* task 1 Period: 500ms */
};

u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);

//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.TIMCount)      /* If the time is not 0 */
      {
            Task_Comps.TIMCount--;   /* Time counter decrement */
            if(Task_Comps.TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps.TIMCount = Task_Comps.TRITime;
                Task_Comps.Run = 1;      /* The task can be run */
            }
      }
    }
}

//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.Run) /* If task can be run */
      {
            Task_Comps.Run = 0;      /* Flag clear 0 */
            Task_Comps.TaskHook();   /* Run task */
      }
    }
}

#include "config.h"
#include "task.h"
#include "io.h"


//u8 State = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//u8 num = 0;
//u8 Run_State = 0;                                //运行状态
//u8 i=0;
////u16 Count_300 = 0;                                //计数300ms变量
////u16 Count_600 = 0;                                //计数600ms变量
////u16 Count_900 = 0;                                //计数900ms变量

//u16        Count_ms = {0,0,0};                        //计时变量数组
//u16 Key_Vol = 0;                                        //按键时长检测

extern u32 REC_NUM;

void Delay10ms(void)        //@24.000MHz
{
        unsigned long edata i;

        _nop_();
        _nop_();
        i = 119998UL;
        while (i) i--;
}       
void main(void)
{
        int count=1;                                                                        //按键计数变量
   
        Sys_init();                                                                                //系统初始化(调用函数)
        usb_init();                                     //USB CDC 接口配置
       
        IE2 |= 0x80;                                    //使能USB中断
        Timer0_Init();                                                                        //定时器初始化
    EA = 1;                                                                                        //IE |= 0X80;
       
       
        while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
       
        while(1)
        {
               
      if (bUsbOutReady)                                                        //如果接收到了数据
      {
            REC_NUM = UsbOutBuffer - 48;
                        //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
               
            usb_OUT_done();                                                        //
      }
                Task_Pro_Handler_Callback();                                //执行函数

//                P2 = ~State[ num ];                //num取值0-7
//                if( P32 == 0 )
//                {
//                        Delay10ms();
//                        if(P32 == 0)
//                        {
//                                while(P32 == 0);
//                               num ++;
//                                if( num >7)
//                                        num = 0;
//                        }
//                }

               
       }
}
void Timer0_Isr(void) interrupt 1
{
       
        Task_Marks_Handler_Callback();                        //系统计时
;
}
882

飞行者 发表于 2025-8-2 19:52:34

10.虚拟LED和数码管 课后小练 简易密码箱


代码文件中密码改成12345670,以下是IO.C的部分代码
//IO.C部分代码
//任务二:简易密码箱
u8 passward = { 20,20,20,20,20,20,20,20};
u8 Seg_no = 0;
void SEG_Task(void)
{
                u8 num = 0;

      switch(Seg_no){
                case 0: Display_Seg( SEG_NUM], ~T_NUM );         break;
                case 1: Display_Seg( SEG_NUM], ~T_NUM );         break;
                case 2: Display_Seg( SEG_NUM], ~T_NUM );         break;
                case 3: Display_Seg( SEG_NUM], ~T_NUM );         break;
                case 4: Display_Seg( SEG_NUM], ~T_NUM );         break;
                case 5: Display_Seg( SEG_NUM], ~T_NUM );         break;
                case 6: Display_Seg( SEG_NUM], ~T_NUM );         break;
                case 7: Display_Seg( SEG_NUM], ~T_NUM );         break;
      }
      Seg_no ++;
      if( Seg_no>7 )
                Seg_no=0;               
}
u8 Key_Vol3 = 0;                                                //判断按钮是否按下
u8 Key_no = 0;                                                      //数码管位计数
//密码输入显示
void PW_write_Task(void)
{
      if( key_num <0xff )
                {
                        Key_Vol3 ++;
                        if(Key_Vol3 == 5)                        //是否延时50m秒
                        {
                              if(Key_no == 0)                        //数码管没有按下时显示“--------”
                              {
                                        passward = 20;
                                        passward = 20;
                                        passward = 20;
                                        passward = 20;
                                        passward = 20;
                                        passward = 20;
                                        passward = 20;
                                        passward = 20;

                                       
                              }
                              passward = key_num; //键值传递
                              Key_no++;

                              if( Key_no == 8 )                //密码输入到了八位
                              {
                                        if((passward==1)&&(passward==2)&&(passward==3)&&(passward==4)&&(passward==5)&&(passward==6)&&(passward==7)&&(passward==0))
                                        {
                                                //密码正确八位数码管显示为1
                                                passward = 20;
                                                passward = 20;
                                                passward = 17;
                                                passward = 18;
                                                passward = 14;
                                                passward = 16;
                                                passward = 20;
                                                passward = 20;
                                                

                                        }
                                        else                                 //密码输入错误八位数码管显示为空
                                        {
                                                passward = 20;
                                                passward = 20;
                                                passward = 20;
                                                passward = 20;
                                                passward = 20;
                                                passward = 20;
                                                passward = 20;
                                                passward = 20;
                                        }               
                                        Key_no = 0;
                              }
                                       
                        }      
                }
                else
                {
                        Key_Vol3 = 0;      
                }
}897

页: 1 [2] 3
查看完整版本: Ai8051u擎天柱学习冲哥《8051U深度入门到32位51大型实战视频》记录贴