单片机零基础入门(9-1)实战:模块化编程(模块化两个案例含源码--以及无法显示头文件(.h)的解决方案)
单片机零基础入门(9-1)实战:模块化编程—(以及无法显示头文件(.h)的解决方案)
本文作为单片机零基础入门(8-5)模块化编程的拓展和补充,比前面的单片机零基础入门(8-5)模块化编程更为详细。
一、回顾
上篇文章,单片机零基础入门(8-4)实战:单片机动态数码管消影—附源代码。
解决了问题:如果多个位置显示不同的数字,就会出现字影,而不是清晰的显示对应的数字。
本节内容主要是:C语言预编译、如何创建工程文件、如何添加模块化编程文件、没有显示头文件(.h文件)的解决方案。
文末有两个案例(含源代码和原理图):
案例1:利用模块化利用LED灯写一个流水灯(逐个引脚定义使用版)。
案例2:利用模块化利用LED灯写一个流水灯(使用一个P2搞定所有的引脚)。
二、问题<模块化编程的来源>:
每个人的编程习惯不一样,编程风格不一样,所以会导致有时候阅读代码很吃力。在实际工作过程中,代码维护起来也不方便,后期项目升级或者变更,也会造成更多时间的浪费。这时候,就需要一个可以让代码看起来更规范,更整洁的规则,他就是:模块化编程。
当我们把代码根据模块来编写后,会大大降低阅读代码的人的困难,提高效率,也便于后期的维护或升级。
本节解决题目:把“Delay.c”文件独立出来写,在主函数里面调用一个“Delay.h”文件,既可实现点亮LED灯。实现模块化编程
二、传统编程和模块化编程:
传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。
模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等。
三、模块化编程的框图示例和详解
1、模块化编程的操作
模块化编程仅需要在工程中新建一个.c文件,将需要实现某个功能的模块代码(函数的主体)放到.c里面,将函数的声明放到对应的.h里面。最后调用时,仅仅需要调用.h文件声明一下就行了。
2、注意事项:
(1).c文件:函数、变量的定义。
(2).h文件:可被外部调用的函数、变量的声明。
(3)任何自定义的变量、函数在调用前必须有定义或声明(同一个.c)。
(4)使用到的自定义函数的.c文件必须添加到工程参与编译。
(5)使用到的.h文件必须要放在编译器可寻找到的地方(工程文件夹根目录、安装目录、自定义)。
3、C语言预编译
C语言的预编译以#开头,作用是在真正的编译开始之前,对代码做一些处理(预编译)
预编译 | 意义 |
---|---|
#include<REGX52.H> | 把REGX52.H文件的内容搬到此处 |
#define PI 3.14 | 定义PI,将PI替换成3.14 |
#define ABC | 定义ABC |
ifndef XX_H | 如果没有定义_XX_H_ |
#endif | 与#ifndef,#if匹配,组成“括号” |
此外还有#ifdef,#if,#else,#elif,#undef等
注:
//例子1:
#ifdef AAA
int a=1;
#endif//如果定义了AAA,“int a=1”才会参与编译。
//例子2
#define AAA //定义AAA
#ifdef AAA
int b=0; //int b=0参与编译
#endif//#define定义AAA,#ifdef判断(是否)定义了AAA,int b=0参与编译,#endif结束。
四、创建模块化文件步骤:
1、创建main.c文件
步骤1、创建新项目:
打开keil----创建新项目,点击创建新工程。
步骤2、选择项目创建的文件夹
在文件名写项目名称(注意,不要填写中文)
步骤3、选择单片机的芯片
选择对应单片机的芯片(开发板的芯片,我这里是AT89C51.),点击“OK”
步骤4、展开项目
点击“Target 1”展开“Source Group 1”
步骤5、新建.C文件
鼠标右击“Source Group 1”,点击“Add New Item toGroup “Source Group 1”…”(可以理解为:在“Source Group 1”的文件夹里面创建新文件)。
步骤6、创建主函数
选择“.c”文件,命名为“main”,点击“Add”。
步骤7、查看添加成功的主函数
查看main.c文件已经添加成功,在main.c中添加头文件(#include <REGX51.H>),然后先把框架搭建好,查看编译是否有问题。
2、添加Delay.c和Delay.h文件
步骤同前面“创建main.c”。
2.1、添加Delay.c文件
步骤和创建main.c文件一致,就不一一赘述,详细步骤看截图。
2.2、添加Delay.h文件
步骤也是和前面添加.c文件一样,就不一一赘述,但是,注意,这次创建的.h文件,所以创建时选择“Header File (.h)”文件
注意:
1、创建头文件时,需要选择“Header File (.h)”文件。
2、命名时,和对应的.c文件命名一致。
3、问题:无法显示头文件??不存在刚刚添加的.h怎么办?
问题:当完成2.2的步骤时,竟然意外发现Delay.h文件没有展示出来,到底怎么回事呢??如下图:
别怕!!!!
解决方案来啦:
点击烟花旁边的小魔方,再点击添加文件,找到此目录下的.h文件,确定既可。如下图:
步骤1、 点击工具栏的小魔方,点击添加文件(Add files)。如下图:
步骤2、 文件类型选择"."也就是所有类型文件,最后选择需要添加的头文件“Delay.h”文件。如下图:
步骤3、 最后:查看列表,此时缺少的头文件显示在列表内了。如下图:
到此,又完美解决一个问题。
五、模块化编程实例:
1、头文件的编写:
Delay.h文件添加成功后,里面填写什么内容?代码如下:
Delay.h文件里面固定内容如下:
#ifndef _DELAY_H_
#define _DELAY_H_// 此处添加对应.c的函数名既可。#endif
2、Delay.c文件
Delay.c文件里面是起延迟作用的代码。如下图:
void Delay500ms() //@12.000MHz
{unsigned char i, j, k;i = 4;j = 205;k = 187;do{do{while (--k);} while (--j);} while (--i);
}
3、完善Delay.h文件
在Delay.h文件里面添加对应.c文件的函数名既可。
#ifndef _DELAY_H_
#define _DELAY_H_// 此处添加对应的.c函数名既可void Delay500ms(); //.c里面的函数名#endif
4、在主函数中运用Delay.c的内容
4.1、Delay.h文件内容:
#ifndef __DELAY_H__
#define __DELAY_H__// 此处添加对应的.c函数名既可void Delay200us(unsigned int xms);#endif
4.2、Delay.c内容:
void Delay200us(unsigned int xms) //@12.000MHz
{unsigned char i, j;while(xms--){i = 3;j = 82;do{while (--j);} while (--i);}}
4.3、main.c内容:
六、代码案例(2个):
前面的文章有详细写到如何看LED和数码管的引脚以及如何定义。忘记了可以跳转到“单片机零基础入门(8-2)实战:在数码管中实现显示一个数字–数码管知识的应用”和“单片机零基础入门(4):实现人生中的第一个流水灯(跑马灯)”文章中再巩固一下。
1、单片机原理图
1.1、原理图总览
1.2、原理图LED模块
1.3、原理图MCU部分
2、使用模块化写一个流水灯。(源码)
2.1、第一种:单个独立LED引脚控制:
代码如下:
//案例1:模块化写一个流水灯(第一种:单个独立LED引脚控制:
)
//使用P2_0、P2_1、P2_2....P2_7控制逐个LED亮灭的过程。//led.c#include <REGX51.H>
#include "Delay.h"
#include "led.h"void led()
{P2_0=0;Delay(500);P2_0=1;Delay(500);P2_1=0;Delay(500);P2_1=1;Delay(500); P2_2=0;Delay(500);P2_2=1;Delay(500); P2_3=0;Delay(500);P2_3=1;Delay(500); P2_4=0;Delay(500);P2_4=1;Delay(500); P2_5=0;Delay(500);P2_5=1;Delay(500); P2_6=0;Delay(500);P2_6=1;Delay(500);P2_7=0;Delay(500);P2_7=1;Delay(500); }
/*-------------分隔符----------------------*///led.h#ifndef __LED_H__
#define __LED_H__void led();#endif/*-------------分隔符----------------------*///Delay.c
/*
此处为延时函数
用于单片机的延时操作。
*/
void Delay(unsigned int xms) //@12.000MHz
{unsigned char i, j;while(xms--){i = 3;j = 82;do{while (--j);} while (--i);}}/*-------------分隔符----------------------*///Delay.h#ifndef __DELAY_H__
#define __DELAY_H__// 此处添加对应的.c函数名既可void Delay(unsigned int xms);#endif/*-------------分隔符----------------------*///main.c#include <REGX51.H>
#include "Delay.h"
#include "led.h"void main()
{led(); //调用LED控制函数}
2.2、第二种:八位1体LED引脚控制:
第二种为:单片机零基础入门(4):实现人生中的第一个流水灯(跑马灯)的知识。
八位一体,其实就是led.c文件中的定义方式和前面的引脚逐一定义的不同,其他代码都一样。<但这里源码我还是一样,全部附加上吧。>
代码如下:
/*-------------分隔符----------------------*///案例1:模块化写一个流水灯(第二种:八位1体LED引脚控制:)
//使用P2控制逐个LED亮灭的过程,无需详细到单个引脚。//led.c#include <REGX51.H>
#include "Delay.h"
#include "led.h"/*此处是单片机控制led灯的亮灭
--流水灯操作*/void led()
{//1111 1110P2 = 0XFE; //亮第1个灯Delay(500);P2 = 0XFF;//1111 1101P2 = 0XFD; //亮第2个灯Delay(500);P2 = 0XFF;//1111 1011P2 = 0XFB; //亮第3个灯Delay(500);P2 = 0XFF;//1111 0111P2 = 0XF7; //亮第4个灯Delay(500);P2 = 0XFF;//1110 1111P2 = 0XEF; //亮第5个灯Delay(500);P2 = 0XFF;//1101 1111P2 = 0XDF; //亮第6个灯Delay(500);P2 = 0XFF;//1011 1111P2 = 0XBF; //亮第7个灯Delay(500);P2 = 0XFF;//0111 1111P2 = 0X7F; //亮第8个灯Delay(500);P2 = 0XFF;
}/*-------------分隔符----------------------*///led.h#ifndef __LED_H__
#define __LED_H__void led();#endif/*-------------分隔符----------------------*///Delay.c
/*
此处为延时函数
用于单片机的延时操作。
*/
void Delay(unsigned int xms) //@12.000MHz
{unsigned char i, j;while(xms--){i = 3;j = 82;do{while (--j);} while (--i);}}/*-------------分隔符----------------------*///Delay.h#ifndef __DELAY_H__
#define __DELAY_H__// 此处添加对应的.c函数名既可void Delay(unsigned int xms);#endif/*-------------分隔符----------------------*///main.c#include <REGX51.H>
#include "Delay.h"
#include "led.h"void main()
{led(); //调用LED控制函数}
特别注意:
问题: 有朋友问我, 这个P2的定义怎么来的?
例如:P2 = 0XFF为什么是灭;;P2=0X7F为什么是点亮第8个灯?
答:0XFF是十六进制,单片机的LED点亮方式为二进制,所以,0XFF转化为二进制为:1111 1111<8个1,我们使用的这个单片机1为灭,0为亮>;以此计算:0X7F转换为二进制为0111 1111,所以得到第8个灯点亮。
本章节作为单片机零基础入门(8-5)模块化编程的拓展和补充,比前面的[单片机零基础入门(8-5)模块化编程]更为详细,且有实例,但是我在不同时间不同阶段写的文章。
下一篇:不定时更新,具体时间待定。
------人生在勤,不索何获!------
单片机零基础入门(9-1)实战:模块化编程(模块化两个案例含源码--以及无法显示头文件(.h)的解决方案)相关推荐
- 单片机零基础入门(8-4)实战:单片机动态数码管消影---附源代码
单片机零基础入门(8-4)实战:单片机动态数码管消影 一.回顾 二.问题及原因 三.解决办法: 四.解决后的源代码: 五.补充知识:数码管驱动方式 1.单片机直接扫描: 2.专用驱动芯片: 一.回顾 ...
- 视频教程-20年Nodejs教程零基础入门到项目实战前端视频教程-Node.js
20年Nodejs教程零基础入门到项目实战前端视频教程 7年的开发架构经验,曾就职于国内一线互联网公司,开发工程师,现在是某创业公司技术负责人, 擅长语言有node/java/python,专注于服务 ...
- react从零基础入门到项目实战视频教程
React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站, 并于 2013年 5 月开源.React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它.这 ...
- 天池零基础入门NLP竞赛实战:Task4-基于深度学习的文本分类3-基于Bert预训练和微调进行文本分类
Task4-基于深度学习的文本分类3-基于Bert预训练和微调进行文本分类 因为天池这个比赛的数据集是脱敏的,无法利用其它已经预训练好的模型,所以需要针对这个数据集自己从头预训练一个模型. 我们利用H ...
- 零基础入门深度学习(二):用一个案例掌握深度学习方法
导读 本课程是百度官方开设的零基础入门深度学习课程,主要面向没有深度学习技术基础或者基础薄弱的同学,帮助大家在深度学习领域实现从0到1+的跨越.从本课程中,你将学习到: 深度学习基础知识 numpy实 ...
- 零基础入门--中文命名实体识别(BiLSTM+CRF模型,含代码)
https://github.com/mali19064/LSTM-CRF-pytorch-faster 中文分词 说到命名实体抽取,先要了解一下基于字标注的中文分词. 比如一句话 "我爱北 ...
- 零基础一天学会开发制作一个微信小程序【附源码】
时至如今,微信已然成为一个全民通用的工具,相应的微信小程序开发已经是一个热门的开发项目. 小程序的前端代码和web是极其相似的,wxml和html.wxss和css以及js,现在还经常将wxss读作c ...
- 零基础开启元宇宙|抖音快手虚拟形象直播【源码】
在上一篇文章零基础开启元宇宙--创建虚拟形象中,我们实现了创建虚拟形象,接下来我们可以利用虚拟形象"为所欲为".今天我们利用虚拟形象在短视频平台如快手.抖音中直播,对于不希望露脸的 ...
- 实战并发编程 - 10Guarded Suspension模式在BlockingQueue源码中应用
文章目录 Pre Another Case 源码分析 概 继承关系 核心方法 非阻塞式方法(offer . add) offer(E e) add(E e) 阻塞式方法 (put(E e) / tak ...
最新文章
- 机器学习与深度学习常见面试问题与答案
- Drug Target Review | 筛选用于抗COVID-19的抗病毒化合物
- Palindrome Linked List
- js高程(二)-----继承
- 如何在Amazon AWS上设置一台Linux服务器
- 关于 SAP Spartacus SSR 服务器返回的响应是否应该被缓存的问题
- java 分号 转义_java – 正则表达式和转义和未转义的分隔符
- 开关问题(模板+高斯消元)
- 获取form表单_【第1535期】前端 Form 的表单的一个通用解决方案
- Matlab绘图基本控制命令
- Huffman编码原理详解
- Okhttp之CacheInterceptor简单分析
- SEO助手-免费万能SEO网站优化小助手
- 移动硬盘变成RAW,如何将其转换为NTFS
- WPF 通过Image控件实现多张图片的播放
- meta pseudo label
- IOS 编程初体验 第一篇:自学和培训的选择
- sql server 通过参数获取两位数月份
- 移动端测试=== adb 无线连接手机
- 一文读懂什么是cookie和session。
热门文章
- ubuntu 15.10 如何下载bt种子文件 rtorrent的安装使用方法
- 关于今天莫名其妙的刷票成功的想法
- 视频叠加字幕显示原理与实现方法
- cf服务器人连接延迟,怎么解决大部分人使用Win10系统玩穿越火线出现卡顿或延迟的情况?...
- 三款充满创意的新奇软件分享
- STM32F103电压采集proteus仿真
- ffmpeg合并M3U8加密的视频 ts 合并为 mp4
- c语言 数据结构面试题及答案,数据结构(C语言)【经典题库】含答案
- MEMS光开关的工作原理及应用
- 谷歌眼镜GDK开发指南之Camera