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

news2024/11/18 1:27:25

文章目录

  • 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高速IRC
    while (!(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.coloradmin.cn/o/984685.html

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

相关文章

数字化新零售营销模式如何落地?数字化新零售营销功能推荐

​通过科技手段&#xff0c;针对对线下零售店面的客户进行消费行为、频次等的分析&#xff0c;并进一步整合线上线下资源&#xff0c;实现实体零售的效率充分化&#xff0c;便是目前很火的新零售营销模式&#xff0c;能够将实体门店与数字化技术进行有机结合&#xff0c;通过为…

在Photoshop上标小图标的操作记录

1、做小图标 收集背景图 的背景的rgb值 把这个rgb值记下来&#xff0c;上面的背景要用。 2、统一图标大小 宽度、高度&#xff0c;都设置成1.52 3、把图标往地图上拖 拖到背景图上&#xff0c;可以用上下左右键调整位置 4、在图片上写字 右键这个&#xff0c;就可以写字了。…

SpringBoot / Vue 对SSE的基本使用(简单上手)

一、SSE是什么&#xff1f; SSE技术是基于单工通信模式&#xff0c;只是单纯的客户端向服务端发送请求&#xff0c;服务端不会主动发送给客户端。服务端采取的策略是抓住这个请求不放&#xff0c;等数据更新的时候才返回给客户端&#xff0c;当客户端接收到消息后&#xff0c;…

异步编程 - 06 基于JDK中的Future实现异步编程(中)_CompletableFuture源码解析

文章目录 CompletableFuture 类图结构CompletionStage接口属性resultstackasyncPool 方法CompletableFuture<Void>runAsync(Runnable runnable)CompletableFuture<U> supplyAsync(Supplier<U>supplier)CompletableFuture<U> supplyAsync(Supplier<U…

【java】【SSM框架系列】【一】Spring

目录 一、简介 1.1 为什么学 1.2 学什么 1.3 怎么学 1.4 初识Spring 1.5 Spring发展史 1.6 Spring Framework系统架构图 1.7 Spring Framework学习线路 二、核心概念&#xff08;IoC/DI&#xff0c;IoC容器&#xff0c;Bean&#xff09; 2.1 概念 2.2 IoC入门案例 …

TVC广告片制作成本多少

电视是广告传播的主要媒介之一&#xff0c;具有广泛的受众群体和较高的覆盖率。通过在电视上播放广告片&#xff0c;企业可以将产品或者服务的信息传达给大量潜在客户&#xff0c;提高知名度和曝光度。接下来由深圳TVC广告片制作公司老友记小编从以下几个方面浅析制作一条TVC广…

SAP PI 配置SSL链接接口报错问题处理Peer certificate rejected by ChainVerifier

出现这种情况一般无非是没有正确导入证书或者证书过期的情况 第一种&#xff0c;如果没有导入证书的话&#xff0c;需要在NWA中的证书与验证-》CAs中导入管理员提供的证书&#xff0c;这里需要注意的是&#xff0c;需要导入完整的证书链。 第二种如果是证书过期的&#xff0c…

Java + Selenium + Appium自动化测试

一、启动测试机或者Android模拟器&#xff08;Genymotion俗称世界上最快的模拟器&#xff0c;可自行百度安装&#xff09; 二、启动Appium&#xff08;Appium环境安装可自行百度&#xff09; 三、安装应用到Genymotion上&#xff0c;如下图我安装一个计算机的小应用&#xff…

vit模型

AN IMAGE IS WORTH 16X16 WORDS:TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE 1、问题2、模型结构 1、问题 在视觉方面&#xff0c;注意力要么与卷积网络结合使用&#xff0c;要么用于替代卷积网络的某些组件&#xff0c;同时保持其整体结构不变。 我们证明了这种对CNNs的依赖…

【C#】关于Array.Copy 和 GC

关于Array.Copy 和 GC //一个简单的 数组copy 什么情况下会触发GC呢[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]public static void Copy(Array sourceArray,long sourceIndex,Array destinationArray,long destinationIndex,long length);当源和目…

微服务·架构组件之网关- Spring Cloud Gateway

微服务架构组件之网关- Spring Cloud Gateway 引言 微服务架构已成为构建现代化应用程序的关键范式之一&#xff0c;它将应用程序拆分成多个小型、可独立部署的服务。Spring Cloud Gateway是Spring Cloud生态系统中的一个关键组件&#xff0c;用于构建和管理微服务架构中的网…

芯片方案应用于终端产品时需要哪些技术支持和保障?

在芯片方案应用于终端产品时&#xff0c;客户可能会遇到三大类问题&#xff1a;一是芯片本身的质量缺陷&#xff1b;二是芯片与终端系统软硬件联合调试及验证&#xff1b;三是终端生产。 接下来&#xff0c;小编简短介绍启英泰伦是如何全方位支持客户项目&#xff0c;保障客户…

mac m1 代码调用 Stable Diffusion

from diffusers import DiffusionPipeline import torchpipe DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5") pipe pipe.to("mps") pipe.enable_attention_slicing()prompt "便利店开业" _ pipe(prompt, num_inferen…

分享一个基于SpringBoot+Vue的房屋在线装修预约系统源码

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…

python读取.txt文件中某些关键字后面的内容 并根据该数据画图

感谢一下悦姐帮忙 import re#先把文件读进来&#xff0c;用read读入的是字符串&#xff0c;readlines是list with open(resok.txt) as f:txt f.read()dataset r5low:.*|5mix:.*|5normal:.* para rMAE: (.{6})#意思是MAE&#xff1a; 后面的六个东西 row_data re.findall(d…

6个免费图片素材库,高清无水印、无版权

推荐6个免费高清图片素材库&#xff0c;商用也可以&#xff0c;无需担心版权问题&#xff0c;收藏走一波~ 1、菜鸟图库 https://www.sucai999.com/pic.html?vNTYwNDUx 网站主要为新手设计师提供免费素材&#xff0c;这些素材的质量都很高&#xff0c;类别也很多&#xff0c;…

每日一练 | 网络工程师软考真题Day31

阅读以下说明&#xff0c;答复以下【问题1】至【问题7】 【说明】 某网络拓扑结构如图3-1所示。网络A中的DNS_Server1和网络B中的DNS_Server2分别安装有Windows Server 2003并启用了DNS效劳。DNS_Server1中安装有IIS6.0&#xff0c;建立了一个域名为 abc 的Web站点。 图3-1 【…

pytorch再次学习

目录 数据可视化切换设备device定义类打印每层的参数大小自动微分计算梯度禁用梯度追踪优化模型参数 模型保存模型加载 数据可视化 import torch from torch.utils.data import Dataset from torchvision import datasets from torchvision.transforms import ToTensor import…

Nginx中实现自签名SSL证书生成与配置

文章目录 一.相关介绍1.生成步骤2.相关名词介绍 二.Nginx中实现自签名SSL证书生成与配置1.私钥生成2.公钥生成3.生成解密的私钥key4.签名生成证书5.配置证书并验证6.登录 一.相关介绍 1.生成步骤 &#xff08;1&#xff09;生成私钥&#xff08;Private Key&#xff09;&…

elementUI——el-table自带排序使用问题

问题 排序表格默认第一列按降序排&#xff08;状态1&#xff09;&#xff0c;当点击其他列后&#xff08;状态2&#xff09;&#xff0c;改变日期&#xff0c;触发表格数据更新&#xff0c;发现列的排序还点亮在之前的操作上&#xff0c;没有按照默认来&#xff08;回到状态1&a…