多.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文件初认识及计算器实例相关推荐

  1. 蓝桥杯单片机学习11——PCF8591A/DD/A转换芯片

    上期我们学习了DS1302实时时钟的基本使用,现在我们来学习PCF8591A/D&D/A转换芯片的相关内容 蓝桥杯单片机学习11--PCF8591A/D&D/A转换芯片 PCF8591 ...

  2. 【蓝桥杯-单片机学习笔记(六)】矩阵键盘控制数码管显示0~F

    一.要求 在CT107D单片机训练平台上,首先将J5处的跳线帽接到1~2引脚,使按键S4~S19组成4*4的矩阵键盘.在扫描按键的过程中,发现有按键触发信号后,待按键松开后,数码管显示相应的数字.按键 ...

  3. 蓝桥杯单片机学习13——NE555方波发生器频率测量

    NE555 简介 引脚图 原理图 真值表 工作原理 频率测量原理 定时器测量频率方法 代码实现 总结(一堆废话) 简介 NE555是一种高度稳定的控制器,内部用三个阻值为5KΩ的电阻分压,因此叫做55 ...

  4. 【蓝桥杯—单片机学习笔记(四)】共阳数码管的动态显示

    一.要求 在CT107D单片机训练综合平台上,实现数码管的动态显示,在8位数码管中,前面4位显示年份"2022",接着是2个分隔符"--",最后两位是月份,从1 ...

  5. 蓝桥杯单片机学习12——AT24C02EEPROM存储芯片

    上期我们学习了PCF8591A/D&D/A转换芯片的相关内容,这么我们来介绍以下AT24C02 AT24C02 简介 命名格式 引脚描述 原理图 IIC通信原理 读写地址 存储地址 基本控制方 ...

  6. 蓝桥杯单片机学习日记3-矩阵键盘的使用,线反转法,三步消抖,按键长按与短按

    此片文章用于记录蓝桥杯单片机的学习 篮球杯单片机上的矩阵按键原理图如下: 使用矩阵键盘时,要将跳线帽J5跳至KBD模式. 值得注意的是,若开发板上的单片机使用的为STC15,那么以上原理图适用.如果单 ...

  7. 蓝桥杯单片机学习日记1-LED 蜂鸣器 继电器 数码管的简单驱动

    此片文章用于记录蓝桥杯单片机的学习. LED 蜂鸣器 继电器 数码管 这些都是比赛时常用的外设,如下原理图:  LED部分:  蜂鸣器和继电器部分(图中还有步进电机部分):  数码管部分: 可见,上述 ...

  8. 蓝桥杯单片机学习必备资源

    目录 一.你不知道蓝桥杯单片机底层驱动改了?? 二.小蜜蜂教程--自撸代码 三.个人心得 1.NE555 2.DS1302 3.DS18B20 4.AT24C02 5.PCF8951 6.串口指令读取 ...

  9. 【蓝桥杯-单片机学习笔记(十七)】24C02原理及其读写操作

    一.24C02 24C02是一个2K Bit的串行EEPROM存储器,内部含有256个字节.在24C02里面有一个8字节的页写缓冲器.24C02支持I2C总线协议.I2C是一种双向.两线串行通信接口, ...

最新文章

  1. 文科生如何入门机器学习:先看看这篇零基础教程,再多算几遍吧
  2. Linux内核分析 - 网络[六]:网桥
  3. “万能数据库查询分析器” 5.03发布,访问EXCEL将自动为表名前后加上中括弧
  4. 多边形三角剖分问题的综述
  5. Java编写基于netty的RPC框架
  6. oracle symonym_ORACLE SYNONYM详解
  7. 剑指offer面试题12. 矩阵中的路径(矩阵搜索)(深度优先搜索)(剪枝)
  8. iOS 开发者常用的75 个工具
  9. 测试转开发,我都经历了什么
  10. 微博 用户画像_面向新浪微博的用户画像研究
  11. mysql分区为什么提高性能_通过分区(Partition)提升MySQL性能
  12. 零知识证明学习(三)—— 非交互式零知识证明(zkSNARKs)
  13. 磁力小伙伴,配合使用效果极佳!
  14. 整流器的输入滤波电容的选择
  15. 一个U盘装N款系统不是梦!超级好用的装机神器来了!
  16. C语言实现加减乘除混合运算计算器
  17. 不会就要问,求大神解决一下安装linux不认内置硬盘的问题
  18. CnOpenData中国各省份工商注册企业分年份数量统计(含新增,注销企业数量)
  19. STM32H750 QSPI FLASH使用小结
  20. 智能相机与工业相机区别与特性分析

热门文章

  1. 爱家小精灵 v6.8 免费下载
  2. php生成印章 代码片段
  3. 修车案例 | 梅赛德斯奔驰Sprinter 906动力不足
  4. Unity塔防游戏的制作与实现
  5. 服药最佳时间的选择,千万不要乱吃!
  6. CNN(经典卷积神经网络)来了!
  7. java genesis_Genesis文件问题
  8. [Android实例] 天天动听 半透明Menu效果
  9. 迈克尔杰克逊mtv_如何让您的家人看起来像在迈克尔湾电影中
  10. 把ogg转换为mp3怎么转?