32G12K128实验-LED流水灯
本帖最后由 惦饭宝 于 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、掌握按键消抖原理。
三、实验报告撰写(包括流水灯系统的原理图;实验程序;调试过程以及实验心得体会),要求实验报告提交手写纸质版。
四、相关内容
实验原理图:
软件安装教程[冲哥]:
视频教学:《32位8051单片机原理及应用》,一等奖2万, 送实验箱; 冲哥版 - 视频教学,《单片机原理及应用》教学改革及实战技术交流会,本版限制发帖 国芯技术交流网站 - AI32位8051交流社区 (stcaimcu.com)
实验报告一、实验要求 利用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灯原理图
按键原理图:
STC32原理图:
/------------------------------------------------------------------------------------------------------延时函数原理---------------------------------------------------------------------------------------/ //延时函数delay_ms 延时n毫秒
//6000为经验值,使得i = MAIN_Fosc / 6000 = 4000 ,即这一个循环里面i就循环了4000次,大致为1ms的时间。
#define MAIN_Fosc24000000UL //晶振频率 void delay_ms(u16 ms) //unsigned int { u16 i; do { i = MAIN_Fosc/6000; while(--i); }while(--ms); }
/-------------------------------------------------------------------------------------------------------消抖原理-----------------------------------------------------------------------------------------/
因为按键是机械开关所以当机械触点断开、闭合时,由于机械触点的弹性作用,
一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动(电压上下波动)。
对于一个开关来说,整个按键周期中有效的时间大约在50-200ms,即大约10ms的抖动之后就是正常的低电平。
https://www.stcaimcu.com/data/attachment/forum/202409/15/152519pbnblp9aan6iz9ii.jpg
四、实验程序/---------------------------------------------------------------------------------------------------------花式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); // 等待按键释放,防止多次触发按键事件 } }
/---------------------------------------------------------------------------------------------------------完整程序:-----------------------------------------------------------------------------------------/
Ps:实验程序改写自[冲哥]:视频教学:《32位8051单片机原理及应用》,一等奖2万, 送实验箱; 冲哥版 - 视频教学,《单片机原理及应用》教学改革及实战技术交流会,本版限制发帖 国芯技术交流网站 - AI32位8051交流社区 (stcaimcu.com)
注意事项:STC-ISP中晶振频率调为24MHZ,否则LED灯闪烁时间不定,按照下述图片勾选,实现程序自动下载:
五、调试过程
依据视频教程,将STC32G128K实验箱与电脑连接,正确设置STC-ISP下载器,调试程序。
1.根据输出报告,判断错误位置和错误形式:
2.相关LED灯不按照理想方式亮灭:程序出现逻辑错误,梳理逻辑。
3.使用Keil的程序调试功能。 点击Options for Target选项卡
选择Debug选项
勾选Use Simulator
点击该图标或者Ctrl+F5启动调试操作
进入调试窗口
具体调试过程可参考:Keil5软件使用-进阶调试篇_keil调试教程-CSDN博客六、实验心得
本次LED流水灯实验主要涉及单片机GPIO口的控制、移位操作和延时函数的应用。实验过程中,分三种花式实现了流水灯的顺序点亮、熄灭,以及按键交互。这不仅巩固了对单片机基础知识的掌握,也提升了实践操作能力。
首先,通过对GPIO口的控制,实现了对8个LED灯的精确管理。这使得对单片机与外部设备的交互有了更深入的理解。移位操作在实验中扮演了关键角色,直接关系到流水灯的点亮效果。通过移位操作,顺利实现了LED灯从左到右的移动显示,使得灯光效果更具动态性。同时,移位操作的运用也展现了它在计算机科学中的广泛应用,不仅限于此类实验,在数据处理和算法设计中同样重要。
在此过程中,软件延时函数的合理使用起到了至关重要的作用。尽管软件延时的原理较为简单,但在实际开发中,适当的延时设计能够大幅提升程序的用户体验。通过调节延时时间,流水灯的节奏得以更好地呈现,使整个实验效果更加直观。
此外,按键消抖的处理是实验中的一大亮点。由于机械按键的物理特性,在实际操作中不可避免地会出现抖动现象。通过加入按键消抖的处理方法,成功解决了这一问题,确保了系统的稳定性和可靠性。这也提醒在实际硬件开发中,硬件的物理特性对软件设计有着重要影响,需要软硬件结合来提高系统的性能。
调试阶段是整个实验的关键环节。借助Keil调试工具,进行了多次调试,逐步找出并修正了程序中的逻辑错误。通过对输出结果的分析,明确了问题所在,积累了调试程序的经验。这个过程也让体会到,理论知识与实践操作的结合是提高编程能力的关键。最终,实验顺利完成,对单片机与硬件外设的互动有了更全面的认识,增强了对单片机编程和调试的信心。
这个32G12K128实验-LED流水灯如何间歇同时赋值予全部(P0-P7)呢?间歇时间取多少比较合适? 白水大虾2016 发表于 2024-9-22 10:07
这个32G12K128实验-LED流水灯如何间歇同时赋值予全部(P0-P7)呢?间歇时间取多少比较合适? ...
我猜你可能是要实现每一次闪烁,都有不同的LED灯亮起,而不是示例中的用移位符来有规律的让LED闪烁?
如果你的指的是某个端口的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看上去都行,重要的是你自己觉得时间多少合适吧🤔
{:4_174:} 惦饭宝 发表于 2024-9-22 17:47
我猜你可能是要实现每一次闪烁,都有不同的LED灯亮起,而不是示例中的用移位符来有规律的让LED闪烁?
如果 ...
我就是想要P0到P7的8个端口全部赋值,同时赋值于P0到P7的8个端口行不行?也就是说P0到P7的8个端口各自的8个灯同时熄灭同时点亮同时流水。谢谢您及时解答! 思路、流程清晰,堪称SOP 写的真清晰啊, soma 发表于 2024-9-22 22:07
写的真清晰啊,
哇,大佬! 写的非常好,范例 向大佬学习
页:
[1]