当前位置: 首页 > news >正文

PWM常用库函数(STC8系列)

STC8系列PWM操作常用库函数

STC8系列单片机通过增强型PWM模块提供灵活的脉冲宽度调制功能。以下是核心库函数及其使用说明:

1. PWM初始化函数

普通版:

/*** @brief 初始化PWM通道* @param ch: PWM通道号 (0-7)* @param freq: PWM频率 (单位: Hz)* @param duty: 初始占空比 (0.0-1.0)*/
void PWM_Init(uint8_t ch, uint32_t freq, float duty);

功能:配置PWM时钟源、分频系数和周期寄存器。频率范围参考公式:
fPWM=fsys(PWMAPS+1)×(PWMAARR+1)f_{PWM} = \frac{f_{sys}}{(PWMA_PS + 1) \times (PWMA_ARR + 1)}fPWM=(PWMAPS+1)×(PWMAARR+1)fsys

函数版:

#define PERIOD (MAIN_Fosc / 1000)
PWMx_Duty dutyA;
void	PWM_config(void)
{PWMx_InitDefine		PWMx_InitStructure;// 配置PWM1PWMx_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_MODE2PWMx_InitStructure.PWM_Duty    		= dutyA.PWM1_Duty;	//PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect	= ENO1P | ENO1N;	//输出通道选择,	ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM1, &PWMx_InitStructure);			//初始化PWM// 配置PWM2PWMx_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_MODE2PWMx_InitStructure.PWM_Duty    		= dutyA.PWM2_Duty;	//PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect    = ENO2P | ENO2N;	//输出通道选择,	ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM2, &PWMx_InitStructure);			//初始化PWM// 配置PWM3PWMx_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_MODE2PWMx_InitStructure.PWM_Duty    		= dutyA.PWM3_Duty;	//PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect    = ENO3P | ENO3N;	//输出通道选择,	ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM3, &PWMx_InitStructure);	// 配置PWM4PWMx_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_MODE2PWMx_InitStructure.PWM_Duty    		= dutyA.PWM4_Duty;	//PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect    = ENO4P | ENO4N;	//输出通道选择,	ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM4, &PWMx_InitStructure);// 配置PWMAPWMx_InitStructure.PWM_Period   = PERIOD - 1;			//周期时间,   0~65535PWMx_InitStructure.PWM_DeadTime = 0;					//死区发生器设置, 0~255PWMx_InitStructure.PWM_MainOutEnable= ENABLE;			//主输出使能, ENABLE,DISABLEPWMx_InitStructure.PWM_CEN_Enable   = ENABLE;			//使能计数器, ENABLE,DISABLEPWM_Configuration(PWMA, &PWMx_InitStructure);			//初始化PWM通用寄存器,  PWMA,PWMB// 切换PWM通道PWM1_SW(PWM1_SW_P10_P11);			//PWM1_SW_P10_P11,PWM1_SW_P20_P21,PWM1_SW_P60_P61PWM2_SW(PWM2_SW_P12_P13);			//PWM2_SW_P12_P13,PWM2_SW_P22_P23,PWM2_SW_P62_P63PWM3_SW(PWM3_SW_P14_P15);			//PWM3_SW_P14_P15,PWM3_SW_P24_P25,PWM3_SW_P64_P65PWM4_SW(PWM4_SW_P16_P17);			//PWM4_SW_P16_P17,PWM4_SW_P26_P27,PWM4_SW_P66_P67,PWM4_SW_P34_P33// 初始化PWMA的中断NVIC_PWM_Init(PWMA,DISABLE,Priority_0);
}

实现原理:通过修改捕获比较寄存器值:
CCR=duty×(ARR+1)CCR = duty \times (ARR + 1)CCR=duty×(ARR+1)

2. 扩展寄存器访问使能
EAXSFR();		/* 扩展寄存器访问使能 */
//写在main函数中
3. 频率更新函数
/*** @brief 动态更新PWM频率* @param ch: PWM通道号* @param freq: 新频率值 (单位: Hz)*/
void PWM_SetFreq(uint8_t ch, uint32_t freq);

注意:修改频率时会保持当前占空比不变。

4. PWM输出控制
// 开启PWM输出
void PWM_Enable(uint8_t ch);// 关闭PWM输出
void PWM_Disable(uint8_t ch);

使用示例

使用了库函数封装的一些数据

#include "GPIO.h"			//依赖的库函数
#include"Delay.h"
#include "UART.h"
#include "NVIC.h"
#include "Switch.h"
#include "STC8H_PWM.h"// 1000就是频率   周期 1s/1000  ===>  1ms
#define PERIOD 	(MAIN_Fosc / 1000)	// 周期
#define LED_SW  P45
#define LED1 P27
#define LED2 P26
#define LED3 P15
#define LED4 P14
#define LED5 P23
#define LED6 P22
#define LED7 P21
#define LED8 P20void GPIO_config(void) {GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义GPIO_InitStructure.Pin  = GPIO_Pin_0 |GPIO_Pin_1;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P3, &GPIO_InitStructure);//初始化P4_MODE_IO_PU(GPIO_Pin_5);P2_MODE_IO_PU(GPIO_Pin_7);P2_MODE_IO_PU(GPIO_Pin_6);P1_MODE_IO_PU(GPIO_Pin_5);P1_MODE_IO_PU(GPIO_Pin_4);P2_MODE_IO_PU(GPIO_Pin_3);P2_MODE_IO_PU(GPIO_Pin_2);P2_MODE_IO_PU(GPIO_Pin_1);P2_MODE_IO_PU(GPIO_Pin_0);LED_SW = 0 ; }
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_BRTxCOMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLEUART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART1_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()
{PWMx_InitDefine		PWMx_InitStructure;// 配置PWM4   // ===========================    模式  需要先用1            PWMx_InitStructure.PWM_Mode    =	CCMRn_PWM_MODE1;	//模式// =========================== PWM高电平占空比时间, 0~PeriodPWMx_InitStructure.PWM_Duty    =  (0.0/100.0) * PERIOD;								// ===========================     只用ENO4NPWMx_InitStructure.PWM_EnoSelect  = ENO4P|ENO4N;	//输出通道选择,	ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM4, &PWMx_InitStructure);// 配置PWMA// ===========================  周期 - 1PWMx_InitStructure.PWM_Period   = PERIOD - 1;			//周期时间,   0~65535PWMx_InitStructure.PWM_DeadTime = 0;					//死区发生器设置, 0~255PWMx_InitStructure.PWM_MainOutEnable= ENABLE;			//主输出使能, ENABLE,DISABLEPWMx_InitStructure.PWM_CEN_Enable   = ENABLE;			//使能计数器, ENABLE,DISABLEPWM_Configuration(PWMA, &PWMx_InitStructure);			//初始化PWM通用寄存器,  PWMA,PWMB// 切换PWM4选择PWM4_SW_P26_P27PWM4_SW(PWM4_SW_P26_P27);			//PWM4_SW_P16_P17,PWM4_SW_P26_P27,PWM4_SW_P66_P67,PWM4_SW_P34_P33// 初始化PWMA的中断NVIC_PWM_Init(PWMA,DISABLE,Priority_0);
}
void PWM4_Updata_duty(char value){PWMx_Duty duty;duty.PWM4_Duty =(value /100.0)*PERIOD;UpdatePwm(PWM4,&duty);}void main() {char value = 50 ;u8 i ;EAXSFR ();EA = 1;GPIO_config();UART_config();PWM_config();PWM4_Updata_duty(value);while (1){ //超时计数if(--COM1.RX_TimeOut == 0) {if(COM1.RX_Cnt > 0) {// 这里处理收到的数据,做具体的逻辑,可以调用自己的on_uart1_recvfor(i=0; i<COM1.RX_Cnt; i++)	{// RX1_Buffer[i]存的是接收的每个字节,写出用 TX1_write2buff}if (RX1_Buffer[0] == 0x01){value+=5;if (value >100)value = 100;}else if (RX1_Buffer[0] == 0x02){value-=5;if (value <0)value = 0;}PWM4_Updata_duty(value);printf("value = %d\n",(int)value);}COM1.RX_Cnt = 0;}
}// 不要处理的太快
delay_ms(10);}
http://www.dtcms.com/a/320038.html

相关文章:

  • 【Linux基础知识系列】第八十七篇 - 使用df命令查看磁盘空间
  • 橙河网络:Cint站点如何注册?好做吗?
  • 街道垃圾识别准确率↑32%:陌讯多模态融合算法实战解析
  • 解锁制药新质生产力:合规与效率双赢的数字化转型之道
  • 基于肌电信号的神经网络动作识别系统
  • docker mysql 5.6
  • CSS--:root指定变量,其他元素引用
  • 【题解】洛谷P3172 [CQOI2015] 选数[杜教筛]
  • 【mtcnn】--论文详解重点001之窗口滑动~
  • 板块三章节4——iSCSI 服务器(待更新)
  • python数据结构与算法(基础)
  • 栅栏密码的加密解密原理
  • RISCV instr 第31-40章
  • 钢卷矫平机背后的材料科学
  • 10-netty基础-手写rpc-定义协议头-02
  • 进程、网络通信方法
  • 机器学习通关秘籍|Day 04:梯度下降的概念原理、手动实现梯度下降
  • 商城小程序怎么做?如何开发母婴用品商城小程序?
  • Redis 编译错误:缺少静态库文件,如何解决?
  • 股指期货合约是个啥?怎么玩?
  • GitCode 7月:小程序积分商城更名成长中心、「探索智能仓颉!Cangjie Magic 体验有奖征文活动」圆满收官、深度对话栏目持续热播
  • 2025年我国半导体材料产业链全景分析
  • 遥感卫星领域的AI应用
  • 经营帮:重构企业经营全流程,打造产业互联网新生态
  • 靶场(二十九)---小白心得靶场体会---BitForge
  • MySQL 极简安装挑战:跨平台高效部署指南
  • C语言 16_day
  • 【Linux基础知识系列】第八十九篇 - 文件内容快速查看:使用cat与tac
  • 容器之王--部署Docker私有仓库harbor母盘步骤演练
  • 使用python基于langchain来写一个ai agent