中颖51芯片学习9. PWM(12bit脉冲宽度调制)

中颖51芯片学习9. PWM(12bit脉冲宽度调制)

  • 一、资源简介
  • 二、PWM工作流程
  • 三、寄存器介绍
    • 1. PWMx控制寄存器PWMxCON
    • 2. PWM0周期寄存器PWM0PH/L
    • 3. PWM1周期寄存器PWM1PH/L
    • 4. PWM0占空比控制寄存器PWM0DH/L
    • 5. PWM1占空比控制寄存器 PWM1DH/L
    • 6. 占空比寄存器与周期关系
  • 四、代码实现示例
    • 1. 基本功能
    • 2. 封装PWM函数
      • (1)pwm_utils.c
      • (2)main.c

本文使用的芯片型号为 SH79F9476

一、资源简介

前面介绍了使用 SH79F9476 的可编程计数器阵列 PCA0 生成PWM波,其支持8位、16位脉宽调制。
主要特性如下:

  1. 两路12位PWM模块:SH79F9476提供了两个PWM模块,每个模块可以生成具有可调周期和占空比的脉宽调制波形。

  2. 周期溢出中断:每个PWM周期都提供了溢出中断功能,可以在周期结束时触发中断处理程序。

  3. 输出极性可选择:可以通过设置PWM控制寄存器来选择PWM输出的极性,从而决定占空比期间输出的电平。

  4. PWM模块控制:使用PWM控制寄存器(PWMxCON)可以配置PWM模块的时钟源、输出极性、周期中断等参数。

  5. 周期设置:使用PWM周期寄存器(PWMxPH/L)可以设置PWM输出波形的周期,以控制脉冲的频率。

  6. 占空比设置:使用PWM占空比寄存器(PWMxDH/L)可以设置PWM输出波形的占空比,以控制脉冲的宽度。

二、PWM工作流程

SH79F9476的PWM工作流程如下:

  1. 选择PWM模块时钟源
    在开始配置PWM模块之前,首先需要选择PWM模块的时钟源。可以通过设置PWM控制寄存器(PWMxCON)中的PWMxCK[2:0]位来选择时钟源,以确定PWM模块的工作时钟频率。

  2. 设置PWM周期
    使用PWM周期寄存器(PWMxPH/L)设置PWM输出波形的周期。这些寄存器用于控制PWM脉冲的频率。在设置周期之前,需要确定所需的PWM输出频率,并根据所选的时钟源来计算周期寄存器的值。

  3. 设置PWM占空比
    使用PWM占空比寄存器(PWMxDH/L)设置PWM输出波形的占空比。这些寄存器用于控制PWM脉冲的宽度。在设置占空比之前,需要确定所需的PWM输出占空比,并根据所选的周期来计算占空比寄存器的值。

  4. 选择PWM输出模式
    使用PWM控制寄存器(PWMxCON)中的PWMxS位选择PWM输出模式。可以选择PWM占空比期间输出高电平还是低电平。

  5. 使能PWM模块
    设置PWM使能位(PWMxEN)来启用所需的PWM模块。这将启动PWM输出并使其按照设置的周期和占空比工作。

  6. 修改周期和占空比(可选)
    在PWM输出允许期间,可以根据需要修改周期和占空比寄存器的值。修改后的值将在下一个PWM周期开始生效。

  7. 处理PWM周期中断(可选)
    如果启用了PWM周期中断,当PWM周期结束时,将触发中断处理程序。可以在中断处理程序中执行相应的操作,例如更新周期和占空比等。

  8. 调整PWM输出(可选)
    根据实际需求,可以根据系统的运行情况调整PWM输出的周期和占空比。可以根据外部输入信号或系统状态来动态调整PWM输出。

三、寄存器介绍

1. PWMx控制寄存器PWMxCON

在这里插入图片描述
位功能说明:
在这里插入图片描述
下面示例:

PWM0CON = 0x81;
  • 允许 PWM0模块
  • PWM0占空比期间输出高电平,占空比溢出后输出低电平
  • PWM0使用系统时钟,不分频
  • 禁止PWM0周期中断
  • PWM0输出允许
PWM1CON=0xC1; //11000001
  • 允许PWM1模块
  • PWM1占空比期间输出低电平,占空比溢出后输出高电平
  • PWM1使用系统时钟
  • 禁止PWM1周期中断
  • PWM1输出允许

2. PWM0周期寄存器PWM0PH/L

在这里插入图片描述
输出周期为 [PWM0PH,PWM0PL] * PWM时钟周期 。
PWM0的计数器计数至PWM0PH/L值后归0,这时如果PWM0S=0,则PWM0输出低电平 ;如果PWM0S=1,则PWM0输出高电平。

示例:

	PWM0PL = 0xff;
	PWM0PH = 0x0f;

周期为 0xfff*系统时钟周期,假设系统时钟为12MHz,则PWM0周期为 0xfff/12MHz=0.34125ms

3. PWM1周期寄存器PWM1PH/L

在这里插入图片描述

4. PWM0占空比控制寄存器PWM0DH/L

在这里插入图片描述
位功能说明:
在这里插入图片描述

5. PWM1占空比控制寄存器 PWM1DH/L

在这里插入图片描述
位功能说明:
在这里插入图片描述
修改占空比要注意的是:

  • 修改寄存器 PWMxDH 将使得 PWMx 的输出在下一个周期生效。
  • 用户需先修改 PWMxDL ,再修改 PWMxDH 以修改 PWM占空比。
  • 无论 PWMxDH 是否被修改,都需要将 PWMxDH 再写一次。否则,低位的修改无效。

6. 占空比寄存器与周期关系

下图示例可以比较清楚看出PWMP和PWMD所指的时间:
在这里插入图片描述
即PWMP为PWM周期 ,
PWMD为PWM输出高/低电平时间,具体输出高还是低取决于PWMS的值。

四、代码实现示例

1. 基本功能

下面实例实现PWM输出的基本代码:

void init_pwm0()
{
	_push_(INSCON);
	Select_Bank0();
	PWM0PL = 0xff;
	PWM0PH = 0x0f;
	PWM0DL = 0xff;
	PWM0DH = 0x07;
	PWM0CON = 0x81;
	_pop_(INSCON);
}

void init_pwm1()
{
	_push_(INSCON);
	Select_Bank1();
	PWM1PL = 0xff;
	PWM1PH = 0x0f;
	PWM1DL = 0xff;
	PWM1DH = 0x07;
	PWM1CON = 0xc1;
	_pop_(INSCON);
}

代码选项设置,时钟使用128K:
在这里插入图片描述

2路PWM波形对比: (2路垂直偏移设置不同以方便观察)
在这里插入图片描述

2. 封装PWM函数

(1)pwm_utils.c

#include "pwm_utils.h"

/**
 * @param frequency 频率
 * @param duty 占空比,单位是百分比
 * @param polar 极性
 * @brief 初始化PWM0
 */
void Pwm0_Init(volatile U16 frequency, volatile U16 duty, volatile U16 polar) {
    // 周期,单位是ms
    volatile U16 period = 1000 / frequency;
    volatile U16 PWM0P = period * 128;
    volatile U16 PWM0D = (PWM0P / 100) * duty;
    _push_(INSCON);
    Select_Bank0();
    // 周期寄存器, 0x0fff=4095,周期=4095/128K=32ms
    // 通过周期计算PWM0Px的值,PWM0Px=period*128K/1000
    PWM0PL = PWM0P & 0xff;
    PWM0PH = PWM0P >> 8;
    // 占空比寄存器,0x07ff=2047
    // 计算占空比寄存器的值,PWM0Dx=周期寄存器值*duty/100
    PWM0DL = PWM0D & 0xff;
    PWM0DH = PWM0D >> 8;

    if (polar == 1) {
        PWM0CON |= 0x40;
    } else {
        PWM0CON &= 0xbf;
    }
    // PWM0控制寄存器 1000_0001, 使能、输出允许
    PWM0CON |= 0x81;
    _pop_(INSCON);
}

/**
 * @param frequency 频率
 * @param duty 占空比,单位是百分比
 * @param polar 极性
 * @brief 初始化PWM1
 */
void Pwm1_Init(volatile U16 frequency, volatile U16 duty, volatile U16 polar) {
    // 周期,单位是ms
    volatile U16 period = 1000 / frequency;
    volatile U16 PWM1P = period * 128;
    volatile U16 PWM1D = (PWM1P / 100) * duty;
    _push_(INSCON);
    Select_Bank1();
    // 周期寄存器
    PWM1PL = PWM1P & 0xff;
    PWM1PH = PWM1P >> 8;
    // 占空比寄存器
    PWM1DL = PWM1D & 0xff;
    PWM1DH = PWM1D >> 8;

    if (polar == 1) {
        PWM1CON |= 0x40;
    } else {
        PWM1CON &= 0xbf;
    }
    // PWM1控制寄存器 1100_0001,使能、占空比期间输出低电平、占空比溢出后输出高电平、输出允许
    PWM1CON |= 0x81;
    _pop_(INSCON);
}

(2)main.c

#include "SH79F9476.h"
#include "clk_utils.h"
#include "pwm_utils.h"


void main() {
	
    // 选择低速时钟
    lowFrequenceClk();

	Pwm0_Init(32, 50, 0);
    Pwm1_Init(32, 80, 1);

    while (1) {
    }
}

输出频率32Hz、占空比80、极性相反的波形运行示例:
在这里插入图片描述

本文参考资源来自中颖官网。
本文代码开源地址: https://gitee.com/xundh/learn-sinowealth-51

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

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

相关文章

Next.js+React+Node系统实战,搞定SSR服务器渲染

Next.jsReactNode系统实战,搞定SSR服务器渲染 Next.js React Node.js 实战:实现服务器端渲染(SSR) 项目概述 在这个项目中,我们将探讨如何使用 Next.js、React 和 Node.js 来构建一个服务器渲染的 web 应用程序。通…

pytest使用 pytest-rerunfailures 插件实现失败用例重跑功能

使用 pytest 进行测试时,你可以通过安装并配置 pytest-rerunfailures 插件来实现失败用例重跑功能。以下是一个示例说明: 假设你有一个测试文件 test_example.py 包含如下测试用例: import pytestpytest.mark.parametrize("num",…

javaScript3

javaScript 一.对象1.概念2.创建对象的三种方法(1).字面量创建(利用{})(2)变量、属性、函数、方法的区别(3).new Object创建(4).构造函数 3.new关键字的执行过程4.遍历对象(for..in) 二.内置对象 一.对象 1.概念 一组无序的相关属性和方法的…

报错The chromedriver version cannot be discovered以及下载chromedriver.exe和查看其版本的命令

python3.8.10,win10。 谷歌浏览器版本(我写代码的时候还是123.0.x.x,没几天就自动更新到124.0.x.x了): 在使用selenium的时候,出现报错,The chromedriver version cannot be discovered。 &am…

【面试八股总结】Linux系统下的I/O多路复用

参考资料 :小林Coding、阿秀、代码随想录 I/O多路复用是⼀种在单个线程或进程中处理多个输入和输出操作的机制。它允许单个进程同时监视多个文件描述符(通常是套接字),一旦某个描述符就绪(一般是读就绪或者写就绪),能够…

为什么iPhone支持整页中文OCR应用很少?有什么好的解决方法?

iPhone上面没有支持中文整页OCR识别的app,这是一个值得探讨的问题。OCR,即光学字符识别,是一种将纸质文档或图片中的文字转化为可编辑文本的技术。随着科技的发展,OCR技术已经广泛应用于各个领域,包括文档处理、图像识…

C/C++ 入门(7)string类(STL)

个人主页:仍有未知等待探索-CSDN博客 专题分栏:C 请多多指教! 目录 一、标准库中的string 1、了解 2、string类常用接口说明 1、常见的构造函数 2、容量操作 ​编辑 3、访问及遍历操作 4、修改操作 5、非成员函数 二、string类实现 …

搭建知识库-DataWhale笔记

词向量及向量知识库介绍 词向量 词向量定义 在机器学习和自然语言处理(NLP)中,词向量(Embeddings)是一种将非结构化数据,如单词、句子或者整个文档,转化为实数向量的技术。这些实数向量可以被…

Unet网络架构讲解(从零到一,逐行编写并重点讲解数据维度变化)

📚博客主页:knighthood2001 ✨公众号:认知up吧 (目前正在带领大家一起提升认知,感兴趣可以来围观一下) 🎃知识星球:【认知up吧|成长|副业】介绍 ❤️感谢大家点赞👍&…

大珩PPT助手一键颜色设置

大珩PPT助手最新推出的一键设置文字颜色和背景色功能,为用户在创建演示文稿时带来了更便捷、高效的体验。这一功能使用户能够轻松调整演示文稿中文字的颜色和幻灯片的背景色,以满足不同场合和主题的需要。 以下是该功能的几个关键特点和优势&#xff1a…

恶意游戏并非传说:它们甚至在 Steam 上也存在

三月份,玩家们在在线平台上遇到了热门游戏的假克隆。在受害者中,有一位用户购买了一款假冒游戏《最后纪元》(Last Epoch),但玩了几个小时后却出现了 "蓝屏死机"。 在联系了技术支持后,Steam 将钱…

代码随想录算法训练营Day6 | 242.有效的字母异位词 ●349. 两个数组的交集 ● 202. 快乐数● 1. 两数之和

基础: 1.哈希表是根据关键值进行直接访问的数据结构,时间复杂度是O(1),也就是通过数组的索引下标,直接访问数组中的元素哈希表的作用就是用来快速判断一个元素是否出现在集合里。 2.常见的哈希结构: 数组set &#…

CB2-2CARD之Debian(Bookworm)安装Gnome看CCTV

CB2-2CARD之Debian(Bookworm)安装Gnome看CCTV 1. 源由2. 需求3. Debian系统桌面3.1 系统安装3.2 磁盘扩容3.3 系统更新3.4 Gnome安装 4. 测试4.1 CCTV网页测试4.2 系统空闲测试4.3 Firefox CPU占用率测试 5. 总结 1. 源由 近些年来,随着国内…

arm架构,django4.2.7适配达梦8数据库

【Python相关包版本信息】 Django 4.2.7 django-dmPython 3.1.7 dmPython 2.5.5 【达梦数据库版本】 DM Database Server 64 V8 DB Version: 0x7000c 适配过程中发现的问题如下: 错误一:d…

Git | 分支管理

Git | 分支管理 文章目录 Git | 分支管理1、理解分支2、创建分支&&切换分支3、合并分支4、删除分支5、合并冲突6、分支管理策略合并分支模式实际工作中分支策略bug分支删除临时分支 1、理解分支 分支就类似分身。 在版本回退中,每次提交Git都会将修改以git…

快速部署stable diffusion@Ubuntu

Stable Diffusion可以根据文本描述生成相关的图像,是当前最热门的文生图模型。 在Ubuntu下,可以选择快速安装,或者手动一步步安装。 快速安装 使用文档中的方法,先下载一个sh文件,然后执行这个文件,就自动…

ChatGPT助力测试领域!探索人工智能编写测试用例的新前景

简介 测试用例是测试人员的核心工作内容,是测试人员思想的“实现类”,其充分体现了测试的思路,可以为后续的测试行为提供指导,是测试人员了解业务的重要根据和质量之根本。如果测试用例设计得不完成,出现了遗漏&#x…

git merge 和 git rebese的区别

git merge 和 git rebese的区别 拉取分支和合并代码会涉及两种选择,git merge 和 git rebase: rebase:变基,会有一个干净的分支,但是对于记录来源不够清楚merge:合并,git 分支看起来比较混乱&…

java-Arrays

一、Arrays的概述 Arrays是操作数组的工具类 二、Arrays的常用方法 Arrays的常用方法基本上都被static静态修饰,因此在使用这些方法时,可以直接通过类名调用 1.toString 语法:Arrays.toString(数组) 用于将数组的元素转换为一个字符串&a…

(mac)Prometheus监控之Node_exporter(CPU、内存、磁盘、网络等)

完整步骤 1.启动 Prometheus 普罗米修斯 prometheus --config.file/usr/local/etc/prometheus.yml 浏览器访问 http://localhost:9090/targets 2.启动Node_exporter node_exporter 访问:http://localhost:9100 3.启动grafana brew services start grafana 访问…