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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 十、PWM脉宽调制信号的发生与控制 -> 正文阅读

[嵌入式]十、PWM脉宽调制信号的发生与控制

调整占空比,脉宽调制作用:

①直流电机的调速

②灯光的控制:亮度

③声音大小

④舵机角度调整

利用PWM脉宽信号实现独立按键S7(J5跳帽2、3)L1指示灯亮度变化的控制。

①PWM脉宽信号的频率为100Hz

②系统上电后L1指示灯处在熄灭状态

③L1指示灯有4种亮度模式,分别是完全熄灭10%亮度、50%亮度、90%亮度

按下S7按键,循环切换L1指示灯的4种亮度模式?

分析:

①100Hz = 0.01s = 10ms = 10000us? (周期为10ms)?

将周期分为100等份 = 100 * 100us(每100us产生一次中断 65535 - 100)

怎样产生60%占空比:60次高电平,40次低电平(设count计数)

系统上电后L1指示灯处在熄灭状态:先产生低电平

1、自己写的代码(按键读取部分有点问题,为什么容易误判?)

#include "reg52.h"

sbit S7 = P3^0;
sbit L1 = P0^0;

sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;

void InitHC138()//选LED
{
	HC138_C = 1;
	HC138_B = 0;
	HC138_A = 0;
}

//************定时器相关函数****************************************
unsigned char count = 0;
unsigned char PWM_duty = 0;//PWM占空比
	
void InitTimer0() //中断函数
{
	TMOD = 0x01;
	TH0 = (65535 - 100) / 256; //100Hz = 0.01s = 10ms = 100*100us
	TL0 = (65535 - 100) % 256; //将周期分为100份 = 100us产生一次中断
	
	ET0 = 1;//打开定时器中断
	EA = 1;//打开总中断
	
//TR0 = 1; (启动定时器)先不打开,等需要产生脉宽调制的时候再打开
}

void ServiceTimer0() interrupt 1 //中断服务函数
{
	TH0 = (65535 - 100) / 256; 
	TL0 = (65535 - 100) % 256;//自动重装
	
	count++;
	if (count <= PWM_duty)//计数<=PWM占空比 L1亮
	{
		L1 = 0;
	}
	else if (count < 100)//PWM占空比<计数<100(周期) L1灭
	{
		L1 = 1;
	}
	else if (count == 100)//计数达到一个周期,L1灭,count清零,继续循环
	{
		L1 = 0;
		count = 0;
	}
	
//方法二
//count++;
//if (count == PWM_duty)
//{
//	L1 = 1;
//}
//else if (count == 100)
//{
//	L1 = 0;
//	count = 0;
//}
}

//*****************************************************************


//************按键操作************************************************
void DelayKey(unsigned int t) //按键消抖函数
{
	while(t--);
}

unsigned char flat = 0;//标志位(0时灯灭)

void ScanKeys() //按下S7按键,循环切换L1指示灯的4种亮度模式
{
	if (S7 == 0)
	{
		DelayKey(100);//按键消抖
		if (S7 == 0)
		{
			if (flat == 0)//10%亮度
			{
				L1 = 0;
				TR0 = 1;//启动定时器
				PWM_duty = 10;
				flat = 1;
			}
			else if (flat == 1)//50%亮度
			{
				PWM_duty = 50;
				flat = 2;
			}
			else if (flat == 2)//90%亮度
			{
				PWM_duty = 90;
				flat = 3;
			}
			else if (flat == 3)//灭灯,进入下一次循环
			{
				L1 = 1;
				TR0 = 0;//关闭定时器
				flat = 0;//循环
			}
			while(!S7);//松开后,再进行读取(防止误判)
		}
	}
}
//*******************************************************************

void main()
{
	InitHC138();
	L1 = 1; //系统上电后L1指示灯处在熄灭状态
	InitTimer0();
	while(1)
	{
		ScanKeys();
	}
}

2、标准代码(也有相同情况)

#include "reg52.h"

sbit S7 = P3^0;
sbit L1 = P0^0;

sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;

void InitHC138()//选LED
{
	HC138_C = 1;
	HC138_B = 0;
	HC138_A = 0;
}

//************定时器相关函数****************************************
unsigned char count = 0;
unsigned char PWM_duty = 0;//PWM占空比
	
void InitTimer0() //中断函数
{
	TMOD = 0x01;
	TH0 = (65535 - 100) / 256; //100Hz = 0.01s = 10ms = 100*100us
	TL0 = (65535 - 100) % 256; //将周期分为100份 = 100us产生一次中断
	
	ET0 = 1;//打开定时器中断
	EA = 1;//打开总中断
	
//TR0 = 1; (启动定时器)先不打开,等需要产生脉宽调制的时候再打开
}

void ServiceTimer0() interrupt 1 //中断服务函数
{
	TH0 = (65535 - 100) / 256; 
	TL0 = (65535 - 100) % 256;//自动重装
	
	count++;
	if (count <= PWM_duty)//计数<=PWM占空比 L1亮
	{
		L1 = 0;
	}
	else if (count < 100)//PWM占空比<计数<100(周期) L1灭
	{
		L1 = 1;
	}
	else if (count == 100)//计数达到一个周期,L1灭,count清零,继续循环
	{
		L1 = 0;
		count = 0;
	}
	
//方法二
//count++;
//if (count == PWM_duty)
//{
//	L1 = 1;
//}
//else if (count == 100)
//{
//	L1 = 0;
//	count = 0;
//}
}

//*****************************************************************


//************按键操作************************************************
void DelayKey(unsigned int t) //按键消抖函数
{
	while(t--);
}

unsigned char flat = 0;//标志位(0时灯灭)

void ScanKeys() //按下S7按键,循环切换L1指示灯的4种亮度模式
{
	if (S7 == 0)
	{
		DelayKey(100);//按键消抖
		if (S7 == 0)
		{
			switch(flat)
			{
				case 0:  //10%亮度
					L1 = 0;
					TR0 = 1;//启动定时器
					PWM_duty = 10;
					flat = 1;
				break;
				
				case 1:  //50%亮度
					PWM_duty = 50;
					flat = 2;
				break;
				
				case 2:  //90%亮度
					PWM_duty = 90;
					flat = 3;
				break;
				
				case 3:  //灯灭,进入下一次循环
					L1 = 1;
					TR0 = 0;//关闭定时器
					flat = 0;
				break;
			}
			while(!S7);//松开后,再进行读取(防止误判)
		}
	}
}
//*******************************************************************

void main()
{
	InitHC138();
	L1 = 1; //系统上电后L1指示灯处在熄灭状态
	InitTimer0();
	while(1)
	{
		ScanKeys();
	}
}

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-02-03 01:20:18  更:2022-02-03 01:20:22 
 
开发: 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/26 10:41:47-

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