找回密码
 立即注册
楼主: 飞行者

Ai8051u擎天柱学习冲哥《8051U深度入门到32位51大型实战视频》记录贴

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-8 11:04:16 | 显示全部楼层
06.IO输入输出

IO口输入输出小练2.png
  1. #include "ai8051u.h"
  2. #include "stc32_stc8_usb.h"
  3. #include "math.h"
  4. #include "stdio.h"
  5. #define u8 unsigned char        //8位无符号变量(0-255)
  6.         unsigned char LED_Count = 0  ;
  7.        
  8. u8 state = 0;                                //初始状态
  9. void Delay20ms(void)        //@24.000MHz        Delay20ms( );
  10. {
  11.         unsigned long edata i;
  12.         _nop_();
  13.         _nop_();
  14.         i = 119998UL;
  15.         while (i) i--;
  16. }
  17. void main()
  18. {
  19.         WTST = 0;                                 //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  20.     EAXFR = 1;                                //扩展寄存器(XFR)访问使能
  21.     CKCON = 0;                                //提高访问XRAM速度
  22.    
  23.    
  24.     P0M1 = 0x00;   P0M0 = 0x00;
  25.     P1M1 = 0x00;   P1M0 = 0x00;
  26.     P2M1 = 0x00;   P2M0 = 0x00;
  27.     P3M1 = 0x00;   P3M0 = 0x00;
  28.     P4M1 = 0x00;   P4M0 = 0x00;
  29.     P5M1 = 0x00;   P5M0 = 0x00;
  30.     P6M1 = 0x00;   P6M0 = 0x00;
  31.     P7M1 = 0x00;   P7M0 = 0x00;
  32.    
  33.     usb_init();                                     //USB CDC 接口配置
  34.    
  35.     EA = 1;
  36.     while (1)
  37.     {
  38.         if (bUsbOutReady)
  39.         {
  40. //          USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  41. //                    printf_usb("1. Read Num:%d\n", OutNumber);
  42. //                    printf_usb("2. Read Num:%d\n", OutNumber);
  43. //                    printf_usb("3. Read Num:%d\n", OutNumber);
  44. //                    printf_usb("4. Read Num:%d\n", OutNumber);
  45.             
  46.             usb_OUT_done();
  47.         }
  48. //                //任务1:按下P32按钮灯亮,松开P32按钮灯灭。
  49. //                if(P32 == 0)                                        //判断按钮是否按下
  50. //                {
  51. //                        P20 = 0;
  52. //                }
  53. //                else
  54. //                {
  55. //                        P20 = 1;
  56. //                }
  57.                
  58. //                //任务2:按下P32按钮灯灭,松开P32按钮灯亮。
  59. //                if(P32 == 1)                                        //判断按钮是否按下
  60. //                {
  61. //                        P20 = 0;
  62. //                }
  63. //                else
  64. //                {
  65. //                        P20 = 1;
  66. //                }       
  67. //                //任务:按下P32按钮灯亮,按下P32按钮灯灭。
  68. //                if(P32 == 0)                                        //判断按钮是否按下
  69. //                {
  70. //                        Delay20ms( );                                //延时20毫秒消抖
  71. //                        if(P32 == 0)
  72. //                        {
  73. //                        state = !state;                                //变量取反
  74. //                        P20 = state;
  75. //                        printf("state %d\r\n", (int)state);
  76. //                        while(P32 ==0 );
  77. //                        }
  78. //                }
  79. //        //课后任务1:按一下P32按钮灯亮,按一下P33按钮灯灭。(按一下左边四个灯亮,右边四个灯灭,再按一下左边四个灯灭,右边四个灯亮。)
  80. //                if(P32 == 0)                                        //判断按钮是否按下
  81. //                {
  82. //                        Delay20ms( );                                //延时20毫秒消抖
  83. //                        if(P32 == 0)
  84. //                        {
  85. //                       
  86. //                        P20 = 0;
  87. //                        P21 = 0;
  88. //                        P22 = 0;
  89. //                        P23 = 0;
  90. //                        P24 = 1;
  91. //                        P25 = 1;
  92. //                        P26 = 1;
  93. //                        P27 = 1;
  94. //                       
  95. //                        while(P32 ==0 );
  96. //                        }
  97. //                }
  98. //                if(P33 == 0)                                        //判断按钮是否按下
  99. //                {
  100. //                        Delay20ms( );                                //延时20毫秒消抖
  101. //                        if(P33 == 0)
  102. //                        {
  103. //                       
  104. //                        P20 = 1;
  105. //                        P21 = 1;
  106. //                        P22 = 1;
  107. //                        P23 = 1;
  108. //                        P24 = 0;
  109. //                        P25 = 0;
  110. //                        P26 = 0;
  111. //                        P27 = 0;
  112. //                       
  113. //                        while(P33 ==0 );
  114. //                        }
  115. //                }
  116.                         //课后任务2:按一下亮一颗灯,再按一下亮两颗灯,直到全亮(变量+加法和乘法)
  117.                 if(P32 == 0)                                        //判断按钮是否按下
  118.                 {
  119.                         Delay20ms( );                                //延时20毫秒消抖
  120.                        
  121.                         if(P32 == 0)
  122.                         {
  123.                                 //更新LED计数
  124.                                 LED_Count++;
  125.                                 if(LED_Count > 8)  // 如果超过8个LED,则重置为1
  126.                                 {
  127.                                         LED_Count = 1;
  128.                                 }
  129.                                
  130.                                 //根据计数点亮相应数量的LED
  131.                                
  132.                                 P2 = 0xFF << LED_Count;  // 左移操作,点亮低LED_Count位
  133.                                 while(P32 ==0 );
  134.                         }
  135.                 }
  136.         }
  137. }
复制代码

06.IO口输入输出.rar (59.13 KB, 下载次数: 2)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-10 07:11:33 | 显示全部楼层
07 定时器中断
屏幕截图 2025-07-07 215236.png
  1. #include "ai8051u.h"                        //调用头文件
  2. #include "stc32_stc8_usb.h"                //调用头文件
  3. #include "intrins.h"                        //d调用头文件
  4. #define u8  unsigned char                //8位无符号变量(0-255)       
  5. u8 state = 0;                                        //初始状态
  6. u8 Run_State = 0;                                //运行状态
  7. char *USER_DEVICEDESC = NULL;
  8. char *USER_PRODUCTDESC = NULL;
  9. char *USER_STCISPCMD = "@STCISP#";
  10. void Delay20ms(void)        //@24.000MHz  Delay20ms();
  11. {
  12.         unsigned long edata i;
  13.         _nop_();
  14.         _nop_();
  15.         i = 119998UL;
  16.         while (i) i--;
  17. }
  18. void Timer0_Init(void);                //3秒@24.000MHz 函数声明
  19.        
  20. void main(void)
  21. {
  22.         int count=1;                                                                        //按键计数变量
  23.     WTST = 0;                                                                                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  24.     EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
  25.     CKCON = 0;                                                                                 //提高访问XRAM速度
  26.        
  27.     P0M1 = 0x00;   P0M0 = 0x00;
  28.     P1M1 = 0x00;   P1M0 = 0x00;
  29.     P2M1 = 0x00;   P2M0 = 0x00;
  30.     P3M1 = 0x00;   P3M0 = 0x00;
  31.     P4M1 = 0x00;   P4M0 = 0x00;
  32.     P5M1 = 0x00;   P5M0 = 0x00;
  33.     P6M1 = 0x00;   P6M0 = 0x00;
  34.     P7M1 = 0x00;   P7M0 = 0x00;
  35.        
  36.         usb_init();                                     //USB CDC 接口配置
  37.        
  38. //        Timer0_Init( );
  39.     IE2 |= 0x80;                                    //使能USB中断
  40.     EA = 1;                                                                                        //IE |= 0X80;
  41.        
  42.        
  43.         while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
  44.        
  45.         while(1)
  46.         {
  47.                
  48.         if (bUsbOutReady)                                                        //如果接收到了数据
  49.         {
  50.             //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  51.             
  52.             usb_OUT_done();                                                        //
  53.         }
  54.                
  55.                
  56.                 //任务1:LED灯三秒取反一次,这期间任意时刻按下按钮,串口打印按键次数。
  57. //                if( P32 == 0 )                                                                //判断P32按钮是否按下
  58. //                {
  59. //                        Delay20ms();                                                        //延时20ms消抖
  60. //                        if( P32 == 0 )
  61. //                        {
  62. //                                printf("按键按下次数\xfd:%d 次\r\n",(int)count);
  63. //                                count++;
  64. //                               
  65. //                                while( P32 == 0 );                                        //等待P32松开
  66. //                               
  67. //                        }
  68. //                }
  69.                
  70.                 //任务2:灯按一下点亮三秒后熄灭。(延时关闭车灯)
  71. //                if( P32 == 0 )                                                                //判断P32按钮是否按下
  72. //                {
  73. //                        Delay20ms();                                                        //延时20ms消抖
  74. //                        if( P32 == 0 )
  75. //                        {
  76. //                               
  77. //                                P23 = 0;                                                        //亮灯
  78. //                                Timer0_Init( );                                                //调用定时函数
  79. //                                while( P32 == 0 );                                        //等待P32松开
  80. //                               
  81. //                        }
  82. //                }
  83.                 //任务3:救护车等控制器,按下报警按钮,红蓝交替闪烁(LED1和LED2表示红灯和蓝灯),再按一下报警按钮,红蓝灯停止。
  84.                 if( P32 == 0 )                                                                //判断P32按钮是否按下
  85.                 {
  86.                         Delay20ms();                                                        //延时20ms消抖
  87.                         if( P32 == 0 )
  88.                         {
  89.                                 Run_State = !Run_State;                                //运行状态取反
  90.                                                        
  91.                                 if(Run_State == 1)
  92.                                 {
  93.                                         Timer0_Init();                                       
  94.                                 }
  95.                                 else
  96.                                 {
  97.                                         TR0 = 0;                                                //关闭定时器
  98.                                         P22 = 1;
  99.                                         P23 = 1;
  100.                                 }
  101.                                
  102.                                 while( P32 == 0 );                                        //等待P32松开
  103.                                
  104.                         }
  105.                 }
  106.         }
  107. }
  108. //void Timer0_Init(void)                //3秒@24.000MHz
  109. //{
  110. //        TM0PS = 0x5B;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
  111. //        AUXR &= 0x7F;                        //定时器时钟12T模式
  112. //        TMOD &= 0xF0;                        //设置定时器模式
  113. //        TL0 = 0x3F;                                //设置定时初始值
  114. //        TH0 = 0x01;                                //设置定时初始值
  115. //        TF0 = 0;                                //清除TF0标志
  116. //        TR0 = 1;                                //定时器0开始计时
  117. //        ET0 = 1;                                //使能定时器0中断
  118. //}
  119. void Timer0_Init(void)                //500毫秒@24.000MHz
  120. {
  121.         TM0PS = 0x0F;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
  122.         AUXR &= 0x7F;                        //定时器时钟12T模式
  123.         TMOD &= 0xF0;                        //设置定时器模式
  124.         TL0 = 0xDC;                                //设置定时初始值
  125.         TH0 = 0x0B;                                //设置定时初始值
  126.         TF0 = 0;                                //清除TF0标志
  127.         TR0 = 1;                                //定时器0开始计时
  128.         ET0 = 1;                                //使能定时器0中断
  129. }
  130. void Timer0_Isr(void) interrupt 1
  131. {
  132.         state = !state;                                       
  133.         P22 = state;                               
  134.         P23 = !state;                               
  135. }
复制代码

07.定时器中断.rar (81.68 KB, 下载次数: 0)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-12 11:32:23 | 显示全部楼层
07.定时器中断课后小练”电子功德箱“

屏幕截图 2025-07-12 111654.png
  1. // 课后小练:电子功德箱功能实现
  2. /*
  3. 功能说明:
  4. 1. 按下按钮1(P32),串口切换显示"双倍功德时间"或"单倍功德时间"
  5. 2. 按下按钮2(P33),根据当前模式增加功德值:
  6.    - 双倍模式:显示"功德+2 当前功德:xxx",LED点亮2秒
  7.    - 单倍模式:显示"功德+1 当前功德:xxx",LED点亮1秒
  8. 3. LED通过P21引脚控制,点亮后定时熄灭
  9. */
  10. // 按钮1(P32)检测与模式切换
  11. if (P32 == 0) {                  // 检测按钮1是否按下(低电平有效)
  12.     delay_ms(20);                // 延时20ms消抖,避免按键抖动误触发
  13.     if (P32 == 0) {              // 二次检测,确认按钮按下
  14.         state = !state;          // 切换模式标志位(0=单倍,1=双倍)
  15.         if (state) {             // 双倍模式
  16.             printf("双倍功德时间\r\n");
  17.         } else {                 // 单倍模式
  18.             printf("单倍功德时间\r\n");
  19.         }
  20.         while (P32 == 0);       // 等待按钮释放,防止重复触发
  21.     }
  22. }
  23. // 按钮2(P33)检测与功德值增加
  24. if (P33 == 0) {                  // 检测按钮2是否按下
  25.     delay_ms(20);                // 20ms消抖
  26.     if (P33 == 0) {              // 二次确认按下
  27.         if (state) {             // 双倍功德模式
  28.             y = y + 2;           // 功德值+2
  29.             P21 = 0;             // 点亮P21引脚LED(低电平有效,共阴极连接)
  30.             printf("功德+2 当前功德 %u \r\n", y);  // 串口输出功德值
  31.             Timer0_Init_2();     // 初始化2秒定时器,用于LED熄灭控制
  32.         } else {                 // 单倍功德模式
  33.             y++;                 // 功德值+1
  34.             printf("功德+1 当前功德 %u \r\n", y);
  35.             P21 = 0;             // 点亮LED
  36.             Timer0_Init_1();     // 初始化1秒定时器
  37.         }
  38.         while (P33 == 0);       // 等待按钮释放
  39.     }
  40. }
  41. i++;                            // 计数器自增
  42. if (i % 64 == 0) {              // 每64次循环(约320ms)
  43.     P20 = !P20;                 // 翻转P20引脚电平(可能用于调试或额外指示)
  44. }
  45. delay_ms(5);                    // 5ms延时,控制主循环频率
  46. // 毫秒延时函数(依赖系统时钟MAIN_Fosc)
  47. void delay_ms(u8 ms) {
  48.     u16 i;
  49.     do {
  50.         i = MAIN_Fosc / 6000;    // 根据系统时钟计算延时参数(24MHz时i=4000)
  51.         while (--i);             // 空循环延时
  52.     } while (--ms);              // 循环ms次
  53. }
  54. // 定时器0初始化函数(1秒定时)
  55. void Timer0_Init_1(void) {
  56.     TM0PS = 0x1E;                // 定时器时钟预分频(24MHz/(0x1E+1)=24MHz/31≈774kHz)
  57.     AUXR &= 0x7F;                // 定时器时钟12T模式(1个机器周期=12个时钟周期)
  58.     TMOD &= 0xF0;                // 保留定时器0模式位(低4位不变)
  59.     TL0 = 0xFC;                  // 定时初值低8位(配合TH0实现1ms定时)
  60.     TH0 = 0x03;                  // 定时初值高8位
  61.     TF0 = 0;                     // 清除定时器0溢出标志
  62.     TR0 = 1;                     // 启动定时器0
  63.     ET0 = 1;                     // 使能定时器0中断
  64. }
  65. // 定时器0初始化函数(2秒定时)
  66. void Timer0_Init_2(void) {
  67.     TM0PS = 0x3D;                // 预分频值更大(24MHz/(0x3D+1)=24MHz/62≈387kHz)
  68.     AUXR &= 0x7F;                // 12T模式
  69.     TMOD &= 0xF0;                // 定时器0模式
  70.     TL0 = 0xFC;                  // 初值与1秒模式相同(通过预分频实现更长定时)
  71.     TH0 = 0x03;                  
  72.     TF0 = 0;
  73.     TR0 = 1;
  74.     ET0 = 1;
  75. }
  76. // 定时器0中断服务函数
  77. void Timer0_Isr(void) interrupt 1 {
  78.     P21 = 1;                     // 熄灭LED(高电平,共阴极连接)
  79.     TR0 = 0;                     // 停止定时器0
  80. }
复制代码

电子功德箱.rar (68.77 KB, 下载次数: 1)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-12 11:44:47 | 显示全部楼层
08.定时器周期性调度任务

屏幕截图 2025-07-11 081025.png
  1. #include "config.h"
  2. #include "task.h"
  3. #include "io.h"
  4. char *USER_DEVICEDESC = NULL;
  5. char *USER_PRODUCTDESC = NULL;
  6. char *USER_STCISPCMD = "@STCISP#";
  7. void Delay10ms(void)        //@24.000MHz
  8. {
  9.         unsigned long edata i;
  10.         _nop_();
  11.         _nop_();
  12.         i = 119998UL;
  13.         while (i) i--;
  14. }       
  15. void main(void)
  16. {
  17.         int count=1;                                                                        //按键计数变量
  18.    
  19.         Sys_init();                                                                                //系统初始化(调用函数)
  20.         usb_init();                                     //USB CDC 接口配置
  21.        
  22.         IE2 |= 0x80;                                    //使能USB中断
  23.         Timer0_Init();                                                                        //定时器初始化
  24.     EA = 1;                                                                                        //IE |= 0X80;
  25.        
  26.        
  27.         while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
  28.        
  29.         while(1)
  30.         {
  31.                
  32.         if (bUsbOutReady)                                                        //如果接收到了数据
  33.         {
  34.             //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  35.                
  36.             usb_OUT_done();                                                        //
  37.         }
  38.                 Task_Pro_Handler_Callback();                                //执行函数               
  39.          }
  40. }
  41. void Timer0_Isr(void) interrupt 1
  42. {
  43.        
  44.         Task_Marks_Handler_Callback();                        //系统计时;
  45. }
复制代码

08.定时器周期性调度任务.rar (193.99 KB, 下载次数: 2)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-21 08:45:26 | 显示全部楼层
09.数码管

屏幕截图 2025-07-17 082354.png
io.c代码
  1. #include "io.h"
  2. u8 SEG_NUM[] =
  3. {
  4.         0x3F,       /*'0', 0*/
  5.     0x06,       /*'1', 1*/
  6.     0x5B,       /*'2', 2*/
  7.     0x4F,       /*'3', 3*/
  8.     0x66,       /*'4', 4*/
  9.     0x6D,       /*'5', 5*/
  10.     0x7D,       /*'6', 6*/
  11.     0x07,       /*'7', 7*/
  12.     0x7F,       /*'8', 8*/
  13.     0x6F,       /*'9', 9*/
  14.     0x77,       /*'A', 10*/
  15.     0x7C,       /*'B', 11*/
  16.     0x39,       /*'C', 12*/
  17.     0x5E,       /*'D', 13*/
  18.     0x79,       /*'E', 14*/
  19.     0x71,       /*'F', 15*/
  20.     0x40,       /*'-', 16*/
  21.     0x00,       /*' ', 17*/
  22.     0x80,       /*'.', 18*/
  23. };
  24. u8 T_NUM[8] =
  25. {
  26.         0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
  27. };
  28. //u8 State1 = 0;                                        //LED1初始状态
  29. //u8 State2 = 0;                                        //LED2初始状态
  30. //u8 State3 = 0;                                        //LED3初始状态
  31. //u16 Key_Vol = 0;                                //按键按下持续时间(几个十秒)
  32. //void LED0_Blink(void)
  33. //{
  34. //        State1 = !State1;
  35. //        P20 = State1;
  36. //}
  37. //void LED1_Blink(void)
  38. //{
  39. //        State2 = !State2;
  40. //        P21 = State2;
  41. //}
  42. //void LED2_Blink(void)
  43. //{
  44. //        State3 = !State3;
  45. //        P22 = State3;
  46. //}
  47. //void Key_Task(void)
  48. //{
  49. //                if( P32 == 0 )
  50. //                {
  51. //                        Key_Vol++;
  52. //                        if(Key_Vol == 5)
  53. //                        {
  54. //                                printf("按键单击\r\n");
  55. //                        }        
  56. //                }
  57. //                else
  58. //                {
  59. //                        Key_Vol = 0;        
  60. //                }
  61. //}
  62. //------------------------------------595函数定义-------------------------------------------------
  63. void Init_595(void)
  64. {
  65.         HC595_SER  = 0;
  66.         HC595_RCK  = 0;
  67.         HC595_SCK  = 0;
  68. }
  69. void Send_595( u8 dat )
  70. {
  71.         u8 i;
  72.         for( i=0; i<8; i++ )
  73.         {
  74.                 dat <<= 1;                        //数值左移一位
  75.                 HC595_SER  = CY;        //数据写到引脚
  76.             HC595_RCK  = 1;                //输出上升沿的时钟信号
  77.         HC595_SCK  = 0;
  78.         }
  79. }
  80. void Display_Seg( u8 HC595_1,u8 HC595_2)
  81. {
  82.         Send_595(HC595_1);                //数码管段码输出        高电平点亮
  83.         Send_595(HC595_2);                //数码管位码输出        低电平点亮
  84.         HC595_RCK  = 1;                        //数据输出
  85.         HC595_RCK  = 0;
  86. }
  87. u8 Seg_no = 0;
  88. u8 shi = 0;
  89. u8 fen = 0;
  90. u8 miao = 0;
  91. void Seg_Task(void)
  92. {
  93.         u8 num = 0;
  94.         if( Seg_no == 0 )                                                        //数码管小时十位
  95.         {
  96.                 num = shi/10;
  97.                 Display_Seg( SEG_NUM[num], ~T_NUM[0]);        //数码管段码和位码
  98.         }
  99.         else if(Seg_no == 1)                                                //小时的个位
  100.         {
  101.                 num = shi%10;
  102.                 Display_Seg( SEG_NUM[num], ~T_NUM[1]);        //数码管段码和位码
  103.         }
  104.         else if(Seg_no == 2)                                                //第一个横杠
  105.         {
  106.                
  107.                 Display_Seg( SEG_NUM[16],~T_NUM[2]);        //数码管段码和位码
  108.         }
  109.         if( Seg_no == 3 )                                                        //数码管分十位
  110.         {
  111.                 num = fen/10;
  112.                 Display_Seg( SEG_NUM[num], ~T_NUM[3]);        //数码管段码和位码
  113.         }
  114.         else if(Seg_no == 4)                                                //分钟个位
  115.         {
  116.                 num = fen%10;
  117.                 Display_Seg( SEG_NUM[num], ~T_NUM[4]);        //数码管段码和位码
  118.         }
  119.         else if(Seg_no == 5)                                                //第二个横杠
  120.         {
  121.                
  122.                 Display_Seg( SEG_NUM[16],~T_NUM[5]);        //数码管段码和位码
  123.         }
  124.         if( Seg_no == 6)                                                        //数码管秒十位
  125.         {
  126.                 num = fen/10;
  127.                 Display_Seg( SEG_NUM[num], ~T_NUM[6]);        //数码管段码和位码
  128.         }
  129.         else if(Seg_no == 7)                                                //秒的个位
  130.         {
  131.                 num = fen%10;
  132.                 Display_Seg( SEG_NUM[num], ~T_NUM[7]);        //数码管段码和位码
  133.         }
  134.         else                                                
  135.         {
  136.         }
  137.         Seg_no ++;
  138.         if( Seg_no>7 )
  139.                 Seg_no=0;
  140. }
  141. void TIMECOUNT_Task(void)
  142. {
  143.         miao ++;
  144.         if( miao>60 )
  145.         {
  146.                 miao = 0;
  147.                 fen ++;
  148.                 if(fen >60)
  149.                 {
  150.                         fen = 0;
  151.                         shi ++;
  152.                         if( shi>24 )
  153.                                 shi = 0;
  154.                 }
  155.         }
  156. }
  157. u8 state_now = 0;
  158. void PLED_40(void)
  159. {
  160.         u8 cod[8];
  161.         cod[0] = 0x0f;                //表示开启P0-P3
  162.         cod[1] = 0x01;                //P0端口
  163.         cod[2] = 0x01;                //P1
  164.         cod[3] = ~T_NUM[state_now];                //P2
  165.         cod[4] = 0x01;                //P3
  166.         LED40_SendData( cod, 5 );
  167.         
  168.         P2 = ~T_NUM[state_now];
  169.         state_now++;
  170.         if(state_now > 7)
  171.                 state_now = 0;
  172.         
  173. }
  174. void SEG_PC(void)
  175. {
  176.                 u8 cod[8];
  177.                 cod[0] = SEG_NUM[shi/10];                                //数码管小时十位数段码
  178.                 cod[1] = SEG_NUM[shi%10];                                //小时的个位
  179.                 cod[2] =SEG_NUM[16];                                        //第一个横杠
  180.                
  181.                 cod[3] = SEG_NUM[fen/10];                                //数码管分钟十位数段码
  182.                 cod[4] = SEG_NUM[fen%10];                                //分钟的个位
  183.                 cod[5] =SEG_NUM[16];                                        //第二个横杠
  184.         
  185.                 cod[6] = SEG_NUM[miao/10];                                //数码管秒十位数段码
  186.                 cod[7] = SEG_NUM[miao%10];                                //秒的个位
  187.         
  188.                 SEG7_ShowCode(cod);        
  189. }
复制代码
io.h代码
  1. #ifndef __IO_H
  2. #define __IO_H
  3. #include "config.h"        //调用头文件
  4. //定义引脚名称
  5. #define HC595_SER         P34
  6. #define HC595_RCK         P35
  7. #define HC595_SCK         P32
  8. void LED0_Blink(void);
  9. void LED1_Blink(void);
  10. void LED2_Blink(void);
  11. void Key_Task(void);
  12. //--------------------------------------------------74HC595控制函数声明-----------------------------------------------------
  13. void Init_595(void);
  14. void Send_595( u8 dat );
  15. void Display_Seg( u8 HC595_1,u8 HC595_2);
  16. void Seg_Task(void);
  17. void TIMECOUNT_Task(void);
  18. void PLED_40(void);
  19. void SEG_PC(void);
  20. #endif
复制代码
task.c
  1. #include "task.h"
  2. #include "io.h"
  3. //========================================================================
  4. //                               本地变量声明
  5. //========================================================================
  6. static TASK_COMPONENTS Task_Comps[]=
  7. {
  8. //状态  计数  周期  函数
  9. //        {0, 300,   300,   LED0_Blink},     /* task 1 Period: 300ms */
  10. //        {0, 600,   600,   LED1_Blink},      /* task 1 Period: 600ms */
  11. //        {0, 900,   900,   LED2_Blink},      /* task 1 Period: 900ms */
  12. //        {0, 10,   10,     Key_Task},      /* task 1 Period: 50ms */
  13.         {0, 1,   1,       Seg_Task},      /* task 1 Period: 1ms */
  14.         {0, 1000,   1000,   TIMECOUNT_Task},      /* task 1 Period: 1000ms */
  15.         {0, 1000,   1000,    PLED_40},      /* task 1 Period: 500ms */
  16.         {0, 1000,   1000,   SEG_PC},      /* task 1 Period: 1000ms */
  17.         
  18. };
  19. u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]);
  20. //========================================================================
  21. // 函数: Task_Handler_Callback
  22. // 描述: 任务标记回调函数.
  23. // 参数: None.
  24. // 返回: None.
  25. // 版本: V1.0, 2012-10-22
  26. //========================================================================
  27. void Task_Marks_Handler_Callback(void)
  28. {
  29.     u8 i;
  30.     for(i=0; i<Tasks_Max; i++)
  31.     {
  32.         if(Task_Comps[i].TIMCount)      /* If the time is not 0 */
  33.         {
  34.             Task_Comps[i].TIMCount--;   /* Time counter decrement */
  35.             if(Task_Comps[i].TIMCount == 0) /* If time arrives */
  36.             {
  37.                 /*Resume the timer value and try again */
  38.                 Task_Comps[i].TIMCount = Task_Comps[i].TRITime;  
  39.                 Task_Comps[i].Run = 1;      /* The task can be run */
  40.             }
  41.         }
  42.     }
  43. }
  44. //========================================================================
  45. // 函数: Task_Pro_Handler_Callback
  46. // 描述: 任务处理回调函数.
  47. // 参数: None.
  48. // 返回: None.
  49. // 版本: V1.0, 2012-10-22
  50. //========================================================================
  51. void Task_Pro_Handler_Callback(void)
  52. {
  53.     u8 i;
  54.     for(i=0; i<Tasks_Max; i++)
  55.     {
  56.         if(Task_Comps[i].Run) /* If task can be run */
  57.         {
  58.             Task_Comps[i].Run = 0;      /* Flag clear 0 */
  59.             Task_Comps[i].TaskHook();   /* Run task */
  60.         }
  61.     }
  62. }
复制代码

09shu码管.rar (198.96 KB, 下载次数: 2)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-29 00:05:21 | 显示全部楼层
09数码管课后小练 简易10秒免单计数器 感谢国芯公司,已收到AI8051u试验箱。
此代码借鉴了坛友silas***的代码:
屏幕截图 2025-07-28 233355.png
io.c
  1. #include "io.h"
  2. #include "task.h"
  3. u8 SEG_NUM[] =
  4. {
  5.             0x3F,       /*'0', 0*/
  6.     0x06,       /*'1', 1*/
  7.     0x5B,       /*'2', 2*/
  8.     0x4F,       /*'3', 3*/
  9.     0x66,       /*'4', 4*/
  10.     0x6D,       /*'5', 5*/
  11.     0x7D,       /*'6', 6*/
  12.     0x07,       /*'7', 7*/
  13.     0x7F,       /*'8', 8*/
  14.     0x6F,       /*'9', 9*/
  15.     0x77,       /*'A', 10*/
  16.     0x7C,       /*'B', 11*/
  17.     0x39,       /*'C', 12*/
  18.     0x5E,       /*'D', 13*/
  19.     0x79,       /*'E', 14*/
  20.     0x71,       /*'F', 15*/
  21.     0x40,       /*'-', 16*/
  22.     0x00,       /*' ', 17*/
  23.     0x80,       /*'.', 18*/
  24. };
  25. u8 T_NUM[8] =
  26. {
  27.         0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
  28. };
  29. u16 Key_Vol = 0;                                //按键按下持续时间(几个十秒)
  30. //------------------------------------595函数定义-------------------------------------------------
  31. void Init_595(void)
  32. {
  33.         HC595_SER  = 0;
  34.         HC595_RCK  = 0;
  35.         HC595_SCK  = 0;
  36. }
  37. void Send_595( u8 dat )
  38. {
  39.         u8 i;
  40.         for( i=0; i<8; i++ )
  41.         {
  42.                 dat <<= 1;                        //数值左移一位
  43.                 HC595_SER  = CY;        //数据写到引脚
  44.             HC595_SCK  = 1;                //输出上升沿的时钟信号
  45.         HC595_SCK  = 0;
  46.         }
  47. }
  48. void Display_Seg( u8 HC595_1,u8 HC595_2)
  49. {
  50.         Send_595(HC595_1);                //数码管段码输出        高电平点亮
  51.         Send_595(HC595_2);                //数码管位码输出        低电平点亮
  52.        
  53.         HC595_RCK  = 1;                        //数据输出
  54.         HC595_RCK  = 0;
  55. }
  56. u8 Seg_no = 0;
  57. u8 Seg_no_1 = 0;
  58. u8 shi = 0;
  59. u8 fen = 0;
  60. u8 miao = 0;
  61. u8 ms_10 =0;
  62. u8 Run = 0;
  63. //u8 Key_Vol =0;
  64. bit win = 0;
  65. bit key_Start =1;       
  66. u8 Key_Tabe =0;
  67. //计时函数
  68. void TIMECOUNT_Task(void)
  69. {
  70.         if(key_Start==0)
  71.         {
  72.                 ms_10 ++;
  73.                 if( ms_10>100 )
  74.                 {
  75.                         ms_10 = 0;
  76.                         miao++;
  77.                         if(miao>15)
  78.                         {
  79.                                 miao = 0;
  80.                         }
  81.                 }
  82.         }       
  83. }
  84. /**
  85. * 10秒抢答模式显示函数
  86. * 功能:特殊显示模式,固定前缀"10:00.",后4位显示当前秒和毫秒
  87. * 用途:用于抢答场景,直观展示10秒倒计时窗口
  88. */
  89. /**
  90. * 10秒抢答模式显示函数(仅用if-else实现)
  91. * 功能:特殊显示模式,固定前缀"10:00.",后4位显示当前秒和毫秒
  92. */
  93. void Seg_Task_1(void)
  94. {
  95.         switch(Seg_no){
  96.                 case 0: Display_Seg( SEG_NUM[1], ~T_NUM[0] );   break;//小时十位
  97.                 case 1: Display_Seg( SEG_NUM[0]|SEG_NUM[18], ~T_NUM[1] );   break;
  98.                 case 2: Display_Seg( SEG_NUM[0], ~T_NUM[2] );   break;
  99.                 case 3: Display_Seg( SEG_NUM[0], ~T_NUM[3] );   break;
  100.                 case 4: Display_Seg( SEG_NUM[miao/10], ~T_NUM[4] );   break;
  101.                 case 5: Display_Seg( SEG_NUM[miao%10]|SEG_NUM[18], ~T_NUM[5] );   break;
  102.                 case 6: Display_Seg( SEG_NUM[ms_10/10], ~T_NUM[6] );   break;
  103.                 case 7: Display_Seg( SEG_NUM[ms_10%10], ~T_NUM[7] );   break;
  104.         }
  105.        
  106.         Seg_no++;
  107.         if(Seg_no>7){
  108.         Seg_no=0;
  109.         }
  110. }
  111. u8 state_now = 0;
  112. //u8 Seg_no=0;
  113. /*课后小练:简易10秒免单计数器.
  114. 1.在前四位数码管上显示目标时间,即“ 10. 00 ”表示定时时间10秒钟
  115. 2.后四位显示当前的计时00.00,最小单位为10msBuild started: Project: demo
  116. 3.按下开始按钮后,每10ms最末尾的数字+1;直到按下结束按钮后停止计数。
  117. */
  118. //按键处理任务
  119. void KEY_Task(void)
  120. {
  121.         if( P34 == 0)                        //检测到P34按键按下
  122.         {
  123.                 Key_Vol++;                        //消抖计数累加
  124.                 if( Key_Vol == 5)        //连续检测到5次低电平(消抖完成)
  125.                 {
  126.                         if(key_Start ==1)        // 当前是暂停状态,则切换到运行
  127.                         {
  128.                                 key_Start = 0;
  129.                         }               
  130.                         else if(key_Start == 0)        //// 当前是运行状态,则切换到暂停
  131.                         {
  132.                                 key_Start = 1;
  133.                                 // 判断是否在9.5-10.5秒之间按下,满足则判定为胜利
  134.                 if((miao == 10 && ms_10 > 50) || (miao == 9 && ms_10 > 50))
  135.                                 {
  136.                                         win = 1;
  137.                                        
  138.                                 }
  139.                         }
  140.                 }
  141.         }
  142.         else if(P33 == 0)        // 检测到P33按键按下(复位键)       
  143.         {
  144.                 Key_Vol++;
  145.         if(Key_Vol == 5)       // 消抖完成
  146.                 {
  147.                 key_Start = 1;       // 暂停计时
  148.         ms_10 = 0;        // 重置毫秒
  149.         miao = 0;           // 重置秒
  150.         win = 0;            // 清除胜利标志
  151.                 P0 = 0xFF;          // 关闭P0口控制的LED
  152.                 }
  153.         }
  154.         else
  155.         {
  156.                 Key_Vol = 0;
  157.         }
  158. }
  159. /**
  160. * 胜利效果展示函数
  161. * 功能:当win=1时,P0口8个LED依次点亮(流水灯效果)
  162. */
  163. u8 led_eff=0;
  164. void win_effect(void)
  165. {
  166.     if(win == 1)               // 胜利状态
  167.     {
  168.         P0 =~T_NUM[led_eff];   // 点亮当前LED(低电平有效,取反后对应位为0)
  169.         led_eff++;              // 切换到下一个LED
  170.         if(led_eff > 7)
  171.         {
  172.                        
  173.             led_eff = 0;        // 循环显示
  174.         }
  175.     }
  176. }
  177. void PLED_40(void)
  178. {
  179.         u8 cod[8];
  180.         cod[0] = 0x0f;                //表示开启P0-P3
  181.         cod[1] = 0x01;                //P0端口
  182.         cod[2] = 0x01;                //P1
  183.         cod[3] = ~T_NUM[state_now];                //P2
  184.         cod[4] = 0x01;                //P3
  185.         LED40_SendData( cod, 5 );
  186.        
  187.         P2 = ~T_NUM[state_now];
  188.         state_now++;
  189.         if(state_now > 7)
  190.                 state_now = 0;
  191.        
  192. }
  193. void SEG_PC(void)
  194. {
  195.                 u8 cod[8];
  196.                 cod[0] = SEG_NUM[shi/10];                                //数码管小时十位数段码
  197.                 cod[1] = SEG_NUM[shi%10];                                //小时的个位
  198.                 cod[2] =SEG_NUM[16];                                        //第一个横杠
  199.                
  200.                 cod[3] = SEG_NUM[fen/10];                                //数码管分钟十位数段码
  201.                 cod[4] = SEG_NUM[fen%10];                                //分钟的个位
  202.                 cod[5] =SEG_NUM[16];                                        //第二个横杠
  203.        
  204.                 cod[6] = SEG_NUM[miao/10];                                //数码管秒十位数段码
  205.                 cod[7] = SEG_NUM[miao%10];                                //秒的个位
  206.        
  207.                 SEG7_ShowCode(cod);       
  208. }
复制代码
io.h
  1. #ifndef __IO_H
  2. #define __IO_H
  3. #include "config.h"        //调用头文件
  4. //定义引脚名称
  5. #define HC595_SER         P34
  6. #define HC595_RCK         P35
  7. #define HC595_SCK         P32
  8. void Key_Task(void);
  9. //--------------------------------------------------74HC595控制函数声明-----------------------------------------------------
  10. void Init_595(void);
  11. void Send_595( u8 dat );
  12. void Display_Seg( u8 HC595_1,u8 HC595_2);
  13. //void Seg_Task(void);
  14. void TIMECOUNT_Task(void);
  15. void PLED_40(void);
  16. void SEG_PC(void);
  17. void KEY_Task(void);
  18. void Seg_Task_1(void);
  19. void win_effect(void);
  20. #endif
复制代码
task.c
  1. #include "task.h"
  2. #include "io.h"
  3. //========================================================================
  4. //                               本地变量声明
  5. //========================================================================
  6. static TASK_COMPONENTS Task_Comps[]=
  7. {
  8. //状态  计数  周期  函数
  9. //        {0, 10,   10,     Key_Task},      /* task 1 Period: 50ms */
  10. //        {0, 1,   1,       Seg_Task},      /* task 1 Period: 1ms */
  11.         {0, 10,   10,   TIMECOUNT_Task},      /* task 1 Period: 1000ms */
  12. //        {0, 1000,   1000,    PLED_40},      /* task 1 Period: 500ms */
  13. //        {0, 1,   1,   SEG_PC},      /* task 1 Period: 1ms */
  14.         {0, 10,     10,   KEY_Task},      /* task 1 Period: 1000ms */
  15.         {0, 1,      1,   Seg_Task_1},      /* task 1 Period: 1ms */
  16.         {0, 500,    200,   win_effect},      /* task 1 Period: 1ms */
  17.        
  18. };
  19. u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]);
  20. //========================================================================
  21. // 函数: Task_Handler_Callback
  22. // 描述: 任务标记回调函数.
  23. // 参数: None.
  24. // 返回: None.
  25. // 版本: V1.0, 2012-10-22
  26. //========================================================================
  27. void Task_Marks_Handler_Callback(void)
  28. {
  29.     u8 i;
  30.     for(i=0; i<Tasks_Max; i++)
  31.     {
  32.         if(Task_Comps[i].TIMCount)      /* If the time is not 0 */
  33.         {
  34.             Task_Comps[i].TIMCount--;   /* Time counter decrement */
  35.             if(Task_Comps[i].TIMCount == 0) /* If time arrives */
  36.             {
  37.                 /*Resume the timer value and try again */
  38.                 Task_Comps[i].TIMCount = Task_Comps[i].TRITime;  
  39.                 Task_Comps[i].Run = 1;      /* The task can be run */
  40.             }
  41.         }
  42.     }
  43. }
  44. //========================================================================
  45. // 函数: Task_Pro_Handler_Callback
  46. // 描述: 任务处理回调函数.
  47. // 参数: None.
  48. // 返回: None.
  49. // 版本: V1.0, 2012-10-22
  50. //========================================================================
  51. void Task_Pro_Handler_Callback(void)
  52. {
  53.     u8 i;
  54.     for(i=0; i<Tasks_Max; i++)
  55.     {
  56.         if(Task_Comps[i].Run) /* If task can be run */
  57.         {
  58.             Task_Comps[i].Run = 0;      /* Flag clear 0 */
  59.             Task_Comps[i].TaskHook();   /* Run task */
  60.         }
  61.     }
  62. }
复制代码
main.c
  1. #include "config.h"
  2. #include "task.h"
  3. #include "io.h"
  4. char *USER_DEVICEDESC = NULL;
  5. char *USER_PRODUCTDESC = NULL;
  6. char *USER_STCISPCMD = "@STCISP#";
  7. //void Delay10ms(void)        //@24.000MHz
  8. //{
  9. //        unsigned long edata i;
  10. //        _nop_();
  11. //        _nop_();
  12. //        i = 119998UL;
  13. //        while (i) i--;
  14. //}       
  15. void main(void)
  16. {
  17.         //int count=1;                                                                        //按键计数变量
  18.    
  19.         Sys_init();                                                                                //系统初始化(调用函数)
  20.         usb_init();                                     //USB CDC 接口配置
  21.        
  22.         IE2 |= 0x80;                                    //使能USB中断
  23.         Timer0_Init();                                                                        //定时器初始化
  24.         Init_595();                                                                        //595端口电平初始化
  25.     EA = 1;                                                                                        //IE |= 0X80;
  26.        
  27.         P40=0;
  28.        
  29.         while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
  30.        
  31.         while(1)
  32.         {
  33.                
  34.         if (bUsbOutReady)                                                        //如果接收到了数据
  35.         {
  36.             //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  37.                
  38.             usb_OUT_done();                                                        //
  39.         }
  40.                 Task_Pro_Handler_Callback();                                //执行函数
  41.                
  42.          }
  43. }
  44. void Timer0_Isr(void) interrupt 1
  45. {
  46.        
  47.         Task_Marks_Handler_Callback();                        //系统计时
  48. }
复制代码

09shu码管 10秒简易计数器.rar (202.48 KB, 下载次数: 1)





回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-29 07:33:12 | 显示全部楼层
09数码管课后小练 10s免单计数器 感谢国芯公司,已收到AI8051u试验箱 代码参考了坛友silas3082的代码
屏幕截图 2025-07-28 233355.png

09shu码管 10秒简易计数器.rar

202.48 KB, 下载次数: 0

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-29 07:33:13 | 显示全部楼层
09数码管课后小练 10s免单计数器 感谢国芯公司,已收到AI8051u试验箱 代码参考了坛友silas3082的代码

io.c
  1. #include "io.h"
  2. #include "task.h"
  3. u8 SEG_NUM[] =
  4. {
  5.             0x3F,       /*'0', 0*/
  6.     0x06,       /*'1', 1*/
  7.     0x5B,       /*'2', 2*/
  8.     0x4F,       /*'3', 3*/
  9.     0x66,       /*'4', 4*/
  10.     0x6D,       /*'5', 5*/
  11.     0x7D,       /*'6', 6*/
  12.     0x07,       /*'7', 7*/
  13.     0x7F,       /*'8', 8*/
  14.     0x6F,       /*'9', 9*/
  15.     0x77,       /*'A', 10*/
  16.     0x7C,       /*'B', 11*/
  17.     0x39,       /*'C', 12*/
  18.     0x5E,       /*'D', 13*/
  19.     0x79,       /*'E', 14*/
  20.     0x71,       /*'F', 15*/
  21.     0x40,       /*'-', 16*/
  22.     0x00,       /*' ', 17*/
  23.     0x80,       /*'.', 18*/
  24. };
  25. u8 T_NUM[8] =
  26. {
  27.         0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
  28. };
  29. u16 Key_Vol = 0;                                //按键按下持续时间(几个十秒)
  30. //------------------------------------595函数定义-------------------------------------------------
  31. void Init_595(void)
  32. {
  33.         HC595_SER  = 0;
  34.         HC595_RCK  = 0;
  35.         HC595_SCK  = 0;
  36. }
  37. void Send_595( u8 dat )
  38. {
  39.         u8 i;
  40.         for( i=0; i<8; i++ )
  41.         {
  42.                 dat <<= 1;                        //数值左移一位
  43.                 HC595_SER  = CY;        //数据写到引脚
  44.             HC595_SCK  = 1;                //输出上升沿的时钟信号
  45.         HC595_SCK  = 0;
  46.         }
  47. }
  48. void Display_Seg( u8 HC595_1,u8 HC595_2)
  49. {
  50.         Send_595(HC595_1);                //数码管段码输出        高电平点亮
  51.         Send_595(HC595_2);                //数码管位码输出        低电平点亮
  52.        
  53.         HC595_RCK  = 1;                        //数据输出
  54.         HC595_RCK  = 0;
  55. }
  56. u8 Seg_no = 0;
  57. u8 Seg_no_1 = 0;
  58. u8 shi = 0;
  59. u8 fen = 0;
  60. u8 miao = 0;
  61. u8 ms_10 =0;
  62. u8 Run = 0;
  63. //u8 Key_Vol =0;
  64. bit win = 0;
  65. bit key_Start =1;       
  66. u8 Key_Tabe =0;
  67. //计时函数
  68. void TIMECOUNT_Task(void)
  69. {
  70.         if(key_Start==0)
  71.         {
  72.                 ms_10 ++;
  73.                 if( ms_10>100 )
  74.                 {
  75.                         ms_10 = 0;
  76.                         miao++;
  77.                         if(miao>15)
  78.                         {
  79.                                 miao = 0;
  80.                         }
  81.                 }
  82.         }       
  83. }
  84. /**
  85. * 10秒抢答模式显示函数
  86. * 功能:特殊显示模式,固定前缀"10:00.",后4位显示当前秒和毫秒
  87. * 用途:用于抢答场景,直观展示10秒倒计时窗口
  88. */
  89. /**
  90. * 10秒抢答模式显示函数(仅用if-else实现)
  91. * 功能:特殊显示模式,固定前缀"10:00.",后4位显示当前秒和毫秒
  92. */
  93. void Seg_Task_1(void)
  94. {
  95.         switch(Seg_no){
  96.                 case 0: Display_Seg( SEG_NUM[1], ~T_NUM[0] );   break;//小时十位
  97.                 case 1: Display_Seg( SEG_NUM[0]|SEG_NUM[18], ~T_NUM[1] );   break;
  98.                 case 2: Display_Seg( SEG_NUM[0], ~T_NUM[2] );   break;
  99.                 case 3: Display_Seg( SEG_NUM[0], ~T_NUM[3] );   break;
  100.                 case 4: Display_Seg( SEG_NUM[miao/10], ~T_NUM[4] );   break;
  101.                 case 5: Display_Seg( SEG_NUM[miao%10]|SEG_NUM[18], ~T_NUM[5] );   break;
  102.                 case 6: Display_Seg( SEG_NUM[ms_10/10], ~T_NUM[6] );   break;
  103.                 case 7: Display_Seg( SEG_NUM[ms_10%10], ~T_NUM[7] );   break;
  104.         }
  105.        
  106.         Seg_no++;
  107.         if(Seg_no>7){
  108.         Seg_no=0;
  109.         }
  110. }
  111. u8 state_now = 0;
  112. //u8 Seg_no=0;
  113. /*课后小练:简易10秒免单计数器.
  114. 1.在前四位数码管上显示目标时间,即“ 10. 00 ”表示定时时间10秒钟
  115. 2.后四位显示当前的计时00.00,最小单位为10msBuild started: Project: demo
  116. 3.按下开始按钮后,每10ms最末尾的数字+1;直到按下结束按钮后停止计数。
  117. */
  118. //按键处理任务
  119. void KEY_Task(void)
  120. {
  121.         if( P34 == 0)                        //检测到P34按键按下
  122.         {
  123.                 Key_Vol++;                        //消抖计数累加
  124.                 if( Key_Vol == 5)        //连续检测到5次低电平(消抖完成)
  125.                 {
  126.                         if(key_Start ==1)        // 当前是暂停状态,则切换到运行
  127.                         {
  128.                                 key_Start = 0;
  129.                         }               
  130.                         else if(key_Start == 0)        //// 当前是运行状态,则切换到暂停
  131.                         {
  132.                                 key_Start = 1;
  133.                                 // 判断是否在9.5-10.5秒之间按下,满足则判定为胜利
  134.                 if((miao == 10 && ms_10 > 50) || (miao == 9 && ms_10 > 50))
  135.                                 {
  136.                                         win = 1;
  137.                                        
  138.                                 }
  139.                         }
  140.                 }
  141.         }
  142.         else if(P33 == 0)        // 检测到P33按键按下(复位键)       
  143.         {
  144.                 Key_Vol++;
  145.         if(Key_Vol == 5)       // 消抖完成
  146.                 {
  147.                 key_Start = 1;       // 暂停计时
  148.         ms_10 = 0;        // 重置毫秒
  149.         miao = 0;           // 重置秒
  150.         win = 0;            // 清除胜利标志
  151.                 P0 = 0xFF;          // 关闭P0口控制的LED
  152.                 }
  153.         }
  154.         else
  155.         {
  156.                 Key_Vol = 0;
  157.         }
  158. }
  159. /**
  160. * 胜利效果展示函数
  161. * 功能:当win=1时,P0口8个LED依次点亮(流水灯效果)
  162. */
  163. u8 led_eff=0;
  164. void win_effect(void)
  165. {
  166.     if(win == 1)               // 胜利状态
  167.     {
  168.         P0 =~T_NUM[led_eff];   // 点亮当前LED(低电平有效,取反后对应位为0)
  169.         led_eff++;              // 切换到下一个LED
  170.         if(led_eff > 7)
  171.         {
  172.                        
  173.             led_eff = 0;        // 循环显示
  174.         }
  175.     }
  176. }
  177. void PLED_40(void)
  178. {
  179.         u8 cod[8];
  180.         cod[0] = 0x0f;                //表示开启P0-P3
  181.         cod[1] = 0x01;                //P0端口
  182.         cod[2] = 0x01;                //P1
  183.         cod[3] = ~T_NUM[state_now];                //P2
  184.         cod[4] = 0x01;                //P3
  185.         LED40_SendData( cod, 5 );
  186.        
  187.         P2 = ~T_NUM[state_now];
  188.         state_now++;
  189.         if(state_now > 7)
  190.                 state_now = 0;
  191.        
  192. }
  193. void SEG_PC(void)
  194. {
  195.                 u8 cod[8];
  196.                 cod[0] = SEG_NUM[shi/10];                                //数码管小时十位数段码
  197.                 cod[1] = SEG_NUM[shi%10];                                //小时的个位
  198.                 cod[2] =SEG_NUM[16];                                        //第一个横杠
  199.                
  200.                 cod[3] = SEG_NUM[fen/10];                                //数码管分钟十位数段码
  201.                 cod[4] = SEG_NUM[fen%10];                                //分钟的个位
  202.                 cod[5] =SEG_NUM[16];                                        //第二个横杠
  203.        
  204.                 cod[6] = SEG_NUM[miao/10];                                //数码管秒十位数段码
  205.                 cod[7] = SEG_NUM[miao%10];                                //秒的个位
  206.        
  207.                 SEG7_ShowCode(cod);       
  208. }
复制代码
io.h
  1. #ifndef __IO_H
  2. #define __IO_H
  3. #include "config.h"        //调用头文件
  4. //定义引脚名称
  5. #define HC595_SER         P34
  6. #define HC595_RCK         P35
  7. #define HC595_SCK         P32
  8. void Key_Task(void);
  9. //--------------------------------------------------74HC595控制函数声明-----------------------------------------------------
  10. void Init_595(void);
  11. void Send_595( u8 dat );
  12. void Display_Seg( u8 HC595_1,u8 HC595_2);
  13. //void Seg_Task(void);
  14. void TIMECOUNT_Task(void);
  15. void PLED_40(void);
  16. void SEG_PC(void);
  17. void KEY_Task(void);
  18. void Seg_Task_1(void);
  19. void win_effect(void);
  20. #endif
复制代码
taskl.c
  1. #include "task.h"
  2. #include "io.h"
  3. //========================================================================
  4. //                               本地变量声明
  5. //========================================================================
  6. static TASK_COMPONENTS Task_Comps[]=
  7. {
  8. //状态  计数  周期  函数
  9. //        {0, 10,   10,     Key_Task},      /* task 1 Period: 50ms */
  10. //        {0, 1,   1,       Seg_Task},      /* task 1 Period: 1ms */
  11.         {0, 10,   10,   TIMECOUNT_Task},      /* task 1 Period: 1000ms */
  12. //        {0, 1000,   1000,    PLED_40},      /* task 1 Period: 500ms */
  13. //        {0, 1,   1,   SEG_PC},      /* task 1 Period: 1ms */
  14.         {0, 10,     10,   KEY_Task},      /* task 1 Period: 1000ms */
  15.         {0, 1,      1,   Seg_Task_1},      /* task 1 Period: 1ms */
  16.         {0, 500,    200,   win_effect},      /* task 1 Period: 1ms */
  17.        
  18. };
  19. u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]);
  20. //========================================================================
  21. // 函数: Task_Handler_Callback
  22. // 描述: 任务标记回调函数.
  23. // 参数: None.
  24. // 返回: None.
  25. // 版本: V1.0, 2012-10-22
  26. //========================================================================
  27. void Task_Marks_Handler_Callback(void)
  28. {
  29.     u8 i;
  30.     for(i=0; i<Tasks_Max; i++)
  31.     {
  32.         if(Task_Comps[i].TIMCount)      /* If the time is not 0 */
  33.         {
  34.             Task_Comps[i].TIMCount--;   /* Time counter decrement */
  35.             if(Task_Comps[i].TIMCount == 0) /* If time arrives */
  36.             {
  37.                 /*Resume the timer value and try again */
  38.                 Task_Comps[i].TIMCount = Task_Comps[i].TRITime;  
  39.                 Task_Comps[i].Run = 1;      /* The task can be run */
  40.             }
  41.         }
  42.     }
  43. }
  44. //========================================================================
  45. // 函数: Task_Pro_Handler_Callback
  46. // 描述: 任务处理回调函数.
  47. // 参数: None.
  48. // 返回: None.
  49. // 版本: V1.0, 2012-10-22
  50. //========================================================================
  51. void Task_Pro_Handler_Callback(void)
  52. {
  53.     u8 i;
  54.     for(i=0; i<Tasks_Max; i++)
  55.     {
  56.         if(Task_Comps[i].Run) /* If task can be run */
  57.         {
  58.             Task_Comps[i].Run = 0;      /* Flag clear 0 */
  59.             Task_Comps[i].TaskHook();   /* Run task */
  60.         }
  61.     }
  62. }
复制代码
main.c
  1. #include "config.h"
  2. #include "task.h"
  3. #include "io.h"
  4. char *USER_DEVICEDESC = NULL;
  5. char *USER_PRODUCTDESC = NULL;
  6. char *USER_STCISPCMD = "@STCISP#";
  7. //void Delay10ms(void)        //@24.000MHz
  8. //{
  9. //        unsigned long edata i;
  10. //        _nop_();
  11. //        _nop_();
  12. //        i = 119998UL;
  13. //        while (i) i--;
  14. //}       
  15. void main(void)
  16. {
  17.         //int count=1;                                                                        //按键计数变量
  18.    
  19.         Sys_init();                                                                                //系统初始化(调用函数)
  20.         usb_init();                                     //USB CDC 接口配置
  21.        
  22.         IE2 |= 0x80;                                    //使能USB中断
  23.         Timer0_Init();                                                                        //定时器初始化
  24.         Init_595();                                                                        //595端口电平初始化
  25.     EA = 1;                                                                                        //IE |= 0X80;
  26.        
  27.         P40=0;
  28.        
  29.         while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
  30.        
  31.         while(1)
  32.         {
  33.                
  34.         if (bUsbOutReady)                                                        //如果接收到了数据
  35.         {
  36.             //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  37.                
  38.             usb_OUT_done();                                                        //
  39.         }
  40.                 Task_Pro_Handler_Callback();                                //执行函数
  41.                
  42.          }
  43. }
  44. void Timer0_Isr(void) interrupt 1
  45. {
  46.        
  47.         Task_Marks_Handler_Callback();                        //系统计时
  48. }
复制代码





回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 2025-7-29 07:44:07 | 显示全部楼层
10虚拟LED和shu码管

屏幕截图 2025-07-17 072105.png
io.c
  1. #include "io.h"
  2. //u8 State1 = 0;                                        //LED1初始状态
  3. //u8 State2 = 0;                                        //LED2初始状态
  4. //u8 State3 = 0;                                        //LED3初始状态
  5. u16 Key_Vol = 0;                                //按键按下持续时间(几个十秒)
  6. u16 Key_Vol_2 = 0;
  7. //void LED0_Blink(void)
  8. //{
  9. //        State1 = !State1;
  10. //        P20 = State1;
  11. //}
  12. //void LED1_Blink(void)
  13. //{
  14. //        State2 = !State2;
  15. //        P21 = State2;
  16. //}
  17. //void LED2_Blink(void)
  18. //{
  19. //        State3 = !State3;
  20. //        P22 = State3;
  21. //}
  22. u16 KEY1_COUNT = 0;                //P32按钮计数
  23. u16 KEY2_COUNT = 0;         //P33按钮计数
  24. void Key_Task(void)
  25. {
  26. //-------------------P32按钮计数-------------------
  27.                 if( P32 == 0 )
  28.                 {
  29.                         Key_Vol++;
  30.                         if(Key_Vol == 5)
  31.                         {
  32.                                 KEY1_COUNT++;
  33.                         }       
  34.                 }
  35.                 else
  36.                 {
  37.                         Key_Vol = 0;       
  38.                 }
  39. //-------------------P33按钮计数-------------------               
  40.                 if( P33 == 0 )
  41.                 {
  42.                         Key_Vol_2++;
  43.                         if(Key_Vol_2 == 5)
  44.                         {
  45.                                 KEY2_COUNT++;
  46.                         }       
  47.                 }
  48.                 else
  49.                 {
  50.                         Key_Vol_2 = 0;       
  51.                 }
  52. }
  53. //----------------任务1:P2口流水灯,P10闪烁------------------------------------
  54. u8 P2_STATE = 0X01;
  55. u8 P10_STATE = 0;
  56. void TASK_1( void )
  57. {
  58.         LED40_SetPort( 2, ~P2_STATE );                //点亮P20端口
  59.         P2_STATE = (P2_STATE<<1);                        //由低位向高位一位1000 0000->1 0000 0000
  60.         if( P2_STATE == 0 )                                        //P2端口是否是0,
  61.                 P2_STATE = 1;                                        //否则赋值1
  62. //-------------------------P10闪烁------------------------------------
  63.         if( P10_STATE == 0 )
  64.                 LED40_SetBit(1,0);
  65.         else
  66.                 LED40_ClrBit(1,0);
  67.         P10_STATE = !P10_STATE;
  68. }
  69. //任务2:左边数码管显示P32按下次数,右边数码管显示P33按下次数
  70. u32 KEY_Count =0;  
  71. void TASK_2( void )
  72. {
  73.         KEY_Count = KEY1_COUNT * 10000 + KEY2_COUNT;
  74.        
  75.         SEG7_ShowLong( KEY_Count ,10 );
  76. }
  77. //任务3:按下数字按键在数码管显示对应的按键数字!
  78. u32 REC_NUM = 0;
  79. void TASK_3( void )
  80. {
  81.         SEG7_ShowLong( REC_NUM ,10 );
  82. }
复制代码
io.h
  1. #ifndef __IO_H
  2. #define __IO_H
  3. #include "config.h"        //调用头文件
  4. void LED0_Blink(void);
  5. void LED1_Blink(void);
  6. void LED2_Blink(void);
  7. void Key_Task(void);
  8. void TASK_1( void );
  9. void TASK_2( void );
  10. void TASK_3( void );
  11. #endif
复制代码
task.c
  1. #include "task.h"
  2. #include "io.h"
  3. //========================================================================
  4. //                               本地变量声明
  5. //========================================================================
  6. static TASK_COMPONENTS Task_Comps[]=
  7. {
  8. //状态  计数  周期  函数
  9. //        {0, 300,   300,   LED0_Blink},     /* task 1 Period: 300ms */
  10. //        {0, 600,   600,   LED1_Blink},      /* task 1 Period: 600ms */
  11. //        {0, 900,   900,   LED2_Blink},      /* task 1 Period: 900ms */
  12.         {0, 10,   10,   Key_Task},      /* task 1 Period: 50ms */
  13.         {0, 500,   500,   TASK_1},      /* task 1 Period: 500ms */
  14. //        {0, 500,   500,   TASK_2},      /* task 1 Period: 500ms */
  15.         {0, 500,   500,   TASK_3},      /* task 1 Period: 500ms */
  16. };
  17. u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]);
  18. //========================================================================
  19. // 函数: Task_Handler_Callback
  20. // 描述: 任务标记回调函数.
  21. // 参数: None.
  22. // 返回: None.
  23. // 版本: V1.0, 2012-10-22
  24. //========================================================================
  25. void Task_Marks_Handler_Callback(void)
  26. {
  27.     u8 i;
  28.     for(i=0; i<Tasks_Max; i++)
  29.     {
  30.         if(Task_Comps[i].TIMCount)      /* If the time is not 0 */
  31.         {
  32.             Task_Comps[i].TIMCount--;   /* Time counter decrement */
  33.             if(Task_Comps[i].TIMCount == 0) /* If time arrives */
  34.             {
  35.                 /*Resume the timer value and try again */
  36.                 Task_Comps[i].TIMCount = Task_Comps[i].TRITime;  
  37.                 Task_Comps[i].Run = 1;      /* The task can be run */
  38.             }
  39.         }
  40.     }
  41. }
  42. //========================================================================
  43. // 函数: Task_Pro_Handler_Callback
  44. // 描述: 任务处理回调函数.
  45. // 参数: None.
  46. // 返回: None.
  47. // 版本: V1.0, 2012-10-22
  48. //========================================================================
  49. void Task_Pro_Handler_Callback(void)
  50. {
  51.     u8 i;
  52.     for(i=0; i<Tasks_Max; i++)
  53.     {
  54.         if(Task_Comps[i].Run) /* If task can be run */
  55.         {
  56.             Task_Comps[i].Run = 0;      /* Flag clear 0 */
  57.             Task_Comps[i].TaskHook();   /* Run task */
  58.         }
  59.     }
  60. }
复制代码
  1. #include "config.h"
  2. #include "task.h"
  3. #include "io.h"
  4. //u8 State[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  5. //u8 num = 0;
  6. //u8 Run_State = 0;                                //运行状态
  7. //u8 i=0;
  8. ////u16 Count_300 = 0;                                //计数300ms变量
  9. ////u16 Count_600 = 0;                                //计数600ms变量
  10. ////u16 Count_900 = 0;                                //计数900ms变量
  11. //u16        Count_ms[3] = {0,0,0};                        //计时变量数组
  12. //u16 Key_Vol = 0;                                        //按键时长检测
  13. extern u32 REC_NUM;
  14. void Delay10ms(void)        //@24.000MHz
  15. {
  16.         unsigned long edata i;
  17.         _nop_();
  18.         _nop_();
  19.         i = 119998UL;
  20.         while (i) i--;
  21. }       
  22. void main(void)
  23. {
  24.         int count=1;                                                                        //按键计数变量
  25.    
  26.         Sys_init();                                                                                //系统初始化(调用函数)
  27.         usb_init();                                     //USB CDC 接口配置
  28.        
  29.         IE2 |= 0x80;                                    //使能USB中断
  30.         Timer0_Init();                                                                        //定时器初始化
  31.     EA = 1;                                                                                        //IE |= 0X80;
  32.        
  33.        
  34.         while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
  35.        
  36.         while(1)
  37.         {
  38.                
  39.         if (bUsbOutReady)                                                        //如果接收到了数据
  40.         {
  41.             REC_NUM = UsbOutBuffer[5] - 48;
  42.                         //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  43.                
  44.             usb_OUT_done();                                                        //
  45.         }
  46.                 Task_Pro_Handler_Callback();                                //执行函数
  47. //                P2 = ~State[ num ];                //num取值0-7
  48. //                if( P32 == 0 )
  49. //                {
  50. //                        Delay10ms();
  51. //                        if(P32 == 0)
  52. //                        {
  53. //                                while(P32 == 0);
  54. //                                 num ++;
  55. //                                if( num >7)
  56. //                                        num = 0;
  57. //                        }
  58. //                }
  59.                
  60.          }
  61. }
  62. void Timer0_Isr(void) interrupt 1
  63. {
  64.        
  65.         Task_Marks_Handler_Callback();                        //系统计时
  66. ;
  67. }
复制代码

10虚拟LED和shu码管.rar (182.35 KB, 下载次数: 1)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2025-08-06 08:32:51

2

主题

23

回帖

439

积分

中级会员

积分
439
发表于 5 天前 | 显示全部楼层
10.虚拟LED和数码管 课后小练 简易密码箱

屏幕截图 2025-08-02 192950.png
代码文件中密码改成12345670,以下是IO.C的部分代码
  1. //IO.C部分代码
  2. //任务二:简易密码箱
  3. u8 passward[8] = { 20,20,20,20,20,20,20,20};
  4. u8 Seg_no = 0;
  5. void SEG_Task(void)
  6. {
  7.                 u8 num = 0;
  8.         switch(Seg_no){
  9.                 case 0: Display_Seg( SEG_NUM[passward[0]], ~T_NUM[0] );           break;
  10.                 case 1: Display_Seg( SEG_NUM[passward[1]], ~T_NUM[1] );           break;
  11.                 case 2: Display_Seg( SEG_NUM[passward[2]], ~T_NUM[2] );           break;
  12.                 case 3: Display_Seg( SEG_NUM[passward[3]], ~T_NUM[3] );           break;
  13.                 case 4: Display_Seg( SEG_NUM[passward[4]], ~T_NUM[4] );           break;
  14.                 case 5: Display_Seg( SEG_NUM[passward[5]], ~T_NUM[5] );           break;
  15.                 case 6: Display_Seg( SEG_NUM[passward[6]], ~T_NUM[6] );           break;
  16.                 case 7: Display_Seg( SEG_NUM[passward[7]], ~T_NUM[7] );           break;
  17.         }
  18.         Seg_no ++;
  19.         if( Seg_no>7 )
  20.                 Seg_no=0;               
  21. }
  22. u8 Key_Vol3 = 0;                                                //判断按钮是否按下
  23. u8 Key_no = 0;                                                        //数码管位计数
  24. //密码输入显示
  25. void PW_write_Task(void)
  26. {
  27.         if( key_num <0xff )
  28.                 {
  29.                         Key_Vol3 ++;
  30.                         if(Key_Vol3 == 5)                        //是否延时50m秒
  31.                           {
  32.                                 if(Key_no == 0)                        //数码管没有按下时显示“--------”
  33.                                 {
  34.                                         passward[0] = 20;
  35.                                         passward[1] = 20;
  36.                                         passward[2] = 20;
  37.                                         passward[3] = 20;
  38.                                         passward[4] = 20;
  39.                                         passward[5] = 20;
  40.                                         passward[6] = 20;
  41.                                         passward[7] = 20;
  42.                                        
  43.                                 }
  44.                                 passward[Key_no] = key_num; //键值传递
  45.                                 Key_no++;
  46.                                 if( Key_no == 8 )                //密码输入到了八位
  47.                                 {
  48.                                         if((passward[0]==1)&&(passward[1]==2)&&(passward[2]==3)&&(passward[3]==4)&&(passward[4]==5)&&(passward[5]==6)&&(passward[6]==7)&&(passward[7]==0))
  49.                                         {
  50.                                                 //密码正确八位数码管显示为1
  51.                                                 passward[0] = 20;
  52.                                                 passward[1] = 20;
  53.                                                 passward[2] = 17;
  54.                                                 passward[3] = 18;
  55.                                                 passward[4] = 14;
  56.                                                 passward[5] = 16;
  57.                                                 passward[6] = 20;
  58.                                                 passward[7] = 20;
  59.                                                 
  60.                                         }
  61.                                         else                                 //密码输入错误八位数码管显示为空
  62.                                         {
  63.                                                 passward[0] = 20;
  64.                                                 passward[1] = 20;
  65.                                                 passward[2] = 20;
  66.                                                 passward[3] = 20;
  67.                                                 passward[4] = 20;
  68.                                                 passward[5] = 20;
  69.                                                 passward[6] = 20;
  70.                                                 passward[7] = 20;
  71.                                         }                 
  72.                                         Key_no = 0;
  73.                                 }
  74.                                        
  75.                         }        
  76.                 }
  77.                 else
  78.                 {
  79.                         Key_Vol3 = 0;        
  80.                 }
  81. }
复制代码

10.课后小练 密码锁.rar (183.05 KB, 下载次数: 0)
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-8-7 05:31 , Processed in 3.022751 second(s), 103 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表