关于c:C51单片机学习日志

1次阅读

共计 5276 个字符,预计需要花费 14 分钟才能阅读完成。

2021/05/01

踩坑

一开始装置驱动那里就出问题,驱动明明曾经装置,然而辨认不了单片机的接口,问客服,感觉客服也很迷,最初还是解决了。目测要么是 USB 线接触不良,要么是装置的 WIN10 驱动没起作用,因为前面还装置了一个 XP 驱动。

单片机相干概念

单片机是 单芯片微型计算机 的简称,罕用英文缩写_MCU_(Microcontroller Unit)代指单片机。
我所应用的单片机为 DIP 封装,尽管体积较大,然而不便装配,从而损坏后更换芯片更便捷。
其余两种封装(PLCC,LQFP),尽管体积小,然而更换比拟麻烦,。厂商为_STC_的,这家厂商单片机烧录程序便捷些。
厂商尽管不同,然而内核都是应用的 Intel 公司的 80C51 系列内核,_STC_的单片机命名规定如下:

一些零散知识点(C 语言)

因为 C 语言曾经学过不少了,就选择性地记了些笔记:
罕用存储单位关系:

中文名称 英文名称 换算关系
比特(字位) bit 1B = 8bit
字节 byte 1B = 8bit
千字节 kibibyte 1KB = 1024B
兆字节 Mebibyte 1MB = 1024KB
吉字节 Gigabyte 1GB = 1024MB

常说的 100M 宽带,并非是 100MB 而是100Mbit,所以换算成下载速度须要除以8,换算成字节单位,也就是12.5MB

数据类型 所占位数 范畴
bit 1 0~1
unsigned char 8 0~255
char 8 -128~127
unsigned int 16 0~65535
int 16 -32768~32767
unsigned long 32 0~429467295
float 32 3.4e-38~3.4e38
double 64 1.7e-308~1.7e308

其中,有符号位的最高位是符号位,0示意负数,1示意正数。

一些零散知识点(电子电路根底)

单片机是一种数字集成芯片,数字电路中只有两种电平:高电平和低电平。
高电平为 5V,低电平为0V
TTL 电平信号被利用的较多,因为数字电路中通常数据表示采纳二进制,5V 等价于 逻辑 1 0V等价于 逻辑 0 。TTL 电平规定高电平输入电压 >2.4V,低电平输入电压<0.4V,这是因为理论发送信号时,可能并不一定达到高电平和低电平的准确值,所以只有在这个稳定范畴内都是会被认定为高电平和低电平的。
而计算机串口应用的是 RS232 电平。
高电平为 -12V,低电平为+12V,单片机与计算机串口通信时须要应用电平转换芯片,把 RS232 电平转换为 TTL 电平后,单片机能力辨认。然而电路 USB 接口的供电口是5V,充电宝也是,所以能够用充电宝和电脑 USB 接口来给单片机供电。
I/ O 口是根本输出 Input/ 输入 Output 接口,单片机对外围设备的管制都是通过 I / O 口来进行的(输入高低电平)。接管内部管制也是通过 I / O 口来读取内部电压信号。
选电容时,个别选耐压值比利用零碎高 2 - 3 倍的电容。
有极性的电容,长脚为正,短脚为负。
电容上色彩面积小的局部所对应的为负极,反之为正极(对于直插和贴片电解电容)。而对于钽电容则相同。
单片机须要运行起来最根本的条件为:

  1. 电源
  2. 单片机芯片
  3. 晶振电路
  4. 复位电路
    单片机工作的根本时序:
    振荡周期:也称时钟周期,是指为单片机提供时钟脉冲信号的振荡源的周期。
    机器周期:一个机器蕴含 12 个时钟周期。在一个机器周期内,CPU 能够实现一个独立的操作。
    电路原理图中:
    电阻上的 471 字样代表电阻阻值为 47*10^1 Ω
    电容上的 105 字样代表电容大小为 10*10^5 pF
    网络标号雷同的两点示意这两点理论电气相连(有导线连贯)。

点亮 LED 灯

LED,即发光二极管。其长处是,功耗低,高亮度,色彩艳丽,寿命长。
同样的,LED 灯也是长正短负。它的封装形式和电容电阻相似,开发板中用的就是最小的 0603 封装。贴片式的 LED,有小绿点的一端为负极,另一端为正极。
一般发光二极管工作压降为 1.6V~2.1V。工作电流为1~20mA。一般发光二极管导通压降通常为0.7V。因为其工作电流较小,通常会再串一个限流电阻。
原理

由原理图可知,要想点亮 LED 灯,二极管须要处于导通状态,因为电源输出到阳极的信号恒为高电平,那么阴极为低电平能力导通,那么给阴极输出 0 即可。
实际
踩坑:在建我的项目编译文件时,记得在 output 里勾选输入 hex 文件。
暴力点灯
间接别离对须要亮灯的地位赋值 0。

#include <reg52.h>

sbit LED2 = P1^1;
sbit LED3 = P1^2;
sbit LED5 = P1^4;

void main()
{
    LED2 = 0;
    LED3 = 0;
    LED5 = 0;
}

多口操作点灯
P1的 8 个口一起操作,因为操作时是按位操作,所以赋值的数是二进制数,二进制数位上的 0 和 1 就别离代表了低电平和高电平,然而写程序时个别会赋值 16 进制的数。
二进制高位到低位就对应了 P1 的 8 个口从大到小的序号

#include <reg52.h>

void main()
{P1 = 0xE9;    //1110 1001}

2021/05/02

实现 LED 灯闪动

原理
因为程序中,main函数是会主动循环的,所以如果不加延时,间接让 LED 灯点亮而后再燃烧的话,对于人来说是看不到闪动的。所以,针对于人眼的视觉暂留效应,须要增加延时,使得 LED 灯亮和灭的工夫距离在人眼可见范畴内。
而延时分为软件延时(占用 CPU 资源)和定时延时(应用寄存器,不节约 CPU 资源),这里因为初学,采纳的是实现较为简单的软件延时。
实际
实现个别闪动

#include <reg52.h>

#define uint unsigned int

void delay()   // 繁难延时函数
{
    uint i = 65535;
    while(i--);
}

void main() //main 函数会主动循环
{
    P1 = 0; // 等价于十六进制的 0x00,把 P1 的每一个口赋值成 0,点亮 8 个 LED 灯
    delay();    
    P1 = 0xFF;  // 等价于二进制 1111 1111,把 P1 的每一个口赋值成 1,燃烧 8 个 LED 灯
    delay();}

实现可控延时闪动

#include <reg52.h>

#define uint unsigned int

void delay_ms(uint z)   // 毫秒级延时函数
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;    //114 能够用单片机精灵算,为的是实现毫秒级延时
}

void main() //main 函数会主动循环
{
    P1 = 0; // 等价于十六进制的 0x00,把 P1 的每一个口赋值成 0,点亮 8 个 LED 灯
    delay_ms(100);    
    P1 = 0xFF;  // 等价于二进制 1111 1111,把 P1 的每一个口赋值成 1,燃烧 8 个 LED 灯
    delay_ms(100);    
}

实现流水灯闪动

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

void delay_ms(uint z)   
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;    //114 能够用单片机精灵算,为的是实现毫秒级延时
}

uchar temp;
void main() 
{
    temp = 0xFE;   // 只让第一个 LED 点亮
    P1 = temp;
    delay_ms(500);
    while(1)
    {temp = _crol_(temp, 1); // 循环左移
        P1 = temp;
        delay_ms(500); 
    }
}

最终,尝试写了一个炫酷一点点的亮灯:
花式亮灯

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char
uchar temp;
uint i;

void delay_ms(uint z)   
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;    //114 能够用单片机精灵算出,为的是实现毫秒级延时
}

/* 上面的点亮函数中,延时函数的参数设置为不同时长,看起来更有层次感 */
void left() // 向左顺次点亮一个灯
{
    temp = 0xFE;   // 只让第 1 个 LED 点亮
    P1 = temp;
    delay_ms(100);
    for(i = 0; i < 7; i++)
    {temp = _crol_(temp, 1); // 循环左移
        P1 = temp;
        delay_ms(100); 
    }
    P1 = 0xFF;
    delay_ms(150);
}

void right()    // 向右顺次点亮一个灯
{
    temp = 0x7F;   // 只让第 8 个 LED 点亮
    P1 = temp;
    delay_ms(100);
    for(i = 0; i < 7; i++)
    {temp = _cror_(temp, 1); // 循环右移
        P1 = temp;
        delay_ms(100); 
    }
    P1 = 0xFF;
    delay_ms(150);
}

void side_to_mid()  // 从两边向两头顺次点亮一个灯
{
    P1 = 0x7E;
    delay_ms(200);
    P1 = 0xBD;
    delay_ms(150);
    P1 = 0xDB;
    delay_ms(100);
    P1 = 0XE7;
    delay_ms(100);
    P1 = 0xFF;
    delay_ms(150);
}

void mid_to_side()  // 从两头向两边顺次点亮一个灯
{
    P1 = 0XE7;
    delay_ms(200);
    P1 = 0xDB;
    delay_ms(150);
    P1 = 0xBD;
    delay_ms(100);
    P1 = 0x7E;
    delay_ms(100);
    P1 = 0xFF;
    delay_ms(150);
}

void all()  // 从两边向两头全副点亮
{
    P1 = 0x7E;
    delay_ms(200);
    P1 = 0x3C;
    delay_ms(150);
    P1 = 0x18;
    delay_ms(100);
    P1 = 0X00;
    delay_ms(150);
}

void main() 
{left();
    right();
    side_to_mid();
    mid_to_side();
    all();
    while(1);   // 放弃全亮状态
}

Keil 中的调试工具

工具栏中一个像放大镜一样的 debug 性能,能够看 IO 口在执行完语句的变动。
在 debug 前记得先点击魔法棒图标,设置晶振频率,我所应用的开发板频率为 11.0592MHz
先编译再进入 debug 模式,进入之后能够抉择 IO 口监控状态。同时右边的窗口中有程序运行的工夫等等信息,右下角窗口能够抉择具体的变量进行监控。左上角能够抉择调试模式。

蜂鸣器

原理
单片机是用于管制的,不适宜驱动功率器件,所以并不是间接将 IO 口接到蜂鸣器下面,因为它的输入电流很小,而是用三极管作开关管,再加一个限流电阻,来管制蜂蜜器是否发声的。
直流电机不能间接接到开发板电源上,因为在其完结转动时有较高的反电动势,可能会损坏开发板。
实际
间接在流水灯的代码上稍加批改即可,蜂鸣器在 P23 口,如果间接赋值给 beep 一个逻辑 0 的话,就会使其收回间断不间断的蜂鸣声。

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char
uchar temp;
sbit beep = P2^3;

void delay(uint z)
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--);
}

void main()
{
    temp = 0xF0;
    P1 = temp;
    delay(100);
    while(1)
    {temp = _crol_(temp, 1);
        P1 = temp;
        beep = ~beep;   // 一直取反,使得其每距离 100ms 发声
        delay(100);
    }
}

数码管

原理
数码管外部由 8 颗 LED 组成,想要显示什么样的字符,就管制想要显示的局部亮起,其余局部燃烧即可。个别分为两种,共阴极和共阳极。两者只在公共脚处不同,公共脚为 VCC 的是共阳极,为 GND 的是共阴极。能够用万用表连贯公共脚和其余任意脚即可测出数码管类型。
数码管的公共脚叫做 位选 ,其余脚叫做 段选 。位选用来抉择数码管哪一位亮起,段选用来抉择亮起数码管的哪些 LED 灯亮。
我所应用的开发板中,数码管为共阴极型的,因为它们的阴极连贯的公共脚是接地,为低电平,那么给数码管输出高电平即可电亮 LED 管。
数码管显示分为 动态显示 动态显示 。这里先具体学习动态显示。
动态显示比拟占 IO 口,因为每个数码管的段选都必须接一个 8 位数据线来放弃显示的字形码,显示的字形能够始终放弃,直到送入新的字形。
锁存器
能够把数据输出端与输入端进行隔离或连贯。
74HC573 为例:


输入口 Q 要想输入高低电平,OE 脚必须接 GND。
LE 脚为高时,输入端 Q 随输出端 D 的数据而变动。LE 脚为低时,输入端 Q 数据放弃不变,输出端 D 数据变动不会扭转 Q 的数据。
上拉电阻
将不确定的信号通过一个限流电阻(个别为 10k-4.7k 欧姆的电阻)钳位在高电平,下拉同理,钳位在低电平。准双向 IO中有上拉电阻,那么它就既可能输入高电平又可能输入低电平,而漏极开路输入电路,因为没有上拉电阻,就只能输入低电平,输出高电平会让它处于开路状态。

2021/05/03

正文完
 0