【联盛德W806上手笔记】四、PWM模块

目录

  • PWM 控制器
  • 库函数
    • 函数
    • 参数
  • 测试程序
    • 独立模式
      • main.c
      • wm_hal_msp.c
      • wm_it.c
      • 实验现象
    • 多通道同步模式
      • main.c
      • wm_hal_msp.c
      • wm_it.c
      • 实验现象

Windows 10 20H2
HLK-W806-V1.0-KIT
WM_SDK_W806_v0.6.0


       摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》

PWM 控制器

       5 通道 PWM 信号生成功能
       2 通道输入信号捕获功能(PWM0 和 PWM4 两个通路)
       频率范围:3Hz~160KHz
       占空比最大精度:1/256,插入死区的计数器宽度:8bit
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

库函数

函数

       打开wm_pwm.h,有如下的函数声明:

HAL_StatusTypeDef	HAL_PWM_Init(PWM_HandleTypeDef *hpwm);
//初始化PWM通道
HAL_StatusTypeDef	HAL_PWM_DeInit(PWM_HandleTypeDef *hpwm);
//将初始化之后的通道恢复成默认的状态–各个寄存器复位时的值
void				HAL_PWM_MspInit(PWM_HandleTypeDef *hpwm);
//用于开启对应的时钟和复用对应引脚
void				HAL_PWM_MspDeInit(PWM_HandleTypeDef *hpwm);
//将对应时钟和引脚恢复成默认的状态–各个寄存器复位时的值
HAL_StatusTypeDef	HAL_PWM_Start(PWM_HandleTypeDef *hpwm, uint32_t Channel);
//开始输出波形
HAL_StatusTypeDef	HAL_PWM_Stop(PWM_HandleTypeDef *hpwm, uint32_t Channel);
//停止输出波形
HAL_StatusTypeDef	HAL_PWM_Duty_Set(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t Duty);
//设置输出波形的占空比
HAL_StatusTypeDef	HAL_PWM_Freq_Set(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t Prescaler, uint32_t Period);
//设置输出波形的频率

参数

结构体和枚举类型

typedef struct
{uint32_t Prescaler;			/* Specifies the prescaler value used to divide the PWM clock(40MHz).This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */uint32_t CounterMode;		/* Specifies the counter mode.This parameter can be a value of @ref PWM_Counter_Mode */uint32_t Period;			/* Specifies the period value to be loaded into the PERIODRegister at the next update event.This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF.  */uint32_t Pulse;				/* Specifies the pulse value to be loaded into the Compare Register.This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */uint32_t AutoReloadPreload;	/* Specifies the auto-reload preload.This parameter can be a value of @ref TIM_AutoReloadPreload */uint32_t OutMode;			/* Specifies the output mode.This parameter can be a value of @ref PWM_Out_Mode*/uint32_t OutInverse;		/* Specifies the output polarity.This parameter can be a value of @ref PWM_Out_Inverse */uint32_t Dtdiv;				/* Specifies the prescaler value used to divide the dead zone clock(40MHz) when in complementary mode.This parameter can be a value of @ref PWM_DT_DIV */uint32_t Dtcnt;				/* Specifies the number of dead time clocks when in complementary mode.This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */} PWM_InitTypeDef;typedef struct
{PWM_TypeDef			*Instance;PWM_InitTypeDef		Init;uint32_t			Channel; /* This parameter can be a value of @ref PWM_Channel */} PWM_HandleTypeDef;

宏参数

#define PWM		((PWM_TypeDef *)PWM_BASE)// PWM_Channel
#define PWM_CHANNEL_0	0x00
#define PWM_CHANNEL_1	0x01
#define PWM_CHANNEL_2	0x02
#define PWM_CHANNEL_3	0x03
#define PWM_CHANNEL_4	0x04
#define PWM_CHANNEL_ALL	0x01F// PWM_Counter_Mode
#define PWM_COUNTERMODE_EDGEALIGNED_UP					0x0	// edge-aligned up mode for capture
#define PWM_COUNTERMODE_EDGEALIGNED_DOWN				0x1	// edge-aligned up mode for out
#define PWM_COUNTERMODE_CENTERALIGNED					0x2 // center-aligned mode for out// PWM_AutoReloadPreload
#define PWM_AUTORELOAD_PRELOAD_DISABLE                	0x00               // TIMx_ARR register is not buffered
#define PWM_AUTORELOAD_PRELOAD_ENABLE                 	0x01              // TIMx_ARR register is buffered// PWM_Out_Mode
#define PWM_OUT_MODE_INDEPENDENT						0x00
#define PWM_OUT_MODE_2SYNC								0x01
#define PWM_OUT_MODE_2COMPLEMENTARY						0x02
#define PWM_OUT_MODE_5SYNC								0x03
#define PWM_OUT_MODE_BREAK								0x04// PWM_Out_Inverse
#define PWM_OUT_INVERSE_DISABLE							0x00
#define PWM_OUT_INVERSE_ENABLE							0x01// PWM_DT_DIV
#define PWM_DTDIV_NONE									PWM_DTCR_DTDIV_1
#define PWM_DTDIV_2										PWM_DTCR_DTDIV_2
#define PWM_DTDIV_4										PWM_DTCR_DTDIV_4
#define PWM_DTDIV_8										PWM_DTCR_DTDIV_8

#define IS_PWM_INSTANCE(INSTANCE)	(((INSTANCE) == PWM))#define IS_PWM_CHANNELS(__CHANNEL__)       (((__CHANNEL__) == PWM_CHANNEL_0) || \((__CHANNEL__) == PWM_CHANNEL_1) || \((__CHANNEL__) == PWM_CHANNEL_2) || \((__CHANNEL__) == PWM_CHANNEL_3) || \((__CHANNEL__) == PWM_CHANNEL_4) || \((__CHANNEL__) == PWM_CHANNEL_ALL))#define IS_PWM_PRESCALER(__PRESCALER__) (((__PRESCALER__) >= 0x0000) && ((__PRESCALER__) <= 0x0FFFF))#define IS_PWM_COUNTER_MODE(__MODE__)      (((__MODE__) == PWM_COUNTERMODE_EDGEALIGNED_UP)              || \((__MODE__) == PWM_COUNTERMODE_EDGEALIGNED_DOWN)            || \((__MODE__) == PWM_COUNTERMODE_CENTERALIGNED))#define IS_PWM_PERIOD(__PERIOD__)	(((__PERIOD__) >= 0x00) && ((__PERIOD__) <= 0x0FF))#define IS_PWM_PULSE(__PULSE__)	(((__PULSE__) >= 0x00) && ((__PULSE__) <= 0x0FF))#define IS_PWM_AUTORELOADPRELOAD(__AUTORELOAD__) (((__AUTORELOAD__) == PWM_AUTORELOAD_PRELOAD_DISABLE) || \((__AUTORELOAD__) == PWM_AUTORELOAD_PRELOAD_ENABLE))#define IS_PWM_OUTMODE(__MODE__) (((__MODE__) == PWM_OUT_MODE_INDEPENDENT) || \((__MODE__) == PWM_OUT_MODE_2SYNC) || \((__MODE__) == PWM_OUT_MODE_2COMPLEMENTARY) || \((__MODE__) == PWM_OUT_MODE_5SYNC))#define IS_PWM_OUTINVERSE(__INVERSE__) (((__INVERSE__) == PWM_OUT_INVERSE_DISABLE) || \((__INVERSE__) == PWM_OUT_INVERSE_ENABLE))#define IS_PWM_DTDIV(__DIV__) (((__DIV__) == PWM_DTDIV_NONE) || \((__DIV__) == PWM_DTDIV_2) || \((__DIV__) == PWM_DTDIV_4) || \((__DIV__) == PWM_DTDIV_8))#define IS_PWM_DTCNT(__CNT__) (((__CNT__) >= 0) && ((__CNT__) <= 0x0FF))

测试程序

独立模式

main.c


#include <stdio.h>
#include "wm_hal.h"PWM_HandleTypeDef hpwm;static void PWM_Init(void);
void Error_Handler(void);uint32_t ch = PWM_CHANNEL_1;
int main(void)
{int i = 0;SystemClock_Config(CPU_CLK_160M);printf("enter main\r\n");PWM_Init();HAL_PWM_Start(&hpwm, ch);while (1){for (i = 0; i < 200; i++){HAL_PWM_Duty_Set(&hpwm, ch, i);HAL_Delay(20);}for (i = 200 - 1; i >= 0; i--){HAL_PWM_Duty_Set(&hpwm, ch, i);HAL_Delay(20);}}
}/* 输出波形的频率: f = 40MHz / Prescaler / (Period + 1);* 输出波形的占空比: *     沿对齐模式(递减):(Pulse + 1) / (Period + 1)*                         Pulse >= Period:PWM输出一直为高电平*                         Pulse < Period :PWM输出高电平宽度为(Pulse + 1),低电平宽度为(Period - Pulse)*                         Pulse = 0      :PWM输出高电平宽度为(1),低电平宽度为(Period)* *    中间对齐模式       :(2 * Pulse + 1) / (2 * (Period + 1))*                         Pulse > Period :PWM输出一直为高电平*                         Pulse <= Period:PWM输出高电平宽度为(2 * Pulse + 1),低电平宽度为(2 * (Period - Pulse) + 1)*                         Pulse = 0      :PWM输出高电平宽度为(1),低电平宽度为(2 * Period + 1)*/
static void PWM_Init(void)
{// 输出50Hz、占空比25%的波形hpwm.Instance = PWM;hpwm.Init.AutoReloadPreload = PWM_AUTORELOAD_PRELOAD_ENABLE;hpwm.Init.CounterMode = PWM_COUNTERMODE_EDGEALIGNED_DOWN;hpwm.Init.Prescaler = 4000;	//0~65535hpwm.Init.Period = 200 - 1;	//0~255 40MHz / 4000 / 200 = 50Hz (默认PWM时钟为40MHz)hpwm.Init.Pulse = 200 / 4 - 1;	//0~255 25% DUTYhpwm.Init.OutMode = PWM_OUT_MODE_INDEPENDENT;hpwm.Channel = ch;HAL_PWM_Init(&hpwm);
}void Error_Handler(void)
{while (1){}
}void assert_failed(uint8_t *file, uint32_t line)
{printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}

wm_hal_msp.c

       配置引脚复用。

#include "wm_hal.h"void HAL_MspInit(void)
{}void HAL_PWM_MspInit(PWM_HandleTypeDef *hpwm)
{__HAL_RCC_PWM_CLK_ENABLE();__HAL_AFIO_REMAP_PWM1(GPIOB, GPIO_PIN_1);
}void HAL_PWM_MspDeInit(PWM_HandleTypeDef *hpwm)
{__HAL_RCC_PWM_CLK_DISABLE();HAL_GPIO_DeInit(GPIOB, GPIO_PIN_1);
}

wm_it.c


#include "wm_hal.h"#define readl(addr) ({unsigned int __v = (*(volatile unsigned int *) (addr)); __v;})
__attribute__((isr)) void CORET_IRQHandler(void)
{readl(0xE000E010);HAL_IncTick();
}

实验现象

       可见输出的PWM信号为50Hz,占空比在0~100%间变化。
在这里插入图片描述

多通道同步模式

需要注意的是
配置占空比的函数是没有关于PWM_CHANNEL_ALL的实现的:
在这里插入图片描述

要用PWM_CHANNEL_0才能跑出来

main.c


#include <stdio.h>
#include "wm_hal.h"PWM_HandleTypeDef hpwm;static void PWM_Init(void);
static void GPIO_Init(void);
void Error_Handler(void);uint32_t ch = PWM_CHANNEL_0;int main(void)
{int i = 0;SystemClock_Config(CPU_CLK_160M);printf("enter main\r\n");GPIO_Init();PWM_Init();HAL_PWM_Start(&hpwm, ch);while (1){for (i = 0; i < 200; i++){HAL_PWM_Duty_Set(&hpwm, ch, i);HAL_Delay(20);}for (i = 200 - 1; i >= 0; i--){HAL_PWM_Duty_Set(&hpwm, ch, i);HAL_Delay(20);}}
}static void GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIO_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_16;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_16, GPIO_PIN_SET);
}/* 输出波形的频率: f = 40MHz / Prescaler / (Period + 1);* 输出波形的占空比: *     沿对齐模式(递减):(Pulse + 1) / (Period + 1)*                         Pulse >= Period:PWM输出一直为高电平*                         Pulse < Period :PWM输出高电平宽度为(Pulse + 1),低电平宽度为(Period - Pulse)*                         Pulse = 0      :PWM输出高电平宽度为(1),低电平宽度为(Period)* *    中间对齐模式       :(2 * Pulse + 1) / (2 * (Period + 1))*                         Pulse > Period :PWM输出一直为高电平*                         Pulse <= Period:PWM输出高电平宽度为(2 * Pulse + 1),低电平宽度为(2 * (Period - Pulse) + 1)*                         Pulse = 0      :PWM输出高电平宽度为(1),低电平宽度为(2 * Period + 1)*/
static void PWM_Init(void)
{// 输出50Hz、占空比25%的波形hpwm.Instance = PWM;hpwm.Init.AutoReloadPreload = PWM_AUTORELOAD_PRELOAD_ENABLE;hpwm.Init.CounterMode = PWM_COUNTERMODE_EDGEALIGNED_DOWN;hpwm.Init.Prescaler = 4000;	//0~65535hpwm.Init.Period = 200 - 1;	//0~255 40MHz / 4000 / 200 = 50Hz (默认PWM时钟为40MHz)hpwm.Init.Pulse = 200 / 4 - 1;	//0~255 25% DUTYhpwm.Init.OutMode = PWM_OUT_MODE_5SYNC;hpwm.Channel = ch;HAL_PWM_Init(&hpwm);
}void Error_Handler(void)
{while (1){}
}void assert_failed(uint8_t *file, uint32_t line)
{printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}

wm_hal_msp.c

#include "wm_hal.h"void HAL_MspInit(void)
{}void HAL_PWM_MspInit(PWM_HandleTypeDef *hpwm)
{__HAL_RCC_PWM_CLK_ENABLE();__HAL_AFIO_REMAP_PWM0(GPIOB, GPIO_PIN_0);__HAL_AFIO_REMAP_PWM1(GPIOB, GPIO_PIN_1);__HAL_AFIO_REMAP_PWM2(GPIOB, GPIO_PIN_2);__HAL_AFIO_REMAP_PWM3(GPIOB, GPIO_PIN_3);__HAL_AFIO_REMAP_PWM4(GPIOB, GPIO_PIN_16);
}void HAL_PWM_MspDeInit(PWM_HandleTypeDef *hpwm)
{__HAL_RCC_PWM_CLK_DISABLE();HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0);HAL_GPIO_DeInit(GPIOB, GPIO_PIN_1);HAL_GPIO_DeInit(GPIOB, GPIO_PIN_2);HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3);HAL_GPIO_DeInit(GPIOB, GPIO_PIN_16);
}

wm_it.c


#include "wm_hal.h"#define readl(addr) ({unsigned int __v = (*(volatile unsigned int *) (addr)); __v;})
__attribute__((isr)) void CORET_IRQHandler(void)
{readl(0xE000E010);HAL_IncTick();
}

实验现象

可见3个LED都实现了类似呼吸灯的效果
在这里插入图片描述

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

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

相关文章

C#中如何稳定精确地每隔5ms执行某个函数?

C#中如何稳定精确地每隔5ms执行某个函数&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「C#的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xf…

datatable 自定义搜索框 + 汉化

HTML <input type"text" id"my_news_search" class"" placeholder"搜索站内新闻"> <button class"" id"my_news_search_btn" type"button">搜索</button> JS <script>$(docu…

vlan

分割广播域1.物理分割&#xff08;路由器&#xff09;2.逻辑分割&#xff08;VLAN&#xff09;VLAN的优势&#xff1a;1.控制广播2.增强网络安全性3.简化管理VLAN的种类&#xff1a;1.静态VLAN&#xff1a;基于端口划分静态VLAN2.动态VLAN&#xff1a;基于MAC地址划分VLAN注&am…

【联盛德W806上手笔记】五、TIM定时器

目录定时器库函数函数参数宏Demo中的测试程序main.cwm_hal_msp.cwm_it.c实验现象Windows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》 定时器 微秒与毫秒计时&#xff08;据时钟频率配置计数个数&#xff…

linux驱动分离分层的概念

这个分离分层的概念和输入子系统有点像&#xff0c;但不是完全一样的。为什么会再弄一个这个模型出来我也没有搞懂&#xff0c;现在我的学习还停留在把知识学懂的层面上。至于为什么会产生这种知识&#xff0c;现在我还无从解释&#xff0c;还需时日成长。 这次先上代码在解释整…

IOS-企业开发人员账号amp;邓白氏码申请记录

Apple开发人员账号分三种&#xff0c;个人。公司&#xff0c;还有企业。个人和公司都称为标准账号。另一种是教育机构的账号。 账号介绍 个人和公司的就不说了。如今仅仅说企业账号 首先是申请企业账号的地址&#xff1a; https://developer.apple.com/programs/ios/enterpri…

wordpress置顶文章调用与设置

文章来源: https://www.xuewangzhan.net/wpbbs/15737.html wordpress网站后台允许我们设置一些置顶文章&#xff0c;然后通过调用置顶文章的代码把它调用到自己的网站前台。 下面是最常用的wordpress调用置顶文章代码&#xff0c;适用于所有模板使用。 <?php $sticky g…

【联盛德W806上手笔记】六、7816/UART 控制器

目录7816/UART 控制器串口功能7816 接口功能下载口库函数函数参数宏Demo中的测试程序main.cwm_hal_msp.cwm_it.cfifo.cfifo.hWindows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》 7816/UART 控制器 设备端…

数据库去重查询问题详解

预算2014年院线预算 影城&#xff08;多选&#xff09;北京CBD影城 查询 科目蚌埠万达广场店北京CBD影城  营业收入11 票房收入11 卖品收入00 逾期收入00 广告收入00 映前广告00 LCD广告00 阵地收入00 IMAX广告收入00 其他广告收入00 其…

MySQL5.7更改用户名密码

ALTER USER test% IDENTIFIED BY 123456; https://www.cnblogs.com/paul8339/p/9054497.html 更改用户名密码&#xff0c;官方推荐使用alter ALTER USER test% IDENTIFIED BY 123456; 还有一种 update mysql.user set authentication_stringpassword("新密码") …

python 装饰器 三 (带有参数的装饰器)

#接受装饰器的参数def deco_arg(deco_arg):#接受函数 此列为func1def deco_func(*argv,**kwag):#接受函数的方法 此列为 a bdef _deco_func(*argv,**kwarg):print "before -------执行函数前"print "%s -------打印装饰器的参数"% deco_argret deco_f…

jQuery、jQury UI、jQuery Mobile----读书笔记

<!DOCTYPE html> <html> <head><meta charset"utf-8"> <meta name keywords content""> <meta name descriptioon content“jQuery、jQury UI、jQuery Mobile”> <title>jQuery、jQury UI、jQuery …

【联盛德W806上手笔记】七、I2C

目录WM_SDK_W806_v0.6.0的库函数函数参数宏应用示例初始化使用测试I2C 控制器功能概述主要特性功能描述传输速率选择中断及启动停止可控快速输出及检测信号寄存器描述寄存器列表时钟分频寄存器_1时钟分频寄存器_2控制寄存器数据寄存器收发控制寄存器TXR 读出寄存器CR 读出寄存器…

WordPress如何获取文章所属分类ID、名称或别名?

https://boke112.com/bkwd/4269.html 在 wordpress 主题制作过程中&#xff0c;我们可能会经常用到当前分类 ID&#xff0c;如&#xff1a;在文章页获取该文章分类下的相关文章&#xff0c;这时就可能用到当前分类 ID&#xff0c;即当前文章所在的分类 ID。那么&#xff0c;wor…

【联盛德W806上手笔记】八、SPI及其DMA

目录高速 SPI 设备控制器库函数函数参数宏应用示例初始化引脚复用中断相关使用注意事项DataAlignmentDirection测试main.cwm_hal_msp.cwm_it.c其他改动实验现象Windows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书…

安装配置 radicale

为什么80%的码农都做不了架构师&#xff1f;>>> 可以直接pip安装,也可以下载源码安装,如果要存储到sql里面,则需要下载源码包,用里面的schema.sql 建表 默认安装后没有相应的配置文件,源码包里面也包含了 logging 和config,放到/etc/radicale 下 安装没什么说的,下…

散分,并如何判断时间段上有重叠冲突。

比如某个会议室的预订信息表 roomBookInfo(id,title,beginTime,endTime), 现在有一个新的预订请求 bTime, eTIme 分别 代表 开始、结束时间。请检查下表中的记录&#xff0c;查看是否有时间上的冲突。create table roomBookInfo (id int auto_increment primary key, title var…

wordpress 根据文章ID获取分类ID和标签ID

//wordpress 根据文章ID获取分类ID $categoryget_the_category( $post_ID ); $catid$category[0]->term_id; //wordpress 根据文章ID获取标签ID $tagswp_get_post_tags( $post_ID ); $tagid$tags[0]->term_id; 查看完整内容&#xff1a;http://web.zhaicool.net/366…

实现复选框的单选效果

<!DOCTYPE><html><head><title>实现复选框的单选效果</title></head><body><form methodpost action""><input type"checkbox" name"aa" οnclick"bb(this)"><input type&q…