- 打卡等级:偶尔看看III
- 打卡总天数:41
- 最近打卡:2024-11-09 21:53:17
中级会员
- 积分
- 450
|
// 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秒,注释我懒的写进去了。但是要知道这个间隔是怎呢来的
这对于新人非常有帮助,我就多说了两句,程序不多,注释一堆,理解过程和思路才是最重要的,
如有注释错误请多包涵,我也是新人。
*/
}
}
}
|
|