# 亮灯
# 代码部分
# include<reg52.h>
这个头文件是专用于 51 单片机的 使用了该头文件 便可以直接对单片机的相关寄存器与引脚进行操作 使得单片机开发更加方便
# sbit
sbit 和 bit 一样 都是 C51 扩展的变量类型
经典应用 : sbit LED1 = P1 ^ 0; 意思是定义 LED1 为 P1 口的第一位 以便进行位操作
单看使用的方式和效果 感觉和 #define typedef 的效果差不多 于是就用 #define 和 typedef 试了一下
sbit 实际使用 :

事实上不对 在使用 #define 和 typedef 时编译时出错 查了之后发现根本不是同一个东西
sbit 特殊功能寄存器的一个位的声明,如:sbit LED0=P2^0;
看看,完全没有共同之处吧。
#define 是宏定义,是一个预编译指令。
如 #define PI 3.14 在预编译阶段,会将 PI 替换为 3.14sbit 是 C51 扩展的变量类型
一个在编译期替换,一个在运行期生效
首先,sbit led= P2,这个写法是错误的,虽然编译时不报错,但编译后执行程序时却是错误的。
sbit 是定义一个引脚的,注意,只是定义一个引脚,而 P2 是一个并行口,有 8 个引脚,是不能 sbit 来定义,可以用 sfr 定义。
#define 并不是定义引脚的,也不是定义并行口,只是一个宏替换,就是程序中的 led 换成 P2 后再编译。
所以,sbit 和 #define 根本就不是一回事
关于 #define 和 typedef 的部分大概知道 但是 sbit 的部分不太明白
# int(void) main()
教程视频里面说的是 void main 但是我试了一下 int main 完全没有影响
# intrins.h
这个头文件是用来字符循环移动的
所谓循环移动 就是把整体向左 / 右移动指定位数 高位多出来的添加到末尾
例如 : 1111 1101 通过_ crol _函数可以将字符型数据向左移动 如果移动一位
就变成了 1111 101X 最低位由原来最高位添上 就变为了 1111 1011
# 开始点亮
正式开始的过程中 LED1 = 0; 即可使第一颗 LED 点亮 尝试之后发现
LED1 = 0; 才能使灯点亮 其余的值都不行 (证明这个值需要经过编译器的翻译 不能直接控制电压) 翻译之后有种 bool 类型的感觉
制作流水灯的时候涉及到晶振周期 (又是一个大坑)
晶振具有压电效应,即在晶片两极外加电压后晶体会产生变形,反过来如外力使晶片变形,则两极上金属片又会产生电压。如果给晶片加上适当的交变电压,晶片就会产生谐振(谐振频率与石英斜面倾角等有关系,且频率一定)。晶振利用一种能把电能和机械能相互转化的晶体,在共振的状态下工作可以提供稳定、精确的单频振荡。在通常工作条件下,普通的晶振频率绝对精度可达百万分之五十。利用该特性,晶振可以提供较稳定的脉冲,广泛应用于微芯片的时钟电路里。晶片多为石英半导体材料,外壳用金属封装。
(石英表就是依靠这个原理)
程序在单片机中会循环运行 (循环 int main)
# 流水灯
流水灯中主要依靠软件延时 而软件延时 说白了就是靠程序内部的循环来消耗时间 (单片机执行指令有特定的指令周期 通过对晶振周期的计算 封装好延时函数便可以实现延时效果)
具体代码如下 :
1 |
|
# Tips (在写代码的时候发现了几个 keil 不支持的语法)
不支持 long long int
在 for 语句中无法定义 要在之前定义好
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22/*****不支持这种操作******/
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
;
}
}
/******正确的操作******/
int i,j;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
;
}
}
