IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STC16f40k128——PWM -> 正文阅读

[嵌入式]STC16f40k128——PWM

前言

PWM(全称Pulse Width Modulation,定频调宽度调制技术),是近年来发展的一种电力电子技术,广泛应用于开关电源,电能变换领域,以及电机驱动等众多领域。PWM本质上是高频率,但占空比可能变化的脉冲波

产生专门产生PWM信号的集成芯片,也可以使用MCU或者DSP进行配置产生PWM。数字控制器生成PWM具有灵活方便的优点,因此广泛使用控制器产生期望的PWM进行控制。

STC16F系列的单片机内部集成有PWMA,PWMB类高级PWM。PWMA有8个通道,PWMA1P,PWMA1N到PWMA4P,PWMA4N。

每一个PWMxP和对应的PWMxN互为一组PWM。可以输出带死区互补对称PWM。而PWMB只有4个通道,分别是PWM5,PWM6,PWM7,PWM8.

实际开发产品的过程中,基本上都有可能使用到互补对称的PWM波,并且STC16F系列的PWMA类的PWM通道完全够用。因此只需要掌握PWMA的配置方式以及使用方法即可。

PWM产生原理

TB(Time Base时基)模块

在这里插入图片描述
CK_PSC是主时钟,经预分频器分频后,作为16位计数器[PWM1_CNTRH:PWM1_CNTRL]的计数脉冲。
这个计数器有3种计数模式,向上计数,向下计数或中央对齐模式。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
当16位计数器溢出之后,会重新装载重装值进行下一次计数。(类似于定时器的自动重装载模式)

重复计数寄存器PWM1_RCR用于设置多少次计数器溢出产生一次更新时间。
在这里插入图片描述

比较输出模块

比较输出模块的主要功能是将TB模块中的定时器与一个16位的寄存器[CCRxH:CCRxL]中的值作比较。
当PWMx_CNT<[CCRxH:CCRxL]以及PWMx_CNT>[CCRxH:CCRxL]时,PWM输出端口的极性。
在这里插入图片描述
一种PWM波形配置
在这里插入图片描述

代码配置

综上所述,只需要对PWMx的TB模块和输出比较模块进行相应的配置即可输出对应的PWM波。但是由于STC16F系列的PWM输出端口很灵活,可以根据软件配置在不同的IO口输出PWM。
在这里插入图片描述
编写pwm.c文件

#include "STC16f.h"
#include "pwm.h"
#include "led.h"

int PWM1_Duty = 0.1 * TBPRD;
int PWM2_Duty = 0.1 * TBPRD;
int PWM3_Duty = 0.5 * TBPRD;
int PWM4_Duty = 0.9 * TBPRD;  

void Init_PWMA()
{
	P_SW2 |= 0x80; 

	PWMA_CCER1 = 0x00; // PWMA的所有通道
	PWMA_CCER2 = 0x00; // 
	// 预分频设置
	PWMA_PSCRH = (PreScale-1) >> 8;
	PWMA_PSCRL = PreScale-1;
	
	// 写PWMA的动作
	// PWM_CCMRx 寄存器用于配置PWMAx通道
	PWMA_CCMR1 = 0x60; // upcount,CNT<CCR output 1
	PWMA_CCMR2 = 0x60;
    PWMA_CCMR3 = 0x60;
    PWMA_CCMR4 = 0x60;
	// CCER1 configures PWM1/2, 使能和输出极性
	// CCER2 configures PWM3/4, 使能和输出极性
	PWMA_CCER1 = 0x55; 
	PWMA_CCER2 = 0x55;
	// 设置载波计数周期
	PWMA_ARRH = (TBPRD - 1) >> 8;
	PWMA_ARRL = TBPRD - 1;
	// 使能输出
	PWMA_ENO = 0x00;
    PWMA_ENO |= ENO1P; //使能输出
//    PWMA_ENO |= ENO1N; //使能输出
    PWMA_ENO |= ENO2P; //使能输出
//    PWMA_ENO |= ENO2N; //使能输出
//    PWMA_ENO |= ENO3P; //使能输出
//    PWMA_ENO |= ENO3N; //使能输出
//    PWMA_ENO |= ENO4P; //使能输出
//    PWMA_ENO |= ENO4N; //使能输出

	PWMA_CCR1H = ((unsigned int)PWM1_Duty >> 8); //设置占空比时间
    PWMA_CCR1L = ((unsigned int)PWM1_Duty);
    PWMA_CCR2H = ((unsigned int)PWM2_Duty >> 8); //设置占空比时间
    PWMA_CCR2L = ((unsigned int)PWM2_Duty);
    PWMA_CCR3H = ((unsigned int)PWM3_Duty >> 8); //设置占空比时间
    PWMA_CCR3L = ((unsigned int)PWM3_Duty);
    PWMA_CCR4H = ((unsigned int)PWM4_Duty >> 8); //设置占空比时间
    PWMA_CCR4L = ((unsigned int)PWM4_Duty);
//   选择输出脚位
	PWMA_PS = 0x00;  //高级 PWM 通道输出脚选择位
    PWMA_PS |= PWM1_2; //选择 PWM1_2 通道
    PWMA_PS |= PWM2_2; //选择 PWM2_2 通道
    PWMA_PS |= PWM3_2; //选择 PWM3_2 通道
    PWMA_PS |= PWM4_2; //选择 PWM4_2 通道
	

	
	// 设置死区
	PWMA_DTR = 50; // 50*10e-6
	
	// 设置PWMA中断
//	PWMA_IER |= 0x01; // 更新时中断
//	PWMA_IER |= 1<<1; PWMA1 比较 捕获
//	PWMA_IER |= 1<<2; PWMA1 比较 捕获
//	PWMA_IER |= 1<<3; PWMA1 比较 捕获
//	PWMA_IER |= 1<<4; PWMA1 比较 捕获
	
	PWMA_BKR |= 0x80; // 使能总输出
	PWMA_CR1 |= 0x01; // 开始计数
	
	P_SW2 &= 0x7f;
}
void Forward()
{
	AIN1 = 0;
	AIN2 = 1;
	BIN1 = 0;
	BIN2 = 1;
}
void Backward()
{
	AIN1=1;
	AIN2=0;
	BIN1=1;
	BIN2=0;
}
void PWM1_Duty_Update(unsigned int cmp)
{
	P_SW2 |= 0x80;
	if(cmp > 0.95 * TBPRD)
		cmp = 0.95 * TBPRD;
	else if(cmp < 0.05 * TBPRD)
		cmp = 0.05 * TBPRD;
	PWMA_CCR1H = ((unsigned int)cmp >> 8); //设置占空比时间
	PWMA_CCR1L = ((unsigned int)cmp);
	
	P_SW2 &= 0x7f;
}
void PWM2_Duty_Update(unsigned int cmp)
{	
	P_SW2 |= 0x80;
	if(cmp > 0.95 * TBPRD)
		cmp = 0.95 * TBPRD;
	else if(cmp < 0.05 * TBPRD)
		cmp = 0.05 * TBPRD;
	
	PWMA_CCR2H = ((unsigned int)cmp >> 8); //设置占空比时间
	PWMA_CCR2L = ((unsigned int)cmp);
	
	P_SW2 &= 0x7f;
}
void PWM3_Duty_Update(unsigned int cmp)
{
	P_SW2 |= 0x80;
	if(cmp > 0.95 * TBPRD)
		cmp = 0.95 * TBPRD;
	else if(cmp < 0.05 * TBPRD)
		cmp = 0.05 * TBPRD;
	PWMA_CCR3H = ((unsigned int)cmp >> 8); //设置占空比时间
	PWMA_CCR3L = ((unsigned int)cmp);
	
	P_SW2 &= 0x7f;
}
void PWM4_Duty_Update(unsigned int cmp)
{	
	P_SW2 |= 0x80;
	if(cmp > 0.95 * TBPRD)
		cmp = 0.95 * TBPRD;
	else if(cmp < 0.05 * TBPRD)
		cmp = 0.05 * TBPRD;
	
	PWMA_CCR4H = ((unsigned int)cmp >> 8); //设置占空比时间
	PWMA_CCR4L = ((unsigned int)cmp);
	
	P_SW2 &= 0x7f;
}
void PWMA_Routine(void) interrupt 7
{
	static int i=0;
	static int j=0;
	i++;
	if(i>=2000)
	{
		i=0;
		j++;
		if(j==500)
		{
			j=0;
		}
	}	
}

编写pwm.h文件

#ifndef _PWM_H_
#define _PWM_H_
 
#define AIN1 P05
#define AIN2 P07
#define BIN1 P03
#define BIN2 P02

#define PreScale 24 // 对主频进行的分频系数
#define TBPRD  100// 时基模块的计数值,决定开关周期

// PWMA各个通道的端口选择
#define PWM1_0      0x00	//P:P1.0  N:P1.1
#define PWM1_1      0x01	//P:P2.0  N:P2.1
#define PWM1_2      0x02	//P:P6.0  N:P6.1

#define PWM2_0      0x00	//P:P5.4  N:P1.3
#define PWM2_1      0x04	//P:P2.2  N:P2.3
#define PWM2_2      0x08	//P:P6.2  N:P6.3

#define PWM3_0      0x00	//P:P1.4  N:P1.5
#define PWM3_1      0x10	//P:P2.4  N:P2.5
#define PWM3_2      0x20	//P:P6.4  N:P6.5

#define PWM4_0      0x00	//P:P1.6  N:P1.7
#define PWM4_1      0x40	//P:P2.6  N:P2.7
#define PWM4_2      0x80	//P:P6.6  N:P6.7
#define PWM4_3      0xC0	//P:P3.4  N:P3.3

// PWM输出端口使能
#define ENO1P       0x01
#define ENO1N       0x02
#define ENO2P       0x04
#define ENO2N       0x08
#define ENO3P       0x10
#define ENO3N       0x20
#define ENO4P       0x40
#define ENO4N       0x80

extern int PWM1_Duty;
extern int PWM2_Duty;
extern int PWM3_Duty;
extern int PWM4_Duty;

void InitPWMA(void);
void Forward(void);
void Backward(void);
void PWM1_Duty_Update(unsigned int cmp);
void PWM2_Duty_Update(unsigned int cmp);
void PWM3_Duty_Update(unsigned int cmp);
void PWM4_Duty_Update(unsigned int cmp);
//void PWMA_Routine(void) interrupt 7

#endif
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:42:58  更:2022-11-05 00:45:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 16:35:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码