完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
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 = num %10; num = num / 10; } for(i=5;i>0;i--) { if (buf==0) LedBuf = 0xFF; else break; } for(;i>=0;i--) { LedBuf = LedChar[buf]; } } 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[j] != KeySta[j]) { if(backup[j] != 0) { KeyAction(KeyCodeMap[j]); } backup[j] = KeySta[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] & 0x0F) == 0x00) { KeySta[keyout] = 0; } else if((keybuf[keyout] & 0x0F) == 0x0F) { KeySta[keyout] = 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; ***it KeyOut_1 = P3^0; ***it KeyOut_2 = P3^1; ***it KeyOut_3 = P3^2; ***it KeyOut_4 = P3^3; ***it KeyIn_1 = P4^4; ***it KeyIn_2 = P4^2; ***it KeyIn_3 = P3^5; ***it KeyIn_4 = P3^4; void KeyDriver(); void KeyScan(); void KeyAction(u8 keycode); extern void LedShow(u32 num); #endif |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2956 浏览 16 评论
3458 浏览 1 评论
8996 浏览 16 评论
4051 浏览 18 评论
1108浏览 3评论
572浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1858浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 19:44 , Processed in 0.943541 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号