一、STC89C52单片机
位数:8位
RAM(随机存储器):512B字节
ROM(只读存储器):8K
工作频率:12MHz(本开发板使用)
1.1 STC89C52系列单片机最小应用系统
1.2 开发板
1.3 常用元器件对应缩写
1.电阻:RES
2.电容:CAP(极性电容: CAP-ELEC)
3.晶振:CRYSTAL
4.按键: BUTTON
5.开关:SWITCH
6.排阻:RESPACK
7.发光二极管(LED):LED-BIBY
8.二极管: DIODE
9.三极管:PNP/NPN
10.蜂鸣器:BUZZER(active为有源蜂鸣器)
11.超声波传感器:HCSR04
12.直流电机:MOTOR-DC
13.单片机:AT89C51/AT89C52/STM32XX
14.LCD1602:LM016L
15.OLED屏:OLED12864I2C
16.滑动变阻器:POT(-HG为1%精度,-LIN/-LOG精度为10%)
17.继电器:RELAY
18.LED数码管:CC是共阴管,CA是共阳管
1.4 进制转换
1.5 数据类型
1.6 独立按键
按键默认高电平(1),按下去为低电平(0)
1.6.1 独立按键消抖
#include <REGX52.H>
/*
每按下一次,LED的状态取反
按键的消抖
检测松手
*/
// 延时函数
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
}while (--i);
xms--;
}
}
// 主函数
void main()
{
while(1)
{
if(P3_0 == 0)
{
Delay(20);
while(P3_0 == 0);//检测松手
Delay(20);
P2_0 = ~ P2_0;//默认高电平1,取反为低电平0,按键按下取反,LED灯反复亮灭
}
}
}
1.6.2 独立按键二进制
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
}while (--i);
xms--;
}
}
void main()
{
unsigned char LEDNum = 0;
while(1)
{
if(P3_0==0)
{
//消抖
Delay(20);
while(P3_0==0);//检测松手
Delay(20);
/*
0000 0001 ~(取反) 1111 1110
0000 0010 ~(取反) 1111 1101
0000 0011 ~(取反) 1111 1100
最后LED灯的亮灭顺序是二进制顺序
*/
LEDNum++;
P2 = ~LEDNum;
}
}
}
1.6.3 独立按键位移
#include <REGX52.H>
void Delay(unsigned int xms);
unsigned char LEDNum;
//主函数
void main()
{
P2 = ~0x01;
while(1)
{
//K1按键
if(P3_0 == 0)
{
Delay(20);
while(P3_0 == 0);
Delay(20);
//P2_0 = ~P2_0;//默认高电平1,取反为低电平0,按键按下取反,LED灯反复亮灭
//P2 = ~(LEDNum++);//二进制
/*
0000 0001 <<0 0000 0001
0000 0001 <<1 0000 0010
0000 0001 <<2 0000 0100
0000 0001 <<3 0000 1000
0000 0001 <<4 0001 0000
0000 0001 <<5 0010 0000
0000 0001 <<6 0100 0000
0000 0001 <<7 1000 0000
0000 0001 <<8 0000 0001
*/
LEDNum++;//1
if(LEDNum >= 8)//3
{
LEDNum = 0;
}
P2 = ~(0x01<<LEDNum);//2
}
//K2按键
if(P3_1 == 0)
{
Delay(20);
while(P3_1 == 0);
Delay(20);
/*
初始值为0,0-1会溢出,变成255,所以执行以下判断
如果LEDNum==0时,让LEDNum==7
*/
if(LEDNum == 0)
{
LEDNum = 7;
}else
{
LEDNum--;
}
P2 = ~(0x01<<LEDNum);
}
}
}
//延时函数
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
1.7 数据运算
按位左移:高位移出去,地位补0
例:0011 1100 <<1(按位左移1位) ----> 0111 1000
例:0011 1100 >>2(按位右移2位) ----> 0000 1111
按位异或(^):相同为0;相异为1
1.8 C语言基本语句
1.8.1 基本语句
1.8.2 数组
定义:把相同类型的一系列数据统一编制到某一个组别中,可以通过数组名+索引号简单快捷的操作大量数据。
int x[3]; // 定义一组变量(3个)
int x[]={1,2,3}; // 定义一组变量并初始化
x[0] // 引用数组的第0个变量
x[1] // 引用数组的第1个变量
x[2] // 引用数组的第2个变量
1.8.2 子函数
定义:将完成某一种功能的程序代码单独抽取出来形成一个模块,在其他函数中可随时调用此模块,以达到代码的复用和优化程序结构的目的。
void Function(unsigned char a)
{
}
返回值 函数名 (形参)
{
函数体
}
1.9 数码管
位选:控制哪一个数码管亮
段选:控制数码管显示的内容
(74LS138)138译码器、74HC245芯片驱动数码管
74LS138 芯片作用:减少IO口的占用(3个输入口,8个输出口连接LED)
74HC245 芯片作用:双向数据缓冲器,提高驱动能力
LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的期间。
两种连接方式:共阴极、共阳极连接
CE低电平有效
DIR 接高电平:把左边数据送到右边
接低电平:吧右边数据读回到左边
1.9.1 数码管段码表
0:0x3F 1:0x06 2:0x5B 3:0x4F 4:0x66 5:0x6D
6:0x7D 7:0x07 8:0x7F 9:0x6F
A:0x77 B:0x7C C:0x39 D:0x5E E:0x79 F:0x71 空:0x00
共阳极段码:0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
1.9.2 静态数码管显示
#include <REGX52.H>
//数组 装有共阳极断码表
unsigned char NixieTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
//子函数
void Nixie(unsigned char Location,Number)
{
switch(Location)
{
case 8: P2_4 = 1; P2_3 = 1; P2_2 = 1; break;//7:第八个数码管
case 7: P2_4 = 1; P2_3 = 1; P2_2 = 0; break;//6:第七个数码管
case 6: P2_4 = 1; P2_3 = 0; P2_2 = 1; break;//5:第六个数码管
case 5: P2_4 = 1; P2_3 = 0; P2_2 = 0; break;//4:第五个数码管
case 4: P2_4 = 0; P2_3 = 1; P2_2 = 1; break;//3:第四个数码管
case 3: P2_4 = 0; P2_3 = 1; P2_2 = 0; break;//2:第三个数码管
case 2: P2_4 = 0; P2_3 = 0; P2_2 = 1; break;//1:第二个数码管
case 1: P2_4 = 0; P2_3 = 0; P2_2 = 0; break;//0:第一个数码管
}
P0 = NixieTable[Number];
}
void main()
{
/*
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0x7d;//从高位往低位
*/
// C B A = Y
// 0 0 1 1 = Y3 第四个数码管亮
// 0 1 0 0 = Y4 第五个数码管亮
// A B C D E F G DP
// 1 0 1 1 1 1 1 0
// d 7
Nixie(2,8);//第二个位置亮8
while(1)
{
}
}
1.9.3 动态数码管显示
#include <REGX52.H>
void Delay(unsigned int xms);
//数组
unsigned char NixieTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
//子函数
void Nixie(unsigned char Location,Number)
{
switch(Location)//位置
{
case 8: P2_4 = 1; P2_3 = 1; P2_2 = 1; break;//7:第八个数码管
case 7: P2_4 = 1; P2_3 = 1; P2_2 = 0; break;//6:第七个数码管
case 6: P2_4 = 1; P2_3 = 0; P2_2 = 1; break;//5:第六个数码管
case 5: P2_4 = 1; P2_3 = 0; P2_2 = 0; break;//4:第五个数码管
case 4: P2_4 = 0; P2_3 = 1; P2_2 = 1; break;//3:第四个数码管
case 3: P2_4 = 0; P2_3 = 1; P2_2 = 0; break;//2:第三个数码管
case 2: P2_4 = 0; P2_3 = 0; P2_2 = 1; break;//1:第二个数码管
case 1: P2_4 = 0; P2_3 = 0; P2_2 = 0; break;//0:第一个数码管
}
P0 = NixieTable[Number];
}
void main()
{
/*
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0 = 0x7d;//从高位往低位
*/
// C B A = Y
// 0 0 1 1 = Y3 第四个数码管亮
// 0 1 0 0 = Y4 第五个数码管亮
// A B C D E F G DP
// 1 0 1 1 1 1 1 0
// d 7
while(1)
{
Nixie(1,0);
Delay(2);
Nixie(2,2);
Delay(2);
Nixie(3,1);
Delay(2);
Nixie(4,9);
Delay(2);
}
}
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
2.0 模块化编程及调试工具
2.0.1 模块化编程
把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其他.c文件想使用其中的代码时,只需要#include “xxx.h”文件即可。使用模块化编程可以极大的提高代码的可阅读性、可维护性、可移植性等
2.0.2 LCD1602调试工具
2.1矩阵键盘
逐行扫描;
逐列扫描;