用什么软件建手机网站,格力网站建设需求分析,创建微信小程序要钱吗,华为模板建站文章目录 参考资料1. 准备工作1.1 win10配置51单片机开发环境1.1 Ubuntu配置51单片机开发环境问题1#xff1a;mcs51/8051.h依赖于mcs51/lint.h问题2#xff1a;提示找不到头文件mcs51/8051.h 2. 认识51单片机2.1 STC89C52单片机2.2 管脚图2.3 原理图2.4 按键抖动2.5 头文件说… 文章目录 参考资料1. 准备工作1.1 win10配置51单片机开发环境1.1 Ubuntu配置51单片机开发环境问题1mcs51/8051.h依赖于mcs51/lint.h问题2提示找不到头文件mcs51/8051.h 2. 认识51单片机2.1 STC89C52单片机2.2 管脚图2.3 原理图2.4 按键抖动2.5 头文件说明2.6 模块化函数2.6.1 延时函数2.6.2 矩阵键盘 3. LED模块3.1 原理图实验1点亮LED灯D1实验2LED灯D8闪烁实验3LED流水灯 4. 独立按键模块4.1 原理图实验1独立按键控制LED灯D1 5. 动态数码管模块5.1 原理图实验1数码管LED3显示2实验2数码管LED8 ~ LED1分别显示0 ~ 8 6. LCD1602接口6.1 原理图 7. 矩阵按键模块7.1 原理图实验1在LCD1602显示按下的键码1 ~ 16实验24位密码锁 8. 定时器与中断8.1 原理图实验1实现一个电子时钟 9. 串口通信9.1 原理图 参考资料
51单片机入门教程-2020版 程序全程纯手打 从零开始入门 江协科技资料下载 51单片机STC89C52RC系统性学习笔记
1. 准备工作
1.1 win10配置51单片机开发环境
51单片机
正在重新握手 ... 成功 [0.578]
当前的波特率: 115200
正在擦除目标区域 ... 完成 ! [0.328]
正在下载用户代码 ... 完成 ! [0.141]
正在设置硬件选项 ... 完成 ! [0.031]更新后的硬件选项为:. 当前的时钟频率: 11.088MHz. 系统频率为12T(单倍速)模式. 振荡器的放大增益不降低. 当看门狗启动后,任何复位都可停止看门狗. MCU内部的扩展RAM可用. ALE脚的功能选择仍然为ALE功能脚. P1.0和P1.1与下次下载无关. 下次下载用户程序时,不擦除用户EEPROM区单片机型号: STC89C52RC/LE52RC固件版本号: 6.6.4C编程工具 Keil5 C51 新建项目时选择AT89C51RC2 将程序载入到51单片机的工具 STC-ISP 51单片机接入电脑并配置驱动CH340_CH341
1.1 Ubuntu配置51单片机开发环境
编辑器 VS Code 安装教程安装VS Code插件 C/C Extension Pack安装编译工具 sudo apt-get install sdcc程序编译 sdcc 1_LED_1.c 将编译生成的文件输出到out目录需要先通过sudo mkdir out创建out目录 sdcc 1_LED_1.c -o out/
问题1mcs51/8051.h依赖于mcs51/lint.h
#include mcs51/lint.h
#include mcs51/8051.h问题2提示找不到头文件mcs51/8051.h 8051.h是安装sdcc后产生的请先确保sdcc已经安装sudo find / -name 8051.h搜索一下头文件8051.h所在的目录 这里目录是/usr/share/sdcc/include将该路径配置到includepath先点击Quick Fix 再点击Edit “includePath” setting
添加/usr/share/sdcc/include到Include path
2. 认识51单片机
2.1 STC89C52单片机
所属系列51单片机系列公司STC公司位数8位RAM512字节ROM8KFlash工作频率12MHz本开发板使用
2.2 管脚图 2.3 原理图 高清PDF可从这里下载江协科技资料下载
2.4 按键抖动
对于机械开关当机械触点断开、闭合时由于机械触点的弹性作用一个开关在闭合时不会马上稳定地接通在断开时也不会一下子断开所以在开关闭合及断开的瞬间会伴随一连串的抖动。 因此需要进行防抖处理如下
// 这是一个检测独立按键K1是否按下并控制LED模块的简化代码
if(P3_10) // 如果K1按键按下P3_1的值会变为0
{Delay(20); // 延时20毫秒消抖while(P3_10); // 死循环空转直到K1按键松开P3_1变为1跳出循环Delay(20); // 延时20毫秒消抖P2_0~P2_0; // LED1的亮灭情况
}2.5 头文件说明
#include mcs51/lint.h
#include mcs51/8051.h
#include REGX52.H2.6 模块化函数
2.6.1 延时函数
#ifndef __DELAY_H__
#define __DELAY_H__void Delayms(unsigned char k);#endif#include INTRINS.H// 延时k ms
void Delayms(unsigned char k) //11.0592MHz
{unsigned char i, j;while (k --) {_nop_();i 2;j 199;do{while (--j);} while (--i);}
}2.6.2 矩阵键盘
#ifndef __MATRIXKEYBOARD_H__
#define __MATRIXKEYBOARD_H__unsigned int matrixKeyboard();#endif#include at89c51RC2.h
#include Delay.h
// 反回键码1 ~ 16行优先遍历
// 按列扫描矩阵键盘
// 如果按行的话P1_5和蜂鸣器冲突会导致其发声
unsigned int matrixKeyboard() {unsigned int keyNum 0;P1 0xFF;P1_3 0; // 第一列if (P1_7 0) {Delayms(20); while (P1_7 0); Delayms(20); keyNum 1;}if (P1_6 0) {Delayms(20); while (P1_6 0); Delayms(20); keyNum 5;}if (P1_5 0) {Delayms(20); while (P1_5 0); Delayms(20); keyNum 9;}if (P1_4 0) {Delayms(20); while (P1_4 0); Delayms(20); keyNum 13;}P1 0xFF;P1_2 0; // 第二列if (P1_7 0) {Delayms(20); while (P1_7 0); Delayms(20); keyNum 2;}if (P1_6 0) {Delayms(20); while (P1_6 0); Delayms(20); keyNum 6;}if (P1_5 0) {Delayms(20); while (P1_5 0); Delayms(20); keyNum 10;}if (P1_4 0) {Delayms(20); while (P1_4 0); Delayms(20); keyNum 14;}P1 0xFF;P1_1 0; // 第三列if (P1_7 0) {Delayms(20); while (P1_7 0); Delayms(20); keyNum 3;}if (P1_6 0) {Delayms(20); while (P1_6 0); Delayms(20); keyNum 7;}if (P1_5 0) {Delayms(20); while (P1_5 0); Delayms(20); keyNum 11;}if (P1_4 0) {Delayms(20); while (P1_4 0); Delayms(20); keyNum 15;}P1 0xFF;P1_0 0; // 第四列if (P1_7 0) {Delayms(20); while (P1_7 0); Delayms(20); keyNum 4;}if (P1_6 0) {Delayms(20); while (P1_6 0); Delayms(20); keyNum 8;}if (P1_5 0) {Delayms(20); while (P1_5 0); Delayms(20); keyNum 12;}if (P1_4 0) {Delayms(20); while (P1_4 0); Delayms(20); keyNum 16;}return keyNum;
}3. LED模块
3.1 原理图 LED等的左侧接入VCC正极若要使灯亮则右侧需要接入负极也就是对应的寄存器位需要赋值为0。
实验1点亮LED灯D1
#include AT89C51RC2.h
/*** 点亮LED灯D1
*/
void main() {P2 0xFF; // 将所有灯熄灭P2_0 0; // D1灯亮起while (1); // 程序始终保持运行
}实验2LED灯D8闪烁
#include AT89C51RC2.h
#include INTRINS.H/*** LED灯D8闪烁
*/
void main() {P2 0xFF; while (1){P2_7 0; // D8灯亮Delayms(1000); // 延迟1000ms 1sP2_7 1; // D8灯灭Delayms(1000); // 延迟1000ms 1s}
}实验3LED流水灯
#include AT89C51RC2.h
#include Delay.h/*** LED灯D1 ~ D8按顺序点亮每次只有一个灯亮
*/
void main() {// 1111 1110// 1111 1101// 1111 1011// ...// 1111 1110// 》 其实就是实现循环左移P2 0xFE;while (1){P2 1;if (P2 ! 0xFE) P2 | 0x01;Delayms(1000); // 延迟1000ms 1s}
}4. 独立按键模块
4.1 原理图 实验1独立按键控制LED灯D1
#include AT89C51RC2.h
#include Delay.h/*** 独立按键K1控制LED灯D1* 按下按键并松开后变换灯D1的状态
*/
void main() {while (1){// 注意控制K1的是P3_1控制K2的是P3_0// 当值为0是代表按键按下if (P3_1 0) {Delay(20); // 消除按键抖动while (P3_1 0); // 一直保持按下的状态则卡在这Delay(20); // 消除按键抖动P2_0 ~P2_0; // 状态取反}}
}5. 动态数码管模块
5.1 原理图 LED1 ~ LED8的亮灭位选由P24, P23, P22三位决定P24位高位当这三个位表示数据n时Yn对应的灯亮Y0对应LED1 P0_0 ~ P0_6分别控制a ~ g晶体管P0_7控制dp晶体管为1代表选中。P0_7是最高位P0_0是最低位
实验1数码管LED3显示2
#include AT89C51RC2.h/*** 数码管LED3显示2
*/
void main() {// 选中数码管LED3,对应Y2 P2_4 P2_3 P2_2 0 1 0P2_4 0;P2_3 1;P2_2 0;// a b c d e f g dp// 0 1 2 3 4 5 6 7// a b c d e f g dp// 1 1 0 1 1 0 1 0 0101 1011 0x5B// 数字2需要点亮 a b g e dP0 0x5B;while (1);
}实验2数码管LED8 ~ LED1分别显示0 ~ 8
// 对应数字 0 9 的段码
unsigned char NixieTable[] {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
// 在LED-loc 显示num
void Nixie(unsigned char loc, unsigned char num) { P2_4 0; P2_3 0; P2_2 0; // 1110 0011 0xE3 P2 0xE3if ((loc 0x01) 1) P2_2 1;if ((loc 0x02) 2) P2_3 1;if ((loc 0x04) 4) P2_4 1;P0 NixieTable[num];// 消影数字清零防止上一个位置的数字显示到下一个位置Delayms(1);P0 0x00;
}/*** 数码管LED8 ~ LED1分别显示0 ~ 8
**/
void main() {unsigned char i;while (1) {for (i 0; i 7; i ) {Nixie(7 - i, i);}}
}6. LCD1602接口
6.1 原理图 7. 矩阵按键模块
7.1 原理图 实验1在LCD1602显示按下的键码1 ~ 16
#include at89c51RC2.h
#include Delay.h
// 反回键码1 ~ 16行优先遍历
// 没有按下任何键则返回0
// 按列扫描矩阵键盘
// 如果按行的话P1_5和蜂鸣器冲突会导致其发声
unsigned int matrixKeyboard() {unsigned int keyNum 0;P1 0xFF;P1_3 0; // 第一列if (P1_7 0) {Delayms(20); while (P1_7 0); Delayms(20); keyNum 1;}if (P1_6 0) {Delayms(20); while (P1_6 0); Delayms(20); keyNum 5;}if (P1_5 0) {Delayms(20); while (P1_5 0); Delayms(20); keyNum 9;}if (P1_4 0) {Delayms(20); while (P1_4 0); Delayms(20); keyNum 13;}P1 0xFF;P1_2 0; // 第二列if (P1_7 0) {Delayms(20); while (P1_7 0); Delayms(20); keyNum 2;}if (P1_6 0) {Delayms(20); while (P1_6 0); Delayms(20); keyNum 6;}if (P1_5 0) {Delayms(20); while (P1_5 0); Delayms(20); keyNum 10;}if (P1_4 0) {Delayms(20); while (P1_4 0); Delayms(20); keyNum 14;}P1 0xFF;P1_1 0; // 第三列if (P1_7 0) {Delayms(20); while (P1_7 0); Delayms(20); keyNum 3;}if (P1_6 0) {Delayms(20); while (P1_6 0); Delayms(20); keyNum 7;}if (P1_5 0) {Delayms(20); while (P1_5 0); Delayms(20); keyNum 11;}if (P1_4 0) {Delayms(20); while (P1_4 0); Delayms(20); keyNum 15;}P1 0xFF;P1_0 0; // 第四列if (P1_7 0) {Delayms(20); while (P1_7 0); Delayms(20); keyNum 4;}if (P1_6 0) {Delayms(20); while (P1_6 0); Delayms(20); keyNum 8;}if (P1_5 0) {Delayms(20); while (P1_5 0); Delayms(20); keyNum 12;}if (P1_4 0) {Delayms(20); while (P1_4 0); Delayms(20); keyNum 16;}return keyNum;
}// 在LCD1602显示按下的键码1 ~ 16
void main() {unsigned int num 0, newNum 0;LCD_Init();while (1) {newNum matrixKeyboard();if (newNum ! 0) {num newNum;}LCD_ShowNum(1, 1, num, 2); // 第一行第一列显示占两个位置}
}实验24位密码锁
// 10为011为确认12为清空
void main() {// num保存当前输入的密码// keyNum记录矩阵键盘按下的键码// count记录当前已经输入多少个数字unsigned int num 0, keyNum 0, count 0;// LCD1602初始化LCD_Init();// 在第一行的前9个输入固定显示输入提示符LCD_ShowString(1, 1, PASSWORD:);while (1) {// 第10个字符显示当前输入的密码LCD_ShowNum(1, 10, num, 4);// 获取当前矩阵键盘的键码没有按下任何键则返回0keyNum matrixKeyboard();if (keyNum 1 keyNum 9 count 4) {num num * 10 keyNum;count ;} else if (keyNum 11 count 4) {if (num 1234) {LCD_ShowString(2, 1, OK);} else {LCD_ShowString(2, 1, ERR);}} else if (keyNum 12) {num 0;count 0;LCD_ShowString(2, 1, );}}
}8. 定时器与中断
定时器介绍:51单片机的定时器属于单片机的内部资源其电路的连接和运转均在单片机内部完成 定时器作用︰ (1)用于计时系统可实现软件计时或者使程序每隔一固定时间完成一项操作 (2)替代长时间的Delay提高CPU的运行效率和处理速度(…)
8.1 原理图 TL0和TH0发生溢出时达到65535TF0标志位被置位1从而引发中断。
生成定时器初始化代码
void Timer0Init(void) //1毫秒11.0592MHz
{AUXR 0x7F; //定时器时钟12T模式TMOD 0xF0; //设置定时器模式TMOD | 0x01; //设置定时器模式TL0 0x66; //设置定时初值TH0 0xFC; //设置定时初值TF0 0; //清除TF0标志TR0 1; //定时器0开始计时// 这两个开关配置需要自己加一下ET0 1; // 打开定时器0EA 1; // 打开总开关
}
实验1实现一个电子时钟
void Timer0Init() //1毫秒11.0592MHz
{AUXR 0x7F; //定时器时钟12T模式TMOD 0xF0; //设置定时器模式TMOD | 0x01; //设置定时器模式TL0 0x66; //设置定时初值 TH0 0xFC; //设置定时初值TF0 0; //清除TF0标志TR0 1; //定时器0开始计时ET0 1; // 打开定时器0EA 1; // 打开总开关
}unsigned int count 0;
// 设置时钟为 23:59:45 方便调试
unsigned int second 45;
unsigned int minute 59;
unsigned int hour 23;void main() {
// // TMOD不可位寻址, M0给1 0x01
// // TMOD 0x01; // 配置定时器0
// // 防止对定时器1的配置产生影响使用与或赋值法
// TMOD 0xF0; // 清空定时器0的配置
// TMOD | 0x01; // 配置定时器0
//
// // TCON可位寻址TF0 0, TR0 1
// TF0 0;
// TR0 1;
//
// // 64635 到 65535 相差1000也就是1ms会发生中断
// TH0 64535 / 256; // 取高8位
// TL0 54535 % 256; // 取低8位
//
// // 定时器开关
// ET0 1; // 打开定时器0
// EA 1; // 打开总开关PT0 0;Timer0Init();LCD_Init();LCD_ShowChar(1, 3, :);LCD_ShowChar(1, 6, :);while (1) {if (second 60) {second 0;minute ;}if (minute 60) {minute 0;hour ;}if (hour 24) {hour 0;}LCD_ShowNum(1, 1, hour, 2);LCD_ShowNum(1, 4, minute, 2);LCD_ShowNum(1, 7, second, 2);}
}// 发生时钟中断时会触发该函数中断号为1
void Timer0_Routube() interrupt 1 {TL0 0x66; //设置定时初值TH0 0xFC; //设置定时初值count ;if (count 1000) {second ;count 0;// 中断程序应该尽量简短
// if (second 60) {
// second 0;
// minute ;
// if (minute 60) {
// minute 0;
// hour ;
// if (hour 24) {
// hour 0;
// }
// }
// }}
}9. 串口通信
9.1 原理图