STC8增强型单片机开发【LED呼吸灯(PWM)⭐⭐】

目录

一、引言

二、硬件准备

三、PWM技术概述

四、电路设计

五、代码编写

 EAXSFR:

六、编译与下载

七、测试与调试

八、总结


一、引言

在嵌入式系统开发中,LED呼吸灯是一种常见的示例项目,它不仅能够展示PWM(脉冲宽度调制)技术的应用,还能为系统增添一丝动感和美感。STC8系列增强型单片机凭借其高性能和丰富的功能,非常适合用于LED呼吸灯的开发。本文将详细介绍如何使用STC8增强型单片机实现LED呼吸灯效果。

二、硬件准备

  1. STC8增强型单片机开发板
  2. LED灯珠
  3. 限流电阻
  4. 杜邦线若干

三、PWM技术概述

PWM技术是一种通过调整方波的占空比来模拟输出电压的模拟技术。在LED呼吸灯项目中,我们可以利用PWM技术调整LED的亮度,实现呼吸效果。

四、电路设计

将LED灯珠的正极通过限流电阻连接到STC8单片机的PWM输出引脚,LED的负极连接到单片机的GND引脚。注意选择合适的限流电阻,以免损坏LED或单片机。

五、代码编写

以下是一个基于STC8增强型单片机的LED呼吸灯代码示例:

#include "STC8G_H_GPIO.h"
#include "STC8G_H_UART.h"
#include "STC8G_H_NVIC.h"
#include "STC8H_PWM.h"
#include "Config.h"
#include "STC8G_H_Delay.h"
#include "STC8G_H_Switch.h"

#define LED_SW	P45
#define LED1		P27
#define LED2		P26
#define LED3		P15
#define FREQ		1000

#define PERIOD 	MAIN_Fosc / 1000ul// 周期
/*
 Period = 24000000L / 1000ul
        = 24000

	所以现在Period的结果为24000
*/

// 配置GPIO
void GPIO_config(void) {
    GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义
    // LED_SW
    GPIO_InitStructure.Pin  = GPIO_Pin_5;		//指定要初始化的IO,
    GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
    GPIO_Inilize(GPIO_P4, &GPIO_InitStructure);//初始化
    // P2
    GPIO_InitStructure.Pin  = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_3 | GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_0;		//指定要初始化的IO,
    GPIO_InitStructure.Mode = GPIO_OUT_PP;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
    GPIO_Inilize(GPIO_P2, &GPIO_InitStructure);//初始化
    // P1
    GPIO_InitStructure.Pin  = GPIO_Pin_4 | GPIO_Pin_5;		//指定要初始化的IO,
    GPIO_InitStructure.Mode = GPIO_OUT_PP;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
    GPIO_Inilize(GPIO_P1, &GPIO_InitStructure);//初始化
}

// 配置UART
void UART_config(void) {
    // >>> 记得添加 NVIC.c, UART.c, UART_Isr.c <<<
    COMx_InitDefine		COMx_InitStructure;					//结构定义
    COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
    COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
    COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200
    COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLE
    COMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLE
    UART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4

    NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    UART1_SW(UART1_SW_P30_P31);		// 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}

// 配置PWM
void	PWM_config(void)
{

    // 配置三个部分:PWMA,PWM通道,选择引脚
    PWMx_InitDefine		PWMx_InitStructure;
    /*
    CCMRn_PWM_MODE1:默认全部输出低电平,当占空比大于0时,高电平的占比会随着占空比逐渐增大
    CCMRn_PWM_MODE2:默认全部输出高电平,当占空比大于0时,低电平的占比会随着占空比逐渐增大
    */

    // 配置PWM4
    PWMx_InitStructure.PWM_Mode    =	CCMRn_PWM_MODE1;	//模式,		CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
    PWMx_InitStructure.PWM_Duty    =  0;								//PWM占空比时间, 0~Period
    PWMx_InitStructure.PWM_EnoSelect  = ENO4P | ENO4N | ENO1P | ENO1N | ENO2P | ENO2N | ENO3P | ENO3N;	//输出通道选择,	ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P

    // 配置PWM通道
    PWM_Configuration(PWM4, &PWMx_InitStructure);  	// 配置PWM4通道
    PWM_Configuration(PWM3, &PWMx_InitStructure);	 	//  配置PWM3通道
    PWM_Configuration(PWM2, &PWMx_InitStructure);		//  配置PWM2通道
    PWM_Configuration(PWM1, &PWMx_InitStructure);		//  配置PWM1通道

    PWM4_SW(PWM4_SW_P26_P27);	 // 配置PWM4的引脚
    PWM3_SW(PWM3_SW_P14_P15);	 // 配置PWM3的引脚
    PWM2_SW(PWM2_SW_P22_P23);	 // 配置PWM2的引脚
    PWM1_SW(PWM1_SW_P20_P21);	 // 配置PWM1的引脚
    // 配置PWMA
    PWMx_InitStructure.PWM_Period   = PERIOD;					//周期时间,   0~65535
    PWMx_InitStructure.PWM_DeadTime = 0;					//死区发生器设置, 0~255
    PWMx_InitStructure.PWM_MainOutEnable= ENABLE;			//主输出使能, ENABLE,DISABLE
    PWMx_InitStructure.PWM_CEN_Enable   = ENABLE;			//使能计数器, ENABLE,DISABLE
    PWM_Configuration(PWMA, &PWMx_InitStructure);			//初始化PWM通用寄存器,  PWMA,PWMB

    // 需要中断吗?PWMA是有中断的,但是我们不用。
}

int main() {
    int precent_duty = 0; // 表示占位比的百分比  0~100 / 100 = 0~1 * 24000 = 占空比
    int direction = 1; // 方向   用于表示PWM占空比的增加或减少方向(1表示增加,-1表示减少)。
    PWMx_Duty duty;    // 结构体 在STC8H_PWM.h的第713到723行,用于存储PWM设置信息


    // 打开中断总开关
    EA = 1;

    // 打开PWM使用的扩展RAM寄存器,不打开PWM不能工作,必须配置!
    EAXSFR();

    // 1. 设置工作模式
    GPIO_config();
    UART_config();
    // 2. 配置PWM的工作参数
    PWM_config();
    // 3. 打开LED_SW总开关
    LED_SW = 0;
    // 4. 开启呼吸灯
    while(1) {
        // 呼吸灯效果实现
        precent_duty = precent_duty + direction; // 0~100  // 根据direction的值增加或减少percent_duty
        // 确保precent_duty的值在0至100之间【限制】
        if(precent_duty >= 100) {		// 如果percent_duty的值大于等于100
            precent_duty = 100;			// 给percent_duty设置为100
            direction = -1;					//  给direction设置为-1
            // 表示减少占位比
        } else if(precent_duty <= 0) {		// 如果percent_duty的值小于等于0
            precent_duty = 0;
            direction = 1;
            // 表示增加占位比
        }
        // 个人理解【占位比越高马达越强,占位比越低马达越弱,根据while循环一直执行这处代码】
        // percent_duty为100时  direction为-1 占位比开始减少,占位比越低,马达得到的平均电压越低,马达动力开始降低
        // percent_duty为0时    direction为1  占位比开始增加,占位比越高,马达得到的平均电压越高,马达动力开始增加

        duty.PWM4_Duty = precent_duty / 100.0f * PERIOD;
        duty.PWM3_Duty = precent_duty / 100.0f * PERIOD;
        duty.PWM2_Duty = precent_duty / 100.0f * PERIOD;
        duty.PWM1_Duty = precent_duty / 100.0f * PERIOD;
        //作用:【设置PWM(脉宽调制)的占空比】 用这个公式得到实际的PWM占空比。这个值被赋给duty.PWM4_Duty\PWM3_Duty\PWM2_Duty\PWM1_Duty
        /*
        		percent_duty 为100时
        				100 / 100.0f * 24000 = 24000.0
        					100 / 100.0f = 1.0
        					1.0 * 24000 = 24000.0
						percent_duty 为0时
								0 / 100.0f * 24000 = 0.0
									0 / 100.0f = 0.0
									0.0 * 24000 = 0.0

						当 duty.PWM4_Duty 等于 24000.0 时, 这通常表示100%的占空比,将提供最大的功率或亮度。
						当 duty.PWM4_Duty 等于 0.0 时,这通常表示0%的占空比,将不提供任何功率或亮度。
        */
        // 更新PWMA  PWMA中包含 PWM1\PWM2\PWM3\PWM4
        UpdatePwm(PWMA,&duty); 

        delay_ms(20); // 延迟

    }

}
// 马达也可以用

上列代码所以库函数文件:

 

注意:上述代码仅为示例,具体实现时需要根据STC8增强型单片机的型号和开发板的数据手册进行相应的修改和配置。 

 EAXSFR:

 在STC8H.H文件中第1044行代码。

 STC8H.H不需要导入STC8默认导入

这里的宏定义做了以下事情:

  1. P_SW2 是一个外设端口切换寄存器(可能是一个特定的硬件寄存器,用于控制或配置微控制器的某些外设或功能)。
  2. 0x80 是一个十六进制数,其二进制表示为 10000000
  3. |= 是一个位或赋值操作符,它将 P_SW2 寄存器的当前值与 0x80 进行位或操作,并将结果存回 P_SW2 寄存器。这实际上是将 P_SW2 寄存器的第7位(从右边开始数,最低位为第0位)设置为1,而不改变其他位。

关于注释中提到的 /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展SFR(XSFR) */,这部分是描述某个指令(可能是MOVX指令,用于数据指针(DPTR)和累加器(A)之间的数据交换)的操作对象是扩展的特殊功能寄存器(SFR,Special Function Register)。但是,这与 EAXSFR() 宏本身的具体操作没有直接关系,只是提供了上下文或背景信息。

总结来说,EAXSFR() 在这个上下文中是一个宏,用于设置 P_SW2 寄存器的第7位为1,可能用于控制或启用与扩展SFR相关的某些功能或外设。

六、编译与下载

  1. 在Keil C51中编译程序代码,确保没有错误和警告。
  2. 将编译生成的hex文件通过编程器下载到STC8增强型单片机开发板中。

七、测试与调试

  1. 给开发板上电,观察LED灯珠的亮度变化,检查是否实现了呼吸灯效果。
  2. 如果效果不理想,可以通过调整PWM参数、延时时间等参数进行优化。

八、总结

通过本文的介绍,我们了解了如何使用STC8增强型单片机开发LED呼吸灯项目。在项目实践中,我们不仅掌握了PWM技术的应用,还提高了嵌入式系统开发的能力。希望本文能对大家有所帮助,激发大家对嵌入式系统开发的兴趣和热情。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024 cleanmymac有没有必要买呢,全反面分析

在使用mac时&#xff0c;小编遇到了运行内存不足、硬盘空间不足的情况。遇到这种情况&#xff0c;我们可以借助经典的电脑深度清理软件——CleanMyMac X&#xff0c;清理不常用的软件和系统垃圾&#xff0c;非常好用&#xff01;不过&#xff0c;有许多网友发现CleanMyMac X有免…

SQLite利用事务实现批量插入(提升效率)

在尝试过SQLite批量插入一百万条记录&#xff0c;执行时长高达20多分钟后&#xff0c;就在想一个问题&#xff0c;这样的性能是不可能被广泛应用的&#xff0c;更不可能出现在真实的生产环境中&#xff0c;那么对此应该如何优化一下呢&#xff1f; 首先分析一下批量插入的逻辑 …

社区送水小程序软件开发

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言&#xff1a;pythonjavanode.jsphp均支持 运行软件…

端午节线上活动方案怎么写?

一年一端午&#xff0c;一岁一安康。 如果您想组织端午活动&#xff0c;却不知道如何安排&#xff0c;可以看看何策网&#xff0c;有很多案例参考&#xff0c;仿造模板修改即可。 下面分享一个线上端午节活动策划方案&#xff0c;希望能帮到你&#xff01; 端午节作为祭祖祈…

Remix 集成 MUI

Remix 如何接入 MUI 组件库&#xff0c;MUI 官网提供了一个 Remix 接入 MUI 的例子&#xff0c;用的是老的 Remix版本&#xff0c;如何接入新的 Vite 版本呢&#xff1f; 由于 MUI 支持 SSR&#xff0c;只需要改造对应的 Client 和 Server 即可实现。安装 MUI 组件组件库&…

Java类与对象(一)

类的定义与使用 在Java中使用关键字class定义一个类&#xff0c;格式如下&#xff1a; class 类名{// 成员变量/字段/属性//成员方法/行为 }Java中类和c语言中的结构体有点类似&#xff0c; 在Java中类名一般采用大驼峰&#xff08;每个首字母大写&#xff09;的形式&#xf…

Java SE基础知识(12)

知识梳理&#xff1a; package ZoomId;import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Set;public class demo1 {public static void main(String[] args) {//获取所有的时区名称Set<String> availableZoneId…

Ansible剧本playbook之--------Templates 模块、roles角色详细解读

目录 一、Templates 模块 1.1准备模板文件并设置引用的变量 1.2修改主机清单文件&#xff0c;使用主机变量定义一个变量名相同&#xff0c;而值不同的变量 1.3编写 playbook 1.4ansible主机远程查看修改参数 1.5验证 二、tags 模块 always应用 三、Roles 模块 3.1ro…

公司网页设计思路

在当今互联网时代&#xff0c;公司网页设计是一个极为重要的环节。一款精心设计的公司网页可以提升企业形象&#xff0c;增加用户粘性&#xff0c;吸引更多的潜在客户和合作伙伴。下面将为大家介绍一些公司网页设计的思路。 首先&#xff0c;要确立公司网页的整体风格。网页风格…

适合优化yaml文件编辑效果的.vimrc简单配置

yaml文件编辑最重要的就是缩进对齐&#xff08;一个tab键对应2个空格&#xff09;&#xff0c;最后加上添加横&#xff0c;纵线的效果 某xx.yaml文件或者xx.yml在vim编辑器中效果如图所示&#xff1a;&#xff1a; 简单的~/.vimrc文件配置内容&#xff1a; vim ~/.vimrc set…

网络工程师练习题

网络工程师练习题 网桥怎样知道网络端口连接了那些网站?如果从端口收到一个数据帧,则将其源地址记入该端口的数据库当网桥连接的局域网出现环路时怎么办?运行生成树协议阻塞一部分端口。使用IEEE 802.1q协议,最多可以配置4094个VLAN。VLAN中继协议(VTP)有不同的工作模式,…

AI大模型探索之路-训练篇21:Llama2微调实战-LoRA技术微调步骤详解

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

pytorch单机多卡训练_数据并行DataParallel

1.单机多卡概述 单卡多级的模型训练&#xff0c;即并行训练&#xff0c;可分为数据并行和模型并行两种. 数据并行是指&#xff0c;多张 GPUs 使用相同的模型副本&#xff0c;但采用不同 batch 的数据进行训练. 模型并行是指&#xff0c;多张 GPUs 使用同一 batch 的数据&…

scrapy的入门

今天我们先学习一下scrapy的入门,Scrapy是一个快速的高层次的网页爬取和网页抓取框架&#xff0c;用于爬取网站并从页面中提取结构化的数据。 1. scrapy的概念和流程 1.1 scrapy的概念 我们先来了解一下scrapy的概念,什么是scrapy: Scrapy是一个Python编写的开源网络爬虫框架…

数据恢复软件 –最好的Android数据恢复软件分享

在安卓数据恢复方面&#xff0c;奇客数据恢复安卓版是最好的 Android 数据恢复公司&#xff0c;因为它的成功率为 100%。随着无数企业和个人使用智能手机和平板电脑&#xff0c;总是有很多数据丢失或损坏的机会&#xff0c;这就是它们如此受欢迎的原因。在恢复数据时&#xff0…

鸿蒙ArkUI:【从代码到UI显示的整体渲染流程】

ArkUI 方舟开发框架&#xff08;简称ArkUI&#xff09;是鸿蒙开发的UI框架&#xff0c;提供如下两种开发范式&#xff0c;我们 只学声明式开发范式 [基于ArkTS的声明式开发范式][兼容JS的类Web开发范式]开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/h…

2024最新最全【NMAP】零基础入门到精通

一、Nmap介绍 Nmap(Network Mapper&#xff0c;网络映射器)是一款开放源代码的网络探测和安全审核工具。它被设计用来快速扫描大型网络&#xff0c;包括主机探测与发现、开放的端口情况、操作系统与应用服务指纹识别、WAF识别及常见安全漏洞。它的图形化界面是Zenmap&#xff…

PyTorch的卷积和池化

卷积计算 input 表示输入的图像filter 表示卷积核, 也叫做滤波器input 经过 filter 的得到输出为最右侧的图像&#xff0c;该图叫做特征图 卷积的计算是将卷积核放入左上角&#xff0c;在局部区域间做点积&#xff0c;然后将卷积核在Input上面依次从左向右&#xff0c;从上到下…

19 分页:快速地址转换(TLB)

通过上一节中的知识&#xff0c;可以知道使用分页作为核心机制来实现虚拟内存是比较不错的&#xff0c;但是因为复杂的查询和转换逻辑&#xff0c;导致性能开销比较大。这里就要使用硬件来提升了&#xff0c;便出现了地址转换旁路缓冲存储器&#xff08;TLB&#xff09;&#x…

【算法】滑动窗口——串联所有单词的子串

今天来以“滑动窗口”的思想来详解一道比较困难的题目——串联所有单词的子串&#xff0c;有需要借鉴即可。 目录 1.题目2.下面是示例代码3.总结 1.题目 题目链接&#xff1a;LINK 这道题如果把每个字符串看成一个字母&#xff0c;就是另外一道中等难度的题目&#xff0c;即&…