找回密码
 立即注册
查看: 888|回复: 3

新人报道4,for循环实现LED灯一次亮灭带注释

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:41
  • 最近打卡:2024-11-09 21:53:17

6

主题

6

回帖

450

积分

中级会员

积分
450
发表于 2023-9-20 00:18:27 | 显示全部楼层 |阅读模式
//  STC官方论坛ID:神自不凡,UID: 4147原创编写,新人学习用带注释,我尽量写注释。2023.09.20
//  新人抄写100次程序,不如自己写1次,分析过程思路来的实在。看懂代码就是看懂运行的过程以及结果。
//  注释有助于新人学习,我也在学习中,望大家共同努力。
/*程序结果:使用STC32G12K128单片机P7口接8个LED灯负极,正极接限流电阻470欧到5V
  依次间隔1S点亮LED灯LED1开始直到8个全点亮,之后逐个熄灭,如此循环。
        (循环间隔会有1.5S间隔)如需循环间隔1s参考我写的用数组法的程序 */
//  LED引脚定义:P70=LED1,P71=LED2,P72=LED3,P73=LED4,P74=LED5,P75=LED6,P76=LED7,P77=LED8
//  低电平每隔0.5秒点亮一个LED灯,直到8灯全量之后,每隔0.5秒依次熄灭一个LED灯直到全灭,等待1.5S后开始重复执行
//  下载程序务必设置IRC时钟为35Mhz,不然运行时间间隔不对。

#include <STC32G.H>
#define MAIN_Fosc  35000000UL                //定义主频 35MHz,请按实际频率修改(用于delay函数自适应主频)
typedef unsigned char u8;                                //unsigned char                 类型用 u8 表示
typedef unsigned int u16;                                //unsigned int                  类型用 u16表示
typedef unsigned long int u32;        //unsigned long int 类型用 u32表示

void  delayms(u16 ms)                //简单延时函数,自适应主频,1毫秒*ms
{
        u16 i;
        do{
                        i = MAIN_Fosc / 6000;
                        while(--i);
                }while(--ms);
}
void main()
{
        u8 j;        //用于选择需要点亮的LED

        WTST = 0;        //设置等待时间为0个时钟,CPU运行速度最快

        P7M1 = 0x00;
        P7M0 = 0x00;                //设置P7口为准双向口模式
        //00:准双向口
        //01:推挽输出
        //10:高阻输入
        //11:开漏输出
        while(1)            //设置循环运行
        {
  for(j=0;j<9;j++)   //实现左移
                {
                        P7 = 0xFF;     //程序开始LED全灭,初始值,没有这句你会发现灯乱跳。
      delayms(500);  //灭时间0.5秒                       
                        P7 = (P7 << j); //看注释说明
                  delayms(500); //亮时间0.5秒
                }       
/*
    P7口按需求接线和设置P7为高电平,也就是P7 = 1111 1111 .               
    假设状态LED=1 就是亮, LED=0 就是灭。
    赋予初值P7=0xFF (1111 1111) 等待0.5秒。也就是每次灭0.5秒                       
    j=9 才会8个LED全亮,j=8 你会发现LED8不亮灯。
    当j=0,判断条件j<9成立,执行左移零位得 P7=1111 1111则LED全灭,等待0.5秒 在执行 j自加得到j=1
                  j=1,判断条件j<9成立,执行左移一位得 P7=1111 1110则LED1=1,等待0.5秒 在执行 j自加得到j=2
                  j=2,判断条件j<9成立,执行左移二位得 P7=1111 1110则LED1,2=1,等待0.5秒 在执行 j自加得到j=3
       .
       .  
       .               
                  j=7,判断条件j<9成立,执行左移七位得 P7=1000 0000则LED1,2,3,4,5,6,7=1,等待0.5秒 在执行 j自加得到j=8
      j=8,判断条件j<9成立,执行左移八位得 P7=0000 0000则LED1,2,3,4,5,6,7,8=1,等待0.5秒 在执行 j自加得到j=9
                  j=9,判断条件j<9不成立,退出这个for循环。
    假如缺少代码41行P7 = 0xFF(1111 1111)你运行会发现LED1=1,LED1,2,3=1, LED1,2,3,4,5,6,=1
直到8灯全量然后等几秒才会退出这个for循环,
分析;运行到j=1, 左移一次自动补零,得P7=1111 1110 这个值又是赋给P7的,现象就是LED1=1
      运行到j=2, 左移两位自动补零,P7初值为1111 1110 左移2位得P7=1111 1000,现象就是LED1,2,3=1
      运行到j=3, 左移三位自动补零,P7初值为1111 1000 左移3位得P7=1100 0000,LED1,2,3,4,5,6,=1
                  运行到j=4, 左移四位自动补零,P7初值为1100 0000 左移4位得P7=0000 0000,LED1,2,3,4,5,6,7,8=1
                  运行到j=5, 左移五位自动补零,P7初值为0000 0000 左移5位得P7=0000 0000,LED1,2,3,4,5,6,7,8=1
      运行到j=4就8灯全亮了,               
                  直到运行到j=9, 退出这个for循环,这时8灯已经全量了几秒钟了。
      有代码41行P7 = 0XFF 才会依次点亮,每个左移都是用这个初值来移动
*/
   for(j=7;j>0;j--)  //实现右移
                {
                        P7 = 0xFF;      /*这条必须要,第一个for循环运行完毕,得到P7=0000 0000,
                                         无论怎移动都是8灯一直全量等几秒退出这个for循环*/
      delayms(500);                        
                        P7 =(P7 << j); ////看注释说明
                  delayms(500); //间隔时间500ms,需要其他时间自行更改
/*  赋予初值P7=0xFF (1111 1111) 等待0.5秒。也就是每次灭0.5秒       
                j=8 发现8个LED又闪亮一次,上一个for循环已经闪亮过一次了,所以选择j=7
    当j=7,判断条件j>0成立,执行左移七位得 P7=1000 0000则LED1,2,3,4,5,6,7=1,等待0.5秒 在执行 j自减得到j=6
      j=6,判断条件j>0成立,执行左移六位得 P7=1100 0000则LED1,2,3,4,5,6,=1,等待0.5秒 在执行 j自减得到j=5
                  j=5,判断条件j>0成立,执行左移五位得 P7=1110 0000则LED1,2,3,4,5,=1,等待0.5秒 在执行 j自减得到j=4       
                        .
                        .
                        .
                        j=2,判断条件j>0成立,执行左移两位得 P7=1111 1100则LED1,2,=1,等待0.5秒 在执行 j自减得到j=1       
                        j=1,判断条件j>0成立,执行左移一位得 P7=1111 1110则LED1,=1,等待0.5秒 在执行 j自减得到j=0       
                        j=0,判断条件j>0不成立,退出这个for循环,退出这个for循环时在j=1用了0.5秒,程序75行又用了0.5秒
                        又从while(1)开始巡行程序42行又用了0.5秒,所以程序运行的间隔是1.5秒就是这样来的。
                        每次LED灯都会保持0.5秒亮用延时函数熄灭0.5秒,注释我懒的写进去了。但是要知道这个间隔是怎呢来的
                        这对于新人非常有帮助,我就多说了两句,程序不多,注释一堆,理解过程和思路才是最重要的,
                        如有注释错误请多包涵,我也是新人。
*/
                }                               
        }       
}


VID_20230920_001244.mp4

49.03 MB, 下载次数: 57

4.for逐渐亮灭流水灯.rar

32.5 KB, 下载次数: 54

回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2023-12-05 19:37:53

3

主题

324

回帖

363

积分

禁止发言

积分
363
发表于 2023-9-24 02:03:09 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:41
  • 最近打卡:2024-11-09 21:53:17

6

主题

6

回帖

450

积分

中级会员

积分
450
发表于 2023-10-1 15:39:46 | 显示全部楼层
WangC*** 发表于 2023-9-24 02:03
哈哈 你还自己焊接了个板子

个人申请官方的发板子太难了,随便改了一个直接接外设就好了,我也不想啊
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15630
发表于 2023-10-4 09:52:24 | 显示全部楼层

自己焊接,用 DIP40 + USB-TypeA 插座比较方便
截图202310040950233152.jpg


截图202310040951512200.jpg


截图202310040952181637.jpg


截图202310040953332187.jpg

截图202310040953592053.jpg

回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 20:39 , Processed in 0.125295 second(s), 67 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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