【STC15F2K60S2学习笔记】五.基本模块化构建

本文介绍了C51程序的基本结构,包括预处理命令、函数定义、全局声明以及编程规范,如添加注释、命名规则、代码结构等。同时,还展示了如何通过模块化构建,如文件命名和头文件组织,提升程序的可读性和维护性。
摘要由CSDN通过智能技术生成

写在前面

        经过一段时间的学习,我们对单片机基本编程已经有了一定的了解,对于程序员来说,养成良好的编程习惯很重要,按一定规范编写程序,有助于设计者理清思路,方便程序纠错、修改、整理、阅读,是程序可维护和可移植的前提。

一、C51程序与编程规范

1.C51的程序结构

/* 程序说明、功能、设计者、设计时间、修改时间、版本描述等 */
预处理命令            //用于包含头文件等
全局变量声明;         //全局变量

函数1声明;
函数2声明;

/* 主函数 */
main()
{
    局部变量声明;
    执行语句;
    函数调用;
}

/* 其他函数定义 */
函数1
{
    局部变量声明;
    执行语句;
    函数调用;
}
1.预处理命令
//包含
#include

//宏定义以及撤销
#define
#undef

//条件编译
#if
#else
#endif

#define Today 20231202         //定义Today=20231202
#define uchar unsigned char    //可以利用宏定义简写
2.函数定义
void main()
{
    //执行main函数

    //调用自定义函数
    Key_proc();
}
void Key_proc()
{
    //执行Key_proc函数
}
3.全局声明
void Key_proc();               //函数声明,用在main函数前
4.程序注释
//单行注释规则        //
/*块式注释规则*/      /**/

2.C51编程规范

        (1) 一个好的源程序应该添加必要的注释,以增加程序的可读性。

        (2) 标志符应能直观反映其含义,避免过于冗长,方便源程序的编写、阅读与理解。

        (3) 编译系统专用标志符以下画线开头,建议自定义标志符不使用下画线为首字符。

        (4) 自定义的标志符避免与关键字或 C51 库函数同名。

        (5) 虽然 C51 语言没有限制主函数 main() 放置的位置,但为阅读方便,最好将其放在所有自定义函数的前面。程序语句的书写顺序依次为: 头文件声明、全局变量和自定义函数声明、主函数 main()、自定义函数。

        (6) 每条语句单独写一行,或将配合完成某一功能的几条短语句写在同一行,并注释。

        (7) 源程序文件中不同结构部分之间要留有空行,来明显区分不同的结构。

        (8) 对 if、for、while 等块结构语句中的“{”和“}”要配对对齐,以突出该块结构的起始和结束位置,使程序阅读更直观。

        (9) 源程序书写时,可以通过适当的 Tab 键操作来实现代码对齐。

二、模块化构建

1.文件命名

        

能够快速索引并找到所需文件的命名方式

将Dirver和User区分开

2.头文件编写

1.Key.c
#include "Key.h"

sbit Key_7=P3^0;
sbit Key_6=P3^1;
sbit Key_5=P3^2;
sbit Key_4=P3^3;

unsigned char Key_read()
{
	unsigned char temp;
	if(Key_7==0)temp=7;
	if(Key_6==0)temp=6;
	if(Key_5==0)temp=5;
	if(Key_4==0)temp=4;
	return temp;
}
2.Key.h
#include <stc15f2k60s2.h>

unsigned char Key_read();
3.Seg.c
#include "Seg.h"

unsigned char code Seg_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned char code Seg_dian[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e}; 
unsigned char code Seg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void Seg_disp(unsigned char wei,duan)
{
	//消影
	P2=(P2&0x1f)|0xc0;
	P0=0x00;
	P2&=0x1f;

	//段选
	P2=(P2&0x1f)|0xe0;
	P0=Seg_duan[duan]; 
	P2&=0x1f;

	//位选
	P2=(P2&0x1f)|0xc0;
	P0=Seg_wei[wei];
	P2&=0x1f;
}
4.Seg.h
#include <stc15f2k60s2.h>

void Seg_disp(unsigned char wei,duan);

将头文件添加进main函数

3.main函数编写

/* 头文件声明 */
#include <stc15f2k60s2.h>
#include "Key.h"
#include "Seg.h"

/* 定义 */
#define uint unsigned int
#define uchar unsigned char

/* 变量声明 */
uchar Key_slow;//10ms
uint Seg_slow;//500ms
uchar Key_val,Key_down,Key_old;//按键扫描
uchar Seg_pos;
Seg_buf[8]={2,0,2,3,1,2,0,1};//位选,段选

/* 函数声明 */
void Delay_ms(uint t);//延时函数
void Key_proc();//按键处理
void Seg_proc();
void Other_proc();
void Timer0_init();
void Timer0_ISR();

/* 代码 */
int main()//主函数
{
	Timer0_init();
	while(1)
	{
		Key_proc();
		Seg_proc();
		Other_proc();
	}
}

void Delay_ms(uint t)//11.0592MHZ延时函数
{
	uint i,n;
	for(i=t;i>0;i--)
	{
		for(n=114;n>0;n--);
	}
}

void Key_proc()//按键处理
{
	if (Key_slow) return;
	Key_slow=1;
	
	Key_val=Key_read();
	Key_down=Key_val&(Key_val^Key_old);//捕捉下降沿
	Key_old=Key_val;//辅助扫描
	
	switch(Key_down)
	{
		
	}
}

void Seg_proc()//数码管处理
{
	if (Seg_slow) return;
	Seg_slow=1;
}

void Other_proc()//其他处理
{
	
}

void Timer0_init()//定时器0初始化函数
{
  // 设置定时器0工作方式,使用模式1
  TMOD &= 0xF0;  // 清零低四位
  TMOD |= 0x01;  // 设置定时器0为模式1

  // 设置定时器0的初值,使定时器定时时间为1ms
  TH0 = (65536 - 11052/12) / 256;  // 高八位
  TL0 = (65536 - 11052/12) % 256;  // 低八位

  // 启动定时器0
  TR0 = 1;

  // 允许定时器0中断
  ET0 = 1;
  EA = 1;  // 允许总中断
}

void Timer0_ISR() interrupt 1 //中断服务函数
{
	TH0 = (65536 - 11052/12) / 256;
    TL0 = (65536 - 11052/12) % 256;
	if(++Key_slow==10)Key_slow=0;
	if(++Seg_slow==500)Seg_slow=0;
	if(++Seg_pos==8)Seg_pos=0;
	Seg_disp(Seg_pos,Seg_buf[Seg_pos]);
}

编译时遇到一个警告是正常的,因为有一个Delay_ms的函数没有被使用,到这里stc15f2k60s2单片机的初步模块化就完成了。

无限进步

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这里是扁芒吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值