【蓝桥杯】单片机学习(9)——多.c文件初认识及计算器实例
多.C文件+计算机实例
- 1、多.C文件的初步认识
- extern关键字说明
- 2、实例(CT107D开发板)
- main.c代码:
- system.h代码
- smg.c代码:
- key.c代码:
- system.h代码:
- smg.h代码:
- key.h代码:
1、多.C文件的初步认识
随着使用的硬件模块的增多,程序量逐步增大,为了方便代码的编写、维护和移植,通常采用多.C文件的形式。将按键、数码管、Lcd1602液晶、I2C等各个模块分别写一个.C文件,里面包含各自的底层驱动代码,再写出对应的头文件。这样在编写main.C文件时,需要使用哪个模块,只需要添加对应的头文件即可。
extern关键字说明
extern
关键字 用于外部变量的声明,而不是定义。我们需要在第一次用到该变量的.c文件中声明并定义该变量,其他的.c文件如果需要再次使用该变量,我们只需要声明即可,告诉系统这个变量是存在的,不需要再重复定义。(否则会报错)
以数码管的真值定义为例,我们只需要在smg.c文件中定义该变量,如下:(假设第一个使用到该变量的是SMG.c文件)
unsigned char code LedChar[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f}; //共阳极数码管从0到F的真值
如果我们在main.c中也需要使用到这个变量,只需要在main.c中做如下声明(和首次声明保持一致,code
不能少),而不需要再次定义。
extern unsigned char code LedChar[];
2、实例(CT107D开发板)
通过按键和数码管模块写一个简易整数加法计算器,不考虑连加、连减等连续计算,不考虑小数情况。
main.c代码:
#include"key.h"
#include"smg.h"
#include"system.h"extern u8 LedBuf[] ;
extern u8 code LedChar[];void main()
{All_Int();EA = 1;TMOD = 0x01;TH0 = 0xFC;TL0 = 0x67;ET0 = 1;TR0 = 1;LedBuf[0] = LedChar[0];while(1){KeyDriver();}
}void InterruptTimer0() interrupt 1
{TH0 = 0xFC;TL0 = 0x67;LedScan();KeyScan();
}
system.h代码
#include"system.h"void All_Int()
{P2 = (P2&0x1F)|0x80;//Y4,关闭LED灯P0 = 0xFF;P2 = (P2&0x1F)|0xa0;//Y6,关闭蜂鸣器,继电器P2 = 0x00;P2 = (P2&0x1F)|0xe0;//Y7,段选,关闭数码管P0 = 0xFF;
}
smg.c代码:
#include"smg.h"u8 code LedChar[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f}; //共阳极数码管从0到F的真值u8 LedBuf[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//数码管显示缓冲区void LedScan()
{static u8 index = 0;P2 = (P2&0x1F)|0xe0;//段选P0 = 0xff;P2 = (P2&0x1F)|0xc0;//位选P0 = 0x80>>index;P2 = (P2&0x1F)|0xe0;//段选P0 = LedBuf[index];index++;index &= 0x07;//加到7之后自动清0
}void LedShow(u32 num)
{signed char i;u8 buf[6];for(i=0;i<6;i++){buf[i] = num %10;num = num / 10;}for(i=5;i>0;i--){if (buf[i]==0)LedBuf[i] = 0xFF;elsebreak;}for(;i>=0;i--){LedBuf[i] = LedChar[buf[i]];}
}
key.c代码:
#include"key.h"u8 code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表{ '1', '2', '3', 0x26 }, //数字键1、数字键2、数字键3、向上键{ '4', '5', '6', 0x25 }, //数字键4、数字键5、数字键6、向左键{ '7', '8', '9', 0x28 }, //数字键7、数字键8、数字键9、向下键{ '0', 0x1B, 0x0D, 0x27 } //数字键0、ESC键、 回车键、 向右键
};u8 KeySta[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};//保存按键值的当前状态//按键动作函数
void KeyAction(u8 keycode)
{static u32 result = 0;static u32 attend;if(keycode>='0' & keycode<='9'){attend = (attend * 10) + (keycode - 0x30);LedShow(attend);} else if(keycode == 0x26)//加法{result += attend;attend = 0;LedShow(result);}else if(keycode == 0x0D)//回车键执行加法运算,实际效果与加号相同{result += attend;attend = 0;LedShow(result); }else if(keycode == 0x1B)//Esc键,清零{attend = 0;result = 0;LedShow(attend); }
}//按键驱动函数,检测是否有按键按下
void KeyDriver()
{u8 i,j;static u8 backup[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}}; //按键备份,保存前一次的值for(i=0; i<4; i++){for(j=0; j<4; j++){if(backup[i][j] != KeySta[i][j]){if(backup[i][j] != 0){KeyAction(KeyCodeMap[i][j]);}backup[i][j] = KeySta[i][j];}}}}//按键扫描函数,在定时中断中调用,一般使用间隔1ms
void KeyScan()
{u8 i;static keyout = 0;static keybuf[4][4] = {{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}};keybuf[keyout][0]=(keybuf[keyout][0]<<1) | KeyIn_1;keybuf[keyout][1]=(keybuf[keyout][1]<<1) | KeyIn_2;keybuf[keyout][2]=(keybuf[keyout][2]<<1) | KeyIn_3;keybuf[keyout][3]=(keybuf[keyout][3]<<1) | KeyIn_4; for(i=0;i<4;i++){if((keybuf[keyout][i] & 0x0F) == 0x00){KeySta[keyout][i] = 0;}else if((keybuf[keyout][i] & 0x0F) == 0x0F){KeySta[keyout][i] = 1;}} keyout++;keyout &= 0x03;switch(keyout){case 0:KeyOut_4 = 1;KeyOut_1 = 0;break;case 1:KeyOut_1 = 1;KeyOut_2 = 0;break;case 2:KeyOut_2 = 1;KeyOut_3 = 0;break;case 3:KeyOut_3 = 1;KeyOut_4 = 0;break;default :break;}
}
system.h代码:
#ifndef __SYSTEM_H
#define __SYSTEM_H#include"reg52.h"
#include"intrins.h"typedef unsigned char u8;
typedef unsigned int u16;//void All_Init();#endif
smg.h代码:
#ifndef __SMG_H
#define __SMG_H#include"system.h"void LedScan();
void LedShow(u32 num);#endif
key.h代码:
#ifndef __KEY_H
#define __KEY_H#include"system.h"sfr P4 = 0xC0;sbit KeyOut_1 = P3^0;
sbit KeyOut_2 = P3^1;
sbit KeyOut_3 = P3^2;
sbit KeyOut_4 = P3^3;sbit KeyIn_1 = P4^4;
sbit KeyIn_2 = P4^2;
sbit KeyIn_3 = P3^5;
sbit KeyIn_4 = P3^4;void KeyDriver();
void KeyScan();
void KeyAction(u8 keycode);
extern void LedShow(u32 num);#endif
补充: Keil 5模块化编程详细步骤
前一篇: 单片机学习(8)——1602液晶
下一篇: 单片机学习(10)——I2C通信协议与E2PROM
【蓝桥杯】单片机学习(9)——多.c文件初认识及计算器实例相关推荐
- 蓝桥杯单片机学习11——PCF8591A/DD/A转换芯片
上期我们学习了DS1302实时时钟的基本使用,现在我们来学习PCF8591A/D&D/A转换芯片的相关内容 蓝桥杯单片机学习11--PCF8591A/D&D/A转换芯片 PCF8591 ...
- 【蓝桥杯-单片机学习笔记(六)】矩阵键盘控制数码管显示0~F
一.要求 在CT107D单片机训练平台上,首先将J5处的跳线帽接到1~2引脚,使按键S4~S19组成4*4的矩阵键盘.在扫描按键的过程中,发现有按键触发信号后,待按键松开后,数码管显示相应的数字.按键 ...
- 蓝桥杯单片机学习13——NE555方波发生器频率测量
NE555 简介 引脚图 原理图 真值表 工作原理 频率测量原理 定时器测量频率方法 代码实现 总结(一堆废话) 简介 NE555是一种高度稳定的控制器,内部用三个阻值为5KΩ的电阻分压,因此叫做55 ...
- 【蓝桥杯—单片机学习笔记(四)】共阳数码管的动态显示
一.要求 在CT107D单片机训练综合平台上,实现数码管的动态显示,在8位数码管中,前面4位显示年份"2022",接着是2个分隔符"--",最后两位是月份,从1 ...
- 蓝桥杯单片机学习12——AT24C02EEPROM存储芯片
上期我们学习了PCF8591A/D&D/A转换芯片的相关内容,这么我们来介绍以下AT24C02 AT24C02 简介 命名格式 引脚描述 原理图 IIC通信原理 读写地址 存储地址 基本控制方 ...
- 蓝桥杯单片机学习日记3-矩阵键盘的使用,线反转法,三步消抖,按键长按与短按
此片文章用于记录蓝桥杯单片机的学习 篮球杯单片机上的矩阵按键原理图如下: 使用矩阵键盘时,要将跳线帽J5跳至KBD模式. 值得注意的是,若开发板上的单片机使用的为STC15,那么以上原理图适用.如果单 ...
- 蓝桥杯单片机学习日记1-LED 蜂鸣器 继电器 数码管的简单驱动
此片文章用于记录蓝桥杯单片机的学习. LED 蜂鸣器 继电器 数码管 这些都是比赛时常用的外设,如下原理图: LED部分: 蜂鸣器和继电器部分(图中还有步进电机部分): 数码管部分: 可见,上述 ...
- 蓝桥杯单片机学习必备资源
目录 一.你不知道蓝桥杯单片机底层驱动改了?? 二.小蜜蜂教程--自撸代码 三.个人心得 1.NE555 2.DS1302 3.DS18B20 4.AT24C02 5.PCF8951 6.串口指令读取 ...
- 【蓝桥杯-单片机学习笔记(十七)】24C02原理及其读写操作
一.24C02 24C02是一个2K Bit的串行EEPROM存储器,内部含有256个字节.在24C02里面有一个8字节的页写缓冲器.24C02支持I2C总线协议.I2C是一种双向.两线串行通信接口, ...
最新文章
- 文科生如何入门机器学习:先看看这篇零基础教程,再多算几遍吧
- Linux内核分析 - 网络[六]:网桥
- “万能数据库查询分析器” 5.03发布,访问EXCEL将自动为表名前后加上中括弧
- 多边形三角剖分问题的综述
- Java编写基于netty的RPC框架
- oracle symonym_ORACLE SYNONYM详解
- 剑指offer面试题12. 矩阵中的路径(矩阵搜索)(深度优先搜索)(剪枝)
- iOS 开发者常用的75 个工具
- 测试转开发,我都经历了什么
- 微博 用户画像_面向新浪微博的用户画像研究
- mysql分区为什么提高性能_通过分区(Partition)提升MySQL性能
- 零知识证明学习(三)—— 非交互式零知识证明(zkSNARKs)
- 磁力小伙伴,配合使用效果极佳!
- 整流器的输入滤波电容的选择
- 一个U盘装N款系统不是梦!超级好用的装机神器来了!
- C语言实现加减乘除混合运算计算器
- 不会就要问,求大神解决一下安装linux不认内置硬盘的问题
- CnOpenData中国各省份工商注册企业分年份数量统计(含新增,注销企业数量)
- STM32H750 QSPI FLASH使用小结
- 智能相机与工业相机区别与特性分析