找回密码
 立即注册
查看: 1387|回复: 9

32G12K128实验-LED流水灯

[复制链接]
  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2024-10-23 17:26:58

5

主题

19

回帖

209

积分

中级会员

积分
209
发表于 2024-9-15 22:31:41 | 显示全部楼层 |阅读模式
本帖最后由 惦饭宝 于 2024-10-4 08:59 编辑

                                                                                         实验一 LED流水灯
一、实验要求
利用STC32G12K128实验箱,制作一个单片机控制的流水灯系统。参考实验箱原理图,通过控制单片机的P4.0和P6端口,花式点亮8个发光二极管。

花式1:流水灯从左至右,间隔1秒依次点亮,8盏灯全亮1秒后,全部熄灭,再过1秒后,重复上述过程。

花式2:流水灯从左至右,间隔1秒依次点亮,8盏灯全亮1秒后,从右至左间隔1秒,依次熄灭,全灭后,再过1秒后,重复上述过程。

花式3:按键点灯;要求首次按下按键SW17,点亮最左边的一盏灯(没按按键前,所有灯全灭),并通过USB-CDC/串口助手显示信息“第1轮按键按下”。
第二次按下按键SW17,点亮左边第2盏灯,同时熄灭左边第一盏灯(保持每次按键按下,只亮一盏灯),并通过USB-CDC/串口助手显示信息“第2轮按键按下”。
重复上述按键动作,直到右边第一盏灯点亮后,USB-CDC/串口助手显示信息“第8轮按键按下”。再次按下按键sw17,重复上述过程。

二、实验目的
1、掌握单片机GPIO口的使用。
2、掌握移位和软件延时程序的编写。
3、掌握按键消抖原理。

三、实验报告撰写
(包括流水灯系统的原理图;实验程序;调试过程以及实验心得体会),要求实验报告提交手写纸质版。

四、相关内容

实验原理图:

stc32g实验箱原理图.pdf (374.9 KB, 下载次数: 61)

软件安装教程[冲哥]:



                                                   实验报告
一、实验要求
    利用STC32G12K128实验箱,制作一个单片机控制的流水灯系统。参考实验箱原理图,通过控制单片机的P4.0和P6端口,花式点亮8个发光二极管。
      花式1:流水灯从左至右,间隔1秒依次点亮,8盏灯全亮1秒后,全部熄灭,再过1秒后,重复上述过程。
      花式2:流水灯从左至右,间隔1秒依次点亮,8盏灯全亮1秒后,从右至左间隔1秒,依次熄灭,全灭后,再过1秒后,重复上述过程。
      花式3:按键点灯;要求首次按下按键SW17,点亮最左边的一盏灯(没按按键前,所有灯全灭),并通过USB-CDC/串口助手显示信息“第1轮按键按下”。
    第二次按下按键SW17,点亮左边第2盏灯,同时熄灭左边第一盏灯(保持每次按键按下,只亮一盏灯),并通过USB-CDC/串口助手显示信息“第2轮按键按下”。
    重复上述按键动作,直到右边第一盏灯点亮后,USB-CDC/串口助手显示信息“第8轮按键按下”。再次按下按键sw17,重复上述过程。

二、实验目的
    1、掌握单片机GPIO口的使用。
    2、掌握移位和软件延时程序的编写。
    3、掌握按键消抖原理.

三、实验原理
/-------------------------------------------------------------------------------------------------------流水灯原理图--------------------------------------------------------------------------------------/
LED灯原理图
截图202409151923066968.jpg

按键原理图:

    截图202409151926115274.jpg

STC32原理图:

截图202409151937434543.jpg

/------------------------------------------------------------------------------------------------------延时函数原理---------------------------------------------------------------------------------------/
   
      //延时函数delay_ms 延时n毫秒
      //6000为经验值,使得i = MAIN_Fosc / 6000 = 4000 ,即这一个循环里面i就循环了4000次,大致为1ms的时间。

      #define MAIN_Fosc  24000000UL //晶振频率
      void delay_ms(u16 ms)        //unsigned int
       {
          u16 i;
          do
          {
                i = MAIN_Fosc/6000;
                while(--i);
          }while(--ms);
         }
/-------------------------------------------------------------------------------------------------------消抖原理-----------------------------------------------------------------------------------------/

    因为按键是机械开关所以当机械触点断开、闭合时,由于机械触点的弹性作用,
    一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动(电压上下波动)。
    对于一个开关来说,整个按键周期中有效的时间大约在50-200ms,即大约10ms的抖动之后就是正常的低电平。

   

、实验程序
/---------------------------------------------------------------------------------------------------------花式1:-----------------------------------------------------------------------------------------/

                                                LED_Data = ((LED_Data >> 1)|0x80);                //先计算后输出P6 ,LED_Data右移一位,使得LED显示往右移动,然后在最高位加1,点亮最左边的LED灯            

                                                if( LED_Data == 0XFF )                            // 检查LED_Data是否等于0xFF,即所有LED灯都被点亮
                                                  LED_Data = 0x7F;                                // 如果是,重置LED_Data为0x7F,只保留最高位点亮                                                                                       

                                                P6 = LED_Data;                                    // 将LED_Data的值输出到P6端口,更新LED的状态

                                                delay_ms(1000);                                   // 延时1000ms

/--------------------------------------------------------------------------------------------------------花式2:------------------------------------------------------------------------------------------/

                                                delay_ms(1000);                                  // 延时1000ms
                                                LED_Data = ((LED_Data >> 1)|0x80);                //先计算后输出P6 ,LED_Data右移一位,使得LED显示往右移动,然后在最高位加1,点亮最左边的LED灯             
                                                if( LED_Data == 0XFF )                            // 检查LED_Data是否等于0xFF,即所有LED灯都被点亮
                                                {
                                                        LED_Data = 0XFE;                        
                                                        while( LED_Data != 0XFF )
                                                        {
                                                                LED_Data = ( (LED_Data<<1) +1 );              //向左移位                                        
                                                                P6 = LED_Data;                                // 将LED_Data的值输出到P6端口,更新LED的状态                                                        
                                                                delay_ms(1000);                               // 延时1000ms                                                        
                                                        }
                                                        LED_Data = 0x7F;                        
                                                }
                                                P6 = LED_Data;                                    // 将LED_Data的值输出到P6端口,更新LED的状态        

/---------------------------------------------------------------------------------------------------------花式3:-----------------------------------------------------------------------------------------/

                                                if (KEY1 == 0)                                        // 判断按键有没有按下
                                                {
                                                        delay_ms(10);                                     // 消抖,等待10毫秒
                                                        if (KEY1 == 0)                                    // 再次判断按键是否仍然被按下,确保按键按下有效
                                                        {
                                                                i++;                                          // 增加按键计数
                                                                if (i > 8)                                    // 当超过8次按键后,重置
                                                                 i = 1;
                                                                LED_Data = ~(0x80 >> (i - 1));                // 每次点亮一个灯
                                                                P6 = LED_Data;                                // 更新LED状态
                                                                printf("第%d轮按键按下\r", i);                // 打印消息到串口
                                                                while (KEY1 == 0);                            // 等待按键释放,防止多次触发按键事件
                                                        }
                                                }

/---------------------------------------------------------------------------------------------------------完整程序-----------------------------------------------------------------------------------------/

    截图202409160751532523.jpg

实验一 LED流水灯.zip (114.63 KB, 下载次数: 60)

Ps:实验程序改写自[冲哥]:

注意事项:STC-ISP中晶振频率调为24MHZ,否则LED灯闪烁时间不定,按照下述图片勾选,实现程序自动下载:

截图202409160901134009.jpg

五、调试过程

依据视频教程,将STC32G128K实验箱与电脑连接,正确设置STC-ISP下载器,调试程序

1.根据输出报告,判断错误位置和错误形式:
截图202409160831373311.jpg

2.相关LED灯不按照理想方式亮灭:程序出现逻辑错误,梳理逻辑。

3.使用Keil的程序调试功能。
    点击Options for Target选项卡 截图202409160837185199.jpg

    选择Debug选项
    截图202409160838505290.jpg

    勾选Use Simulator
    截图202409160838191959.jpg

   点击该图标 截图202409160839534353.jpg 或者Ctrl+F5启动调试操作

   进入调试窗口
    截图202409160842239385.jpg
    截图202409160846149233.jpg

六、实验心得
  本次LED流水灯实验主要涉及单片机GPIO口的控制、移位操作和延时函数的应用。实验过程中,分三种花式实现了流水灯的顺序点亮、熄灭,以及按键交互。这不仅巩固了对单片机基础知识的掌握,也提升了实践操作能力。
  首先,通过对GPIO口的控制,实现了对8个LED灯的精确管理。这使得对单片机与外部设备的交互有了更深入的理解。移位操作在实验中扮演了关键角色,直接关系到流水灯的点亮效果。通过移位操作,顺利实现了LED灯从左到右的移动显示,使得灯光效果更具动态性。同时,移位操作的运用也展现了它在计算机科学中的广泛应用,不仅限于此类实验,在数据处理和算法设计中同样重要。
在此过程中,软件延时函数的合理使用起到了至关重要的作用。尽管软件延时的原理较为简单,但在实际开发中,适当的延时设计能够大幅提升程序的用户体验。通过调节延时时间,流水灯的节奏得以更好地呈现,使整个实验效果更加直观。
  此外,按键消抖的处理是实验中的一大亮点。由于机械按键的物理特性,在实际操作中不可避免地会出现抖动现象。通过加入按键消抖的处理方法,成功解决了这一问题,确保了系统的稳定性和可靠性。这也提醒在实际硬件开发中,硬件的物理特性对软件设计有着重要影响,需要软硬件结合来提高系统的性能。
  调试阶段是整个实验的关键环节。借助Keil调试工具,进行了多次调试,逐步找出并修正了程序中的逻辑错误。通过对输出结果的分析,明确了问题所在,积累了调试程序的经验。这个过程也让体会到,理论知识与实践操作的结合是提高编程能力的关键。最终,实验顺利完成,对单片机与硬件外设的互动有了更全面的认识,增强了对单片机编程和调试的信心。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:220
  • 最近打卡:2025-05-08 11:47:57

6

主题

220

回帖

370

积分

中级会员

积分
370
发表于 2024-9-22 10:07:47 | 显示全部楼层
这个32G12K128实验-LED流水灯如何间歇同时赋值予全部(P0-P7)呢?间歇时间取多少比较合适?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2024-10-23 17:26:58

5

主题

19

回帖

209

积分

中级会员

积分
209
发表于 2024-9-22 17:47:30 | 显示全部楼层
白水大*** 发表于 2024-9-22 10:07
这个32G12K128实验-LED流水灯如何间歇同时赋值予全部(P0-P7)呢?间歇时间取多少比较合适? ...

我猜你可能是要实现每一次闪烁,都有不同的LED灯亮起,而不是示例中的用移位符来有规律的让LED闪烁?
如果你的 截图202409221731138203.jpg 指的是某个端口的8个位,

这样的话我觉得直接让你想要的端口等于0Xxx就行,定义一个数组来保存流水灯状态,然后用一个循环来让P0端口不断改变。
// 定义流水灯状态数组
unsigned char led_states[] = {0xAA, 0xAF, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6}; // 这里根据实际需求修改状态值
unsigned char i = 0;

void main() {

    while (1) {
        for (i = 0; i <(你设定的状态个数); i++) {
            P0 = led_states;  // 设置P0端口的状态
            Delay(500);     
        }
    }
}

如果你想要的是所有的P0-P7,8个端口都赋值。
额我不知道这样可不可以,因为我发现P5的端口中P5^6和P5^7是没有寄存器的,而且全部这些io口全都用来接LED灯的话......
还是有点思路的,你也是定义一个函数,把所有的端口都在里面统一赋值

void SetAllIOPorts(unsigned char value) {
    P0 = value;
    P1 = value;
    P2 = value;
    P3 = value;
    P4 = value;
    P5 = value;
    P6 = value;
    P7 = value;
}

void main() {
    while(1) {
        SetAllIOPorts(0xFF); // 将所有端口的所有引脚置高电平,点亮所有LED
        Delay(500);      //延时500ms
    }
}

至于间歇时间我觉得这个你得自己去试试,延时1000ms或者500ms看上去都行,重要的是你自己觉得时间多少合适吧🤔

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:510
  • 最近打卡:2025-05-09 00:40:40
已绑定手机

1

主题

836

回帖

1529

积分

金牌会员

积分
1529
发表于 2024-9-22 18:39:25 | 显示全部楼层
靡不有初,鲜克有终
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:220
  • 最近打卡:2025-05-08 11:47:57

6

主题

220

回帖

370

积分

中级会员

积分
370
发表于 2024-9-22 19:26:12 | 显示全部楼层
惦*** 发表于 2024-9-22 17:47
我猜你可能是要实现每一次闪烁,都有不同的LED灯亮起,而不是示例中的用移位符来有规律的让LED闪烁?
如果 ...

我就是想要P0到P7的8个端口全部赋值,同时赋值于P0到P7的8个端口行不行?也就是说P0到P7的8个端口各自的8个灯同时熄灭同时点亮同时流水。谢谢您及时解答!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:181
  • 最近打卡:2025-04-03 11:26:38

4

主题

138

回帖

631

积分

高级会员

积分
631
发表于 2024-9-22 19:58:44 | 显示全部楼层
思路、流程清晰,堪称SOP
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:430
  • 最近打卡:2025-05-09 08:24:27
已绑定手机

19

主题

3196

回帖

4960

积分

论坛元老

积分
4960
发表于 2024-9-22 22:07:48 | 显示全部楼层
写的真清晰啊,
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2024-10-23 17:26:58

5

主题

19

回帖

209

积分

中级会员

积分
209
发表于 2024-9-23 07:54:05 | 显示全部楼层
so*** 发表于 2024-9-22 22:07
写的真清晰啊,

哇,大佬!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:25
  • 最近打卡:2024-09-24 08:48:14

1

主题

84

回帖

273

积分

中级会员

积分
273
发表于 2024-9-23 14:08:02 | 显示全部楼层
写的非常好,范例
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:24
  • 最近打卡:2025-04-25 23:25:07

0

主题

21

回帖

170

积分

注册会员

积分
170
发表于 2024-9-23 16:43:56 | 显示全部楼层
向大佬学习
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-9 09:45 , Processed in 0.136056 second(s), 124 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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