学习笔记|回顾(1-12节课)|应用模块化的编程|添加函数头|静态变量static|STC32G单片机视频开发教程(冲哥)|阶段小结:应用模块化的编程(上)

文章目录

  • 1.回顾(1-12节课)
  • 2.应用模块化的编程(.c + .h)
    • Tips:添加函数头
    • 创建程序文件三步
    • 引脚定义都在.h文件
    • 函数定义三步
    • bdata位寻址变量的使用
  • 3.工程文件编写
    • 静态变量static的使用
    • 完整程序为:
      • demo.c:
      • seg_led.c:
      • seg_led.h:

1.回顾(1-12节课)

一、认识单片机
二、了解单片机硬件(介绍开发板)
三、开发环境搭建和下载,新工程建立资料下载
四、点亮点一个LED(CDC和HID下载)		--GPIO
五、C语言运算符和进制数入门
六、LED闪烁和花式点灯       			--GPIO
七、按键点亮灯					--GPIO
八、蜂鸣器					--GPIO
九、数码管的静态使用				--GPIO
十、数码管动态点亮 				--GPIO
十一、定时器					--TIM
十二、计数器的使用				--TIM

重点理清程序的逻辑思路。重点理清程序的逻辑思路。重点理清程序的逻辑思路。什么时候打开LED?LED打开多久?什么时候切换数码管显示?什么时候按键按下触发什么功能?
之前的课主要是带大家熟悉写程序的方法,分析逻辑,实现我们要的功能。
那么这一节课开始,我们要规范程序,符合我们工程师级别的代码规范。

2.应用模块化的编程(.c + .h)

一、LED & 数码管 --led_seg.c, led_seg.h
二、按键 --key.c, key.h
三、蜂鸣器 --beep.c, beep.h
四、定时器 --tim.c, tim.h
一个功能对应一个.c和.h

Tips:添加函数头

//========================================================================
// 函数名称:
// 函数功能:
// 入口参数: @
// 函数返回:
// 当前版本: VER1.0
// 修改日期: 2023
// 当前作者:
// 其他备注:
//========================================================================
在keil中设置:
在这里插入图片描述

在这里插入图片描述
添加后,重启软件就可以使用了。

创建程序文件三步

新建文件并保存
添加到工程
添加引用路径

引脚定义都在.h文件

sbit 名称 = P10;
#define 名称 P10

函数定义三步

定义
声明
调用

修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。
举例1:如果文件a.c需要引用b.c中变量int v,就可以在a.c中声明extern int v,然后就可以引用变量v。
举例2:如果文件a.c需要引用b.c中变量int v,就可以在b.h中声明extern int v,然后a.c调用b.h就可以引用变量v。
注意extern修饰的变量不能赋初值。
详细介绍可参考:extern关键字,C语言extern关键字用法详解。

bdata位寻址变量的使用

a.c a.h
u8 bdata LED = 0x00; extern u8 bdata LED;
sbit LED0 = LED^0; extern bit LED0;
sbit LED1 = LED^1; extern bit LED1;

3.工程文件编写

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
因为他们公用P6端口,所以给他们放在了一个文件。

之前的程序是在定时器中通过一个函数刷新数码管,现在就要给他增加刷新LED的功能。这里刷新显示,在别的地方赋值。
利用上节的文件,复制成工程9.TIM多任务,进入,新建目录(路径)HARDWARE,所有子程序都放入,本次要写的4个功能分别建立4个文件夹:
在这里插入图片描述

打开project,选择Add New ltem to Group ‘source Group 1’…
在这里插入图片描述

就可以在LED目录中新建seg_led.c和seg_led.h:
在这里插入图片描述

添加引用路径:
在这里插入图片描述

至此,工程文件模板就建立了。
seg_led.h修改,添加infdef预定义:

#ifndef __SEG_LED_H
#define __SEG_LED_H#include "COMM/stc.h"		//调用头文件
#include "COMM/usb.h"#endif

可以将此预定义存为template,方便使用。
在seg_led.c和demo.c中都增加对seg_led.h的调用。
将demo.c中数码管的功能移植至seg_led.c中:

u8 SEG_Tab[21] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff};	//共21个字节:0-9段码共10个,0-9带小数点共10个,全部不显示共1个,
u8 COM_Tab[8] = { 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe };																	//0-7的位码数组
u8 Show_Tab[8] = {20,20,20,20,20,20,20,20};

静态变量static的使用

如果要在其他文件中控制变量Show_Tab用于显示,则需要将其放在.h文件中作为外部变量:extern u8 Show_Tab[8];
移植void SEG_Fre(void),在函数体中增加static 变量,静态变量,第一次执行的时候再赋初始值,定义:static int num = 0;
如果不加static,每次进入函数后都会重新赋为0 ,不会刷新第2位以后的值,故需要使用静态变量,只赋值一次。
删除主函数中冗余代码,在.h文件中加入数码管赋初值。

编译,选目标文件,下载完成,数码管显示0-7,但led还是不亮,需要加入相应点亮刷新代码。
seg_led.h中定义LED的显示变量和电源开关:

extern u8 LED_DATA;		//LED的显示变量#define LED_POW P40 	//P40是led的电源开关

seg_led.c中更新刷新函数SEG_Fre:

void SEG_Fre( void )
{static int num = 0;if(num <=7 )						//num==0-7的执行{LED_POW = 0;					//关闭LED电源SEG_COM = COM_Tab[num];			//相应数码管位码的选择SEG_SEG = SEG_Tab[Show_Tab[num]];//需要显示的数字的内码}else if ( num <= 8 )				//num==8的执行{LED_POW = 0;					//LED刷新,打开电源SEG_COM = 0xff;					//关闭数码管SEG_SEG = LED_DATA;				//输出LED状态}else								//num==9的执行{LED_POW = 1;					//LED关闭电源SEG_COM = 0xff;					//关闭数码管SEG_SEG = 0xff;					//关闭所有段码信号}num++;if( num >=10 )num = 0;						//num清零
}

demo.c中对LED赋初值:

LED_DATA = 0x0f;	//赋初值,亮一半灭一半

完整程序为:

demo.c:

#include "COMM/stc.h"		//调用头文件
#include "COMM/usb.h"
#include "seg_led.h"#define KEY1 P32		//定义一个按键 引脚选择P32
#define KEY2 P33		//定义一个按键 引脚选择P33#define BEEP P54		//定义一个按键 引脚选择P54#define SEG_Delay  1	//延时多少ms#define MAIN_Fosc 24000000UL	//定义主时钟char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";u32 TimCount = 0;		//计数单位1ms
bit RUN_State = 0;		//开始运行/结束运行
u8 num = 0;
u16 Count_T1 = 0;void sys_init();	//函数声明
//void delay_ms(u16 ms);	//unsigned int
//void INT1_Isr(void);
void Timer0_Isr(void);void main()					//程序开始运行的入口
{sys_init();				//USB功能+IO口初始化usb_init();				//usb库初始化EA = 1;					//CPU开放中断,打开总中断。//数码管初始化,显示0-7:Show_Tab[0] = 0;Show_Tab[1] = 1;Show_Tab[2] = 2;Show_Tab[3] = 3;Show_Tab[4] = 4;Show_Tab[5] = 5;Show_Tab[6] = 6;Show_Tab[0] = 7;LED_DATA = 0x0f;	//赋初值,亮一半灭一半while(1)		//死循环{if( DeviceState != DEVSTATE_CONFIGURED ) 	//continue;if( bUsbOutReady ){usb_OUT_done();}}
}void sys_init()		//函数定义
{WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快EAXFR = 1; //扩展寄存器(XFR)访问使能CKCON = 0; //提高访问XRAM速度P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口P3M0 = 0x00;P3M1 = 0x00;P3M0 &= ~0x03;P3M1 |= 0x03;//设置USB使用的时钟源IRC48MCR = 0x80;    //使能内部48M高速IRCwhile (!(IRC48MCR & 0x01));  //等待时钟稳定USBCLK = 0x00;	//使用CDC功能需要使用这两行,HID功能禁用这两行。USBCON = 0x90;
}//void delay_ms(u16 ms)	//unsigned int
//{
//	u16 i;
//	do
//	{
//		i = MAIN_Fosc/6000;
//		while(--i);
//	}while(--ms);
//}void Timer0_Isr(void) interrupt 1 //1ms进来执行一次,无需其他延时,重复赋值
{SEG_Fre();		//数码管刷新1ms执行一次}//void INT1_Isr(void) interrupt 3 //计时器中断
//{
//	//P60 = !P60; //led取反
//}

seg_led.c:

#include "seg_led.h"u8 SEG_Tab[21] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff};	//共21个字节:0-9段码共10个,0-9带小数点共10个,全部不显示共1个,
u8 COM_Tab[8]  = { 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe };																	//0-7的位码数组
u8 Show_Tab[8] = {20,20,20,20,20,20,20,20}; 																					//数码管显示数组,上电后,全部关闭显示
//u8 LED_DATA  =  0xff;																											//LED初始全部熄灭void SEG_Fre( void )
{static int num = 0;if(num <=7 )						//num==0-7的执行{LED_POW = 0;					//关闭LED电源SEG_COM = COM_Tab[num];			//相应数码管位码的选择SEG_SEG = SEG_Tab[Show_Tab[num]];//需要显示的数字的内码}else if ( num <= 8 )				//num==8的执行{LED_POW = 0;					//LED刷新,打开电源SEG_COM = 0xff;					//关闭数码管SEG_SEG = LED_DATA;				//输出LED状态}else								//num==9的执行{LED_POW = 1;					//LED关闭电源SEG_COM = 0xff;					//关闭数码管SEG_SEG = 0xff;					//关闭所有段码信号}num++;if( num >=10 )num = 0;						//num清零
}

seg_led.h:

#ifndef __SEG_LED_H
#define __SEG_LED_H#include "COMM/stc.h"		//调用头文件
#include "COMM/usb.h"extern u8 Show_Tab[8];		//数码管的内码显示变量
extern u8 LED_DATA;		//LED的显示变量//------------------------引脚定义------------------------//
#define SEG_SEG P6
#define SEG_COM P7
#define LED_POW P40 	//P40是led的电源开关void SEG_Fre(void);  		//仅声明#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70962.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文件上传漏洞-upload靶场13-16关 (图片木马-文件包含与文件上次漏洞)

文件上传漏洞-upload靶场13-16关 &#xff08;图片木马-文件包含与文件上次漏洞&#xff09; 简介 upload靶场到了第十三关&#xff0c;难度就直线上升了&#xff0c;在最后这7关中&#xff0c;包含了图片木马、竞争条件等上传技巧&#xff0c;这些漏洞的本质&#xff0c;都是…

重复的DNA序列(力扣)JAVA

DNA序列 由一系列核苷酸组成&#xff0c;缩写为 ‘A’, ‘C’, ‘G’ 和 ‘T’.。 例如&#xff0c;“ACGAATTCCG” 是一个 DNA序列 。 在研究 DNA 时&#xff0c;识别 DNA 中的重复序列非常有用。 给定一个表示 DNA序列 的字符串 s &#xff0c;返回所有在 DNA 分子中出现不止…

Vite,Vue3项目引入dataV报错的解决方法

背景:开发一个大屏项目中,需要是要DataV的那边边框,装饰等,只是DataV是基于vue2的,vue3版的作者还在开发中,于是翻了DataV的源码,发现使用esm方式时是直接引入源码而不经过打包,其源码中使用的vue语法vue3也支持,所以可以直接在vue3中引入使用. vite,vue3项目直接引入DataV 安…

Upload-labs 1~15 通关详细教程

文章目录 Upload-labs 1~15 通关详细教程Pass-01-前端js验证Pass-02-后端MIME验证Pass-03-黑名单验证Pass-04-黑名单验证.htaccessPass-05-文件后缀名大小写绕过Pass-06-文件后缀名空格绕过Pass-07-文件后缀名点绕过Pass-08-文件后缀名::$DATA绕过Pass-09-点空格点空格绕过Pass…

《Market Insight:中国低代码/零代码市场发展洞察 ( 2023 )》报告正式发布 | LowCode低码时代

数字化浪潮下&#xff0c;低代码/零代码通过提升“开发生产力”将极大促进技术应用效率和产业数字化进程。目前中国的低代码/零代码在制造业、政务与公共事业、金融、电商等领域取得了一定的应用成效。而伴随着生成式AI技术的应用突破&#xff0c;低代码/零代码市场又将迎来新的…

【前端】React项目初体验

React介绍 React 是一个非常流行的 JavaScript 前端框架&#xff0c;它为开发人员提供了一种快速构建高质量用户界面的方式。以下是使用 React 构建项目的初体验&#xff1a; 安装 React 和相关依赖项 使用 React 开发项目需要先安装一些必需的依赖项&#xff0c;包括 Node.…

快速掌握STM32工程创建

STM32 工程创建-- 使用Keil uVision5 软件 晓理紫 1 准备库函数库 STM32F10x_StdPeriph_Lib_V3.5.0 VX 搜索“晓丽紫”关注回复STM32F10x即可下载 2、创建一个目录用来存放工程 STM32Study STM32Study/study1 存放本次工程目录 3、打开Keil uVision5 创建工程 4、选择型号(根据…

【用unity实现100个游戏之9】使用Unity制作类八方旅人、饥荒风格的俯视角2.5D游戏

前言 2.5D游戏 是一种介于二维和三维之间的游戏形式。它通常在二维平面上展示游戏内容&#xff0c;但利用三维技术来实现更加逼真的图像效果。 在2.5D游戏中&#xff0c;角色和环境通常是以平面的形式呈现&#xff0c;但可以在垂直方向上移动。这意味着玩家可以在一个相对较薄…

对话永洪科技CEO何春涛:专注BI,决胜AI时代丨数据猿专访

大数据产业创新服务媒体 ——聚焦数据 改变商业 大数据、云计算、人工智能为代表的新一代信息技术走向普及&#xff0c;数据驱动业务&#xff0c;逐渐成为现代化企业管理、运作的日常。对于年均复合增长率超过20%的国内商业智能&#xff08;BI&#xff09;市场而言&#xff0c…

编译KArchive在windows10下

使用QT6和VS2019编译KArchive的简要步骤&#xff1a; 安装 Qt &#xff0c;我是用源码自己编译的 "F:\qtbuild"安装CMakefile并配置环境变量安装Git下载ECM源码 https://github.com/KDE/extra-cmake-modules.git-------------------------------------------------…

运筹系列85:求解大规模tsp问题的julia代码

1. 大规模tsp问题的挑战 数学模型和精确解法见《运筹系列65&#xff1a;TSP问题的精确求解法概述》和《运筹系列80:使用Julia精确求解tsp问题》&#xff1a; variable(m, x[1:n,1:n], Bin,Symmetric) # 0-1约束 objective(model, Min, sum(x.*distmat)/2) constraint(model, …

计算机视觉的应用13-基于SSD模型的城市道路积水识别的应用项目

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用13-基于SSD模型的城市道路积水识别的应用项目。今年第11号台风“海葵”后部云团的影响&#xff0c;福州地区的降雨量突破了历史极值&#xff0c;多出地方存在严重的积水。城市道路积水是造成交通拥…

javaee之黑马乐优商城2

简单分析一下商品分类表的结构 先来说一下分类表与品牌表之间的关系 再来说一下分类表和品牌表与商品表之间的关系 面我们要开始就要创建sql语句了嘛&#xff0c;这里我们分析一下字段 用到的数据库是heima->tb_category这个表 现在去数据库里面创建好这张表 下面我们再去编…

Unexpected mutation of “xxxx“ prop

原因 是因为子级修改了父级的数据&#xff0c;所以eslint执行的时候报了这个错 修复方式 1 如果是弹窗等组件&#xff0c;可以根据功能进行修改&#xff0c;比如我这块用的 element ui 的 dialog&#xff0c;便可以改成这样 使用 model-value 代替 修复方式 2 新建子组件…

3种等待方式,让你学会Selenium设置自动化等待测试脚本!

一、Selenium脚本为什么要设置等待方式&#xff1f;——即他的应用背景到底是什么 应用Selenium时&#xff0c;浏览器加载过程中无法立即显示对应的页面元素从而无法进行元素操作&#xff0c;需设置一定的等待时间去等待元素的出现。&#xff08;简单来说&#xff0c;就是设置…

CTFSHOW 年CTF

1.除夕 php的弱类型&#xff0c;用小数点绕过 这里后面直接加字母不行 2.初三 error_reporting(0); extract($_GET); include "flag.php"; highlight_file(__FILE__); 这里通过extract将get的参数导入为了变量 $_function($__,$___){return $__$___?$___:$__; }; …

恒运资本:银行股适合定投吗?为什么银行股适合定投?

在股票市场上&#xff0c;出资者能够通过手动不断的买入到达基金定投的效果&#xff0c;那么&#xff0c;银行股适合定投吗&#xff1f;为什么银行股适合定投&#xff1f;下面恒运资本为我们准备了相关内容&#xff0c;以供参考。 银行股适合定投&#xff0c;即通过定投不断的买…

索尼 toio™ 应用创意开发征文|小巧机器,大无限,探索奇妙世界

文章目录 前言微型机器人的未来&#xff1a;toio™小机器人简介toio™小机器人&#xff1a;创新功能一览toio™小机器人&#xff1a;多领域的变革者toio™小机器人贪吃蛇游戏代码实现写在最后 前言 当我们谈到现代科技的创新时&#xff0c;往往会联想到复杂的机器和高级的编程…

Linux CentOS7命令及命令行

Linux CentOS7中命令及命令行是非常重要的概念。对大多数初学者来说是既熟悉又了解甚少。本文初步讨论这方面的内容&#xff0c;与同行者交流。 一、命令 命令又称为指令&#xff0c;&#xff08;英语命令 command&#xff0c;可用简写cmd表示&#xff09;&#xff0c;在终端…

小程序引入高德/百度地图坐标系详解

小程序引入高德/百度地图坐标系详解 官网最近更新时间&#xff1a;最后更新时间: 2021年08月17日 高德官网之在原生小程序中使用的常见问题 链接 目前在小程序中使用 高德地图只支持以下功能 &#xff1a;地址描述、POI和实时天气数据 小结&#xff1a;从高德api中获取数…