STC8H8K64U 学习笔记 - PWM

STC8H8K64U 学习笔记 - PWM

  • 环境说明
    • 引脚说明
  • PWM
    • 呼吸灯
    • 震动马达
  • 乐谱

环境说明

该内容仅针对我自己学习的开发板做的笔记,在实际开发中需要针对目标电路板的原理图进行针对性研究。

  • 芯片:STC8H8K64U
  • 烧录软件:stc-isp-v6.92G
  • 编码工具:天问

引脚说明

  • P0_0:蜂鸣器,按频率发音,1:高,0:低
  • P0_1:电动马达,0:停,1:动
  • P5_3:小蓝灯,0:灭,1:亮
  • P2_7:1 号 LED 灯,0:亮,1:灭
  • P2_6:2 号 LED 灯,0:亮,1:灭
  • P1_5:3 号 LED 灯,0:亮,1:灭
  • P1_4:4 号 LED 灯,0:亮,1:灭
  • P2_3:5 号 LED 灯,0:亮,1:灭
  • P2_2:6 号 LED 灯,0:亮,1:灭
  • P2_1:7 号 LED 灯,0:亮,1:灭
  • P2_0:8 号 LED 灯,0:亮,1:灭
  • P5_1:1 号按键,0:按下,1:弹起
  • P5_2:2 号按键,0:按下,1:弹起
  • P5_3:3 号按键,0:按下,1:弹起
  • P5_4:4 号按键,0:按下,1:弹起
  • P3_4:矩阵键盘第 1 行引脚
  • P3_5:矩阵键盘第 2 行引脚
  • P4_0:矩阵键盘第 3 行引脚
  • P4_1:矩阵键盘第 4 行引脚
  • P0_3:矩阵键盘第 1 列引脚
  • P0_6:矩阵键盘第 2 列引脚
  • P0_7:矩阵键盘第 3 列引脚
  • P1_7:矩阵键盘第 4 列引脚

PWM

  • 频率和周期的关系
    • 频率(Frequency): 表示单位时间内发生事件的次数。常用单位是赫兹(Hz),1赫兹等于每秒一个周期。
    • 周期(Period): 表示一个完整事件发生所需的时间。周期是频率的倒数。
    • 举例:
      • 24MHz(兆赫兹),每秒计算24M次,1M = 1k * 1k = 1 000 000
        • 那么周期的时间就是1/24MHz=41.67ns,那么计算1次需要41.67ns,就是说执行1次所需的时间
  • PWM全称是脉宽调制(Pulse Width Modulation),是一种通过改变信号的脉冲宽度来控制电路输出的技术。
  • PWM与引脚对应关系(引脚来源:《stc8h.pdf》的 997 页)

在这里插入图片描述

呼吸灯

通过 PWM 设置 LED 灯的亮度

#define PWM_DUTY_MAX 1000//PWM最大占空比值

#include <STC8HX.h>
uint32 sys_clk = 24000000;//设置PWM、定时器、串口、EEPROM频率参数
#include "lib/twen_board.h"
#include "lib/PWM.h"
#include "lib/delay.h"

uint16 index = 0;
int16 inc = 5;
uint16 frequency = 1000;

void setup() {
  twen_board_init();//天问51初始化
  
  pwm_init(PWM4N_P27, frequency, 0);
  pwm_init(PWM4P_P26, frequency, 0);
  // pwm_init(PWM3N_P15, frequency, 0);
  // pwm_init(PWM3P_P14, frequency, 0);
  // pwm_init(PWM2N_P23, frequency, 0);
  // pwm_init(PWM2P_P22, frequency, 0);
  // pwm_init(PWM1N_P21, frequency, 0);
  // pwm_init(PWM1P_P20, frequency, 0);
}

void loop() {
  pwm_duty(PWM4N_P27, index);
  pwm_duty(PWM4P_P26, index);
  // pwm_duty(PWM3N_P15, index);
  // pwm_duty(PWM3P_P14, index);
  // pwm_duty(PWM2N_P23, index);
  // pwm_duty(PWM2P_P22, index);
  // pwm_duty(PWM1N_P21, index);
  // pwm_duty(PWM1P_P20, index);
  
  delay(1);
  if(index >= 1000) {
    inc = -5;
  }
  if(index <= 0) {
    inc = 5;
  }
  index+= inc;
}

void main(void) {
  setup();
  while(1){
    loop();
  }
}

震动马达

通过 PWM 设置马达的震动强度

#define PWM_DUTY_MAX 1000//PWM最大占空比值

#include <STC8HX.h>
uint32 sys_clk = 24000000;//设置PWM、定时器、串口、EEPROM频率参数
#include "lib/twen_board.h"
#include "lib/PWM.h"
#include "lib/delay.h"

uint16 index = 0;
int16 inc = 5;
uint16 frequency = 1000;

void setup() {
  twen_board_init();//天问51初始化
  
  pwm_init(PWM6_P01, frequency, 0);
  P0M1&=~0x02;P0M0|=0x02;//推挽输出
}

void loop() {  
  pwm_duty(PWM6_P01, index);
  
  delay(1);
  if(index >= 1000) {
    inc = -5;
  }
  if(index <= 0) {
    inc = 5;
  }
  index+= inc;
}

void main(void) {
  setup();
  while(1){
    loop();
  }
}

乐谱

#define PWM_DUTY_MAX 1000//PWM最大占空比值

#include <STC8HX.h>
uint32 sys_clk = 24000000;//设置PWM、定时器、串口、EEPROM频率参数
#include "lib/twen_board.h"
#include "lib/UART.h"
#include "lib/PWM.h"

// 哆Do  来Re  咪Mi  发Fa  唆So  拉La  西Si  哆Do
// 523,  587,  659,  698,  784,  880,  988,  1047
// 1047, 1175, 1319, 1397, 1568, 1760, 1976, 2093
// 2093, 2349, 2637, 2794, 3135, 3520, 3951, 4186

// 设定小字2组的音阶
#define s2_Do 1047
#define s2_Re 1175
#define s2_Mi 1319
#define s2_Fa 1397
#define s2_So 1568
#define s2_La 1760
#define s2_Si 1976
// 设定小字3组的音阶
#define s3_Do 2093
#define s3_Re 2349
#define s3_Mi 2637
#define s3_Fa 2794
#define s3_So 3135
#define s3_La 3520
#define s3_Si 3951
#define s4_Do 4186
// 设定默认的中音(小字2组的音阶)
#define M1 1047
#define M2 1175
#define M3 1319
#define M4 1397
#define M5 1568
#define M6 1760
#define M7 1976
// 设定默认的高音(小字3组的音阶)
#define G1 2093
#define G2 2349
#define G3 2637
#define G4 2794
#define G5 3135
#define G6 3520
#define G7 3951

void putchar(char c) {
  if (c == '\n') {
    uart_putchar(UART_1, 0x0d);
    uart_putchar(UART_1, 0x0a);
  } else {
    uart_putchar(UART_1, (uint8)c);
  }
}

// 每个音阶之间的停顿时间
uint16 spot = 200;
// 单个音阶的持续时间
uint16 duration = 100;
// 按键按下标志位
uint8 pressed1 = 0;
uint8 pressed2 = 0;
// 连续播放乐谱数组过程中的循环索引值
uint16 index = 0;
// 连续播放乐谱数组过程中的循环长度
uint16 lenth = 0;

void setup() {
  twen_board_init();//天问51初始化
  P0M1&=~0x01;P0M0|=0x01;//推挽输出
  uart_init(UART_1, UART1_RX_P30, UART1_TX_P31, 115200, TIM_1);//初始化串口
}

// 启动蜂鸣器(输入单位 hz)
// @param hz        蜂鸣器输入频率
// @param recess    与下一个音阶之间的休息时间
void launchBuzzer(const uint16 hz, uint16 recess) {
  // 假设入参是 523 Hz, 即  523 次/秒
  // 换算为 1000ms 执行 523 次
  // 得到每次执行的时间是 1000ms / 523 次 ≈ 1.912 ms
  // 高低电平各占一半, 即约等于 0.956 ms
  
  // duration = 1000 / hz / 2;
  // printf_small("duration is %d\n", duration);
  // P0_0 = 1;
  // delay(duration);
  // P0_0 = 0;
  // delay(duration);
  
  if(hz == 0) {
    // 如果传入是 0 表示该音阶置空
    delay(duration);
    return;
  }
  pwm_init(PWM5_P00, hz, 500);
  delay(duration);
  pwm_duty(PWM5_P00, 0);
  if(recess > 0) {
    delay(recess);
  }
}

// 乐谱 —— 生日快乐
xdata uint16 music_score_birthday[] = {
  G5, G5, G6, G5, M1, G7,
  G5, G5, G6, G5, M2, M1,
  G5, G5, M5, M3, M1, G7, G6,
  M4, M4, M3, M1, M2, M1
};

// 乐谱 —— 哆啦A梦
xdata uint16 music_score_doraemon[] = {
  G5,M1,M1,M3,  M6,M3,M5,
  M5,M6,M5,M3,  M4,M3,M2,
  M6,M2,M2,M4,  M7,M7,M6,M5,
  M4,M4,M3,  M6,M7,M1,M2,
  
  G5,M1,M1,M3,  M6,M3,M5,
  M5,M6,M5,M3,  M4,M3,M2,
  M6,M2,M2,M4,  M7,M6,M5,
  M4,M4,M3,M2,  M7,M2,M1
};

// 播放指定乐谱
void play(uint16 *ps, uint16 len) {
  for(index = 0; index < len; index++) {
    launchBuzzer(ps[index], spot);
  }
  delay(1000);
}

void loop() {
  // 按下按键 1 播放 生日快乐
  if(P5_1 == 0 && pressed1 == 0) {
    pressed1 = 1;
    lenth = sizeof(music_score_birthday) / sizeof(uint16);
    play(music_score_birthday, lenth);
  } else if(P5_1 == 1 && pressed1 == 1) {
    pressed1 = 0;
  }
  
  // 按下按键 2 播放 哆啦A梦
  if(P5_2 == 0 && pressed2 == 0) {
    pressed2 = 1;
    lenth = sizeof(music_score_doraemon) / sizeof(uint16);
    play(music_score_doraemon, lenth);
  } else if(P5_2 == 1 && pressed2 == 1) {
    pressed2 = 0;
  }
}

void main(void) {
  setup();
  while(1){
    loop();
  }
}

有部分音阶不太对,可能是频率值弄错了,但影响不大!

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

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

相关文章

CSS面试题---基础

1、css选择器及优先级 选择器优先级&#xff1a;内联样式>id选择器>类选择器、属性选择器、伪类选择器>标签选择器、微元素选择器 注意&#xff1a; !important优先级最高&#xff1b; 如果优先级相同&#xff0c;则最后出现的样式生效&#xff1b; 继承得到的样式优先…

Google DeepMind 大语言模型中的长形态事实性

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 论文标题&#xff1a;Long-form factuality in large language models 论文链接&#xff1a;https://arxiv.org/abs/2403.18802 论文的关键信息总结如下&#xff1a; 研究问题是什么&#xff1f;论文…

Python+requests+Pytest+logging+allure+pymysql框架详解

一、框架目录结构 1)tools目录用来放公共方法存储,如发送接口以及读取测试数据的方法,响应断言 数据库断言 前置sql等方法;2)datas目录用例存储接口用例的测试数据,我是用excel来存储的数据,文件数据 图片数据等;3)testcases目录用来存放测试用例,一个python文件对应…

docker容器之etcd安装

一、etcd介绍 1、etcd是什么 etcd是CoreOS团队于2013年6月发起的开源项目&#xff0c;它的目标是构建一个高可用的分布式键值(key-value)数据库。 2、etcd特点 简单的接口&#xff0c;通过标准的HTTP API进行调用&#xff0c;也可以使用官方提供的 etcdctl 操作存储的数据。…

Java | Leetcode Java题解之第3题无重复字符的最长子串

题目&#xff1a; 题解&#xff1a; class Solution {public int lengthOfLongestSubstring(String s) {// 哈希集合&#xff0c;记录每个字符是否出现过Set<Character> occ new HashSet<Character>();int n s.length();// 右指针&#xff0c;初始值为 -1&#…

【好书推荐4】图机器学习

【好书推荐4】图机器学习 写在最前面编辑推荐内容简介作者简介目录前言/序言本书读者内容介绍 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限可能…

67、yolov8目标检测和旋转目标检测算法batchsize=1/6部署Atlas 200I DK A2开发板上

基本思想:需求部署yolov8目标检测和旋转目标检测算法部署atlas 200dk 开发板上 一、转换模型 链接: https://pan.baidu.com/s/1hJPX2QvybI4AGgeJKO6QgQ?pwd=q2s5 提取码: q2s5 from ultralytics import YOLO# Load a model model = YOLO("yolov8s.yaml") # buil…

辽宁梵宁教育:设计领域的靠谱正规线上教育机构典范

辽宁梵宁教育&#xff0c;作为一家专注于学习设计的线上教育机构&#xff0c;近年来在业界崭露头角&#xff0c;赢得了广大学习者的认可和好评。接下来&#xff0c;本文将从多个维度详细阐述梵宁教育为何是一家靠谱且正规的线上教育机构。 梵宁教育在师资力量上表现出色。其拥有…

0基础学习Mybatis系列数据库操作框架——目录结构

大纲 配置的修改代码的修改Main.java文件所在包下新增org.example.model包新增org.example.mapper包 单元测试 在《0基础学习Mybatis系列数据库操作框架——最小Demo》一文中&#xff0c;我们用最简单的方法组织出一个Mybatis应用项目。为了后续构建更符合日常开发环境的项目&a…

校园跑腿(源码+文档)

校园跑腿管理系统&#xff08;小程序、ios、安卓都可部署&#xff09; 文件包含内容程序简要说明含有功能项目截图客户端店铺代购用户条款隐私协议租借服务行李代搬拨打客服电话注册界面我的界面申请骑手登录界面快递带取资料修改快递代寄主页万能帮 管理端代购管理添加用户订单…

如何通过优化图片来提升WordPress网站的访问速度

因为我本身也是一个接触网站时间并不长的半小白选手&#xff0c;最开始建站的时候也选择了比较流行的WordPress来&#xff0c;过程虽然坎坷&#xff0c;但是好歹网站是上线了&#xff0c;网站初步的效果我还是比较满意的&#xff0c;但是总感觉网页加载的速度比较慢。 我用的服…

c++的学习之路:7、类和对象(3)

一、初始化列表 初始化列表&#xff1a;以一个冒号开始&#xff0c;接着是一个以逗号分隔的数据成员列表&#xff0c;每个"成员变量"后面跟一个放在括号中的初始值或表达式&#xff0c;如下方代码就是初始化列表的方式。从图片可以看出这种方式也可以利用缺省初始化…

文件搜索案列 --java

目标&#xff1a; 搜索盘符下面符合要求的文件名&#xff0c;并可以选择是否打开该文件 代码&#xff1a; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Scanner;public class findQQ {public static void main(String[] a…

Protobuf 二进制文件学习及解析

0. 简介 protobuf也叫protocol buffer是google 的一种数据交换的格式&#xff0c;它独立于语言&#xff0c;独立于平台。google 提供了多种语言的实现&#xff1a;java、c#、c、go 和 python&#xff0c;每一种实现都包含了相应语言的编译器以及库文件。 由于它是一种二进制的…

【攻防世界】file_include (PHP伪协议+过滤器)

打开题目环境&#xff1a; 进行PHP代码审计&#xff0c;发现这是一个文件包含漏洞。 我们尝试利用PHP伪协议中的 php://filter来读取 check.php 中的内容。 构造payload 并提交&#xff1a; 发现payload被过滤掉了&#xff0c;我们就需要尝试使用不同的转换器。 PHP各类转换…

java和408相关知识

一、java 1.JVM的GC机制&#xff1a; &#xff08;1&#xff09;哪些内存需要回收&#xff1f; 堆和方法区&#xff0c;程序计数器、虚拟机栈、本地方法栈3个区域是随线程而生&#xff0c;随线程而灭的 &#xff08;2&#xff09;什么时候回收&#xff1f; 判断对象是否可…

HarmonyOS 应用开发之自定义组件冻结功能

自定义组件处于非激活状态时&#xff0c;状态变量将不响应更新&#xff0c;即Watch不会调用&#xff0c;状态变量关联的节点不会刷新。通过freezeWhenInactive属性来决定是否使用冻结功能&#xff0c;不传参数时默认不使用。支持的场景有&#xff1a;页面路由&#xff0c;TabCo…

LC 107.二叉树的层序遍历II

107. 二叉树的层序遍历 II 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 示例 1&#xff1a; 输入&#xff1a; root [3,9,20,null,null,15,7] 输出…

OpenHarmony实战开发-如何通过ArkTS卡片实现一个简单的音乐卡片

​介绍 本示例展示了如何通过ArkTS卡片实现一个简单的音乐卡片 效果预览 使用说明 1.安装应用&#xff0c;并在桌面上长按本应用的桌面图标&#xff0c;长按后弹出选项列表。 2.点击弹出列表中的服务卡片选项进入卡片添加界面。 3.点击正下方的添加到桌面按钮&#xff0c;…

uniapp项目-懂你找图

文章目录 项目介绍项目搭建1.项目创建 2.新增tabbar3引入字体图标 uni-ui介绍使用 uni-api介绍 首页模块功能分析搭建子页面分段器介绍 封装自己的异步请求为什么要封装封装的思路 编写首页-推荐页面分页功能 专辑列表获取专辑详情数据 项目介绍 微信小程序&#xff0c;提供图…