5

强者的回首--时钟心脏

 2 years ago
source link: https://blog.csdn.net/diandengren/article/details/120591282
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.



联动文章真正的数码管.

什么是单片机?玩的就是时间!(首篇)

单片机的心脏就是时钟

image-20210930092936969

完成老师给的第一个任务 :

第1 个灯: 亮 1s 、 灭 1s 、 亮 1s 、 灭 1s ,循环 。
第2 个灯: 亮 2s 、 灭 2s 、 亮 2s 、 灭 2s ,循环 。
第3 个灯: 亮 4s 、 灭 4s 、 亮 4s 、 灭 4s ,循环。
那么,最笨的方法是,以1 秒时间为延迟时间,分步控制每个 LED

你是强者,自己领域的强者,所以用最有效的方法,上面的方法和暴力求解法又有上面区别呢?题目一变就推到重来所以这种做法永远都是高校学生做法,毫无两点(我说的是没有追求的高校学生)

把任务改成如下:

第1 个灯: 亮 2ms、 、 灭 2ms、 、 亮 2ms、 、 灭 2ms ,循环 。
第2 个灯: 亮 7ms、 、 灭 7ms、 、 亮 7ms、 、 灭 7ms ,循环 。
第3 个灯: 亮 97ms 、 灭 97ms 、 亮 97ms 、 灭 97ms, , 循环 。
这样的任务,不用定时器, 又该怎么写?

硬件没有三个灯只有两个灯,见谅

image-20210930151534888

image-20210930154707010

采集是很耗时间的但是这个时间间隔肉眼看不出来在闪,一直都是亮的

但是你可以通过光晕感觉到他在闪

STC15_LED.c

#include <STC15.h>
#include "all.h"
sbit LED1 = P3^2;
sbit LED2 = P3^3;

void main()
{
	static u16 count = 0;//静态计数器
	P3M1 = 0;
	P3M0 = 0;//设置IO口模式标准IO口
	while(1)
     {
		count++;
		if(count % 110 == 0)//亮2ms灭2ms
		{
			LED1 =~ LED1; 
		}
		if(count % 375 == 0)//亮7ms灭7ms
		{
			LED2 =~ LED2; 
			count = count%8250;//把范围卡死在0-8250
		}
	}
}

all.h

#include<STC15.h>

typedef unsigned char     u8;
typedef unsigned short    u16;
typedef unsigned long     u32;

传统的无规则编程

1 、所有的代码都写在一个文件。
2 、动不动就是 delay 、 while 死等。
3 、函数与函数之间交错调用。
4 、浪费中断资源来弥补上面的问题!
5 、程序执行效率极低。
6 、程序移植性很低,代码可阅读性极差!

强者上面的不要看了,回首上面无规则,感慨一下就行了

传统的模块化编程:

1、每个电路模块单独文件写代码, 需要则包含。
2、用定时器时间来分配任务时间。
3、文件与文件之间函数允许互相调用。
4、各模块之间的数据 互相调用。
5、没有严格规范代码书写要求,可阅读性不高。
6、程序效率较高,程序可移植性较高。
缺点:管理上还是有点乱

强者的国度,一般高校学生能到这里已经不错了,最起码思考了,我见过最搞笑的是有的老师永远都是无规则编程

框架式编程

1、每个电路模块单独文件写代码, 全部互相包含。
2、定时器或者 CPU 来分配任务时间。
3、文件分层、同级之间要求不能调用函数。
4、主文件负责各子文件缓存数据的交互。
5、规范代码书写要求,全部一个格式。方便阅读!
6、程序效率非常高,让整个开发板都能协调运行!
7、某个硬件工作不正常 不能影响 其他硬件。
8、函数和数据可以分开控制,不受时间约束

我没到这一步,这一步是经验与摸索,基本都是工作几年的人自己的武器,我不属于这里,但不代表我不向往

image-20210930203255413

image-20210930203728019

单片机的“看门狗”功能

在单片机项目里面,我们为了防止单片机程序跑飞,同时也为了避免我们写出“死等”的低效率代码,借助看门狗复位就可以及时发现问题

遇到单片机程序跑飞的概率,比买彩票中500万概率还低,无法做实验模拟,只能软件模拟超时

看门狗的寄存器配置(STC-ISP也可以修改)

1.计算好看门狗定时时间,确定分频系数值

2.软件或者硬件配置寄存器,看门狗开计时

3.在定时器溢出之前,把看门狗计数器清零(喂狗)

4.下载程序到单片机里面,再让开发板复位一次

5.模拟出不能及时“喂狗”的情况

特别注意:如果软件设置了分频系数,ISP硬件设置无效

image-20211002144916853

image-20211002144938063

实际上闪烁很快的,可能是我制作gif的时候掉帧了,马上演示一个看门狗溢出的样例

image-20211002152726883

溢出样例一看也在疯狂重启

//看门狗
void WDT_CONTR_Allot()
{
	static xdata u16 count = 0;
	count++;
	if(count>1000)
	{		
		LED2 = ~LED2;
		count = 0;//超过1000计数器清零
		WDT_CONTR=0x34;	//启动看门狗和喂狗
	}
}

image-20211002161108722

单片机的掉电定时唤醒功能

单片机的掉电唤醒专用定时器:WKTCH ,WKTCL

1.调电停机唤醒专用15位定时器:WKTCH(高七位),WKTCL(低8位)

2.先配置该寄存器,需要减去1,最大值是32768-1

3.该寄存器最高位置1,该掉电停机唤醒定时器允许

4,掉电时间image-20211001130748397

5.后把寄存器PCON第一位PD置1,单片机进入掉电模式

6.进入掉电模式,唤醒定时器马上启动

7.唤醒之后,单片机执行掉电时刻的下一条指令

image-20211002164610281

image-20211002165809801

image-20211002203529919

image-20211002205200456

void main()
{
	u16 count = 0;
	SN74LS244_IO_Mode();
	P3M1 = 0;
	P3M0 = 0;
	count = 500;
	while(count--)
	{
		LED2 = ~LED2;
	}		
	WKTCH = 0xc4;//掉电唤醒定时器高字节
	WKTCL = 0x72;//掉电唤醒定时器低字节
	PCON |= 0x02;
	count = 500;
	while(count--)
	{
		LED2 = ~LED2;
	}
	while(1)
    {
		SMG_Allot();
		WDT_CONTR_Allot();
	}
}

联动文章真正的数码管.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK