51单片机学习笔记:定时器产生PWM可调方波,控制led灯亮度

2023-05-16

使用定时器T0产生PWM方波,

用按键调整占空比,20级可调

控制led灯的亮度等级.

 


#include  "my51.h"
#include  "timer0.h"

#define grading    20 	   	   //亮度20级变化
sbit keyS3=P3^5; 			   //按键调整占空比,PWM_keyChange++
sbit keyS4=P3^6; 			   //				PWM_keyChange--

u8 PWM_keyChange=10;	  	   //初值,按键调整在1~20之间变化
							   //占空比   PWM_keyChange/grading

void T0_work()				   //本函数由T0定时器中断函数调用
{	
	if(timeMultiple1Flag)
	{		
		led=off(7);			   //关闭7号灯
		timeMultiple1Flag=0;   //清定时器复用置位标志
	}
	
	if(timeMultiple2Flag)
	{		
		led=on(7);			   //打开7号灯
		timeMultiple2Flag=0;   //清定时器复用置位标志
	}  		
}

void main()				    	//测试
{
	u8 keyFlag=1;				//程序中没有消抖处理,只是简易的按键进出自锁标志
	led0=ledon;					//先打开0号灯,用于和7号灯对比亮度		
	initT0(1,10,grading);		//1毫秒的基本定时,亮的时间1*10毫秒,暗1*(grading-10)毫秒
	while(1)
	{
		if(0==keyS3)
		{
			if(keyFlag)			   			  //防止一次按键中多次执行
			{
				keyFlag=0;		   			  //清标志,类似同步锁
				if(++PWM_keyChange>grading)
				{
					PWM_keyChange=grading;	  //占空比最大100%
				}
				initT0(1,PWM_keyChange,grading);	
			}			
		}
		else if(0==keyS4)
		{
			if(keyFlag)
			{
				keyFlag=0;
				if(0==--PWM_keyChange)				//占空比减小
				{
					PWM_keyChange=1;  				//最小占空比 1/20
				}	
				initT0(1,PWM_keyChange,grading);	//占空比减小
			}
		}
		else
		{
			keyFlag=1;	//按键锁释放标志,下一次按键时允许调整占空比
		}
	}
}
  

 


#ifndef _MY51_H
#define _MY51_H
#include <reg52.h>
//#include <math.h>
#include <intrins.h>
#include <stdio.h>
#include "mytype.h"


#ifndef _51LED_
#define _51LED_
#define led 	  P1      			 //P1总线连8个led灯,灯连573锁存器,P1置低电平点亮
#define LED		  led
#define ON(x)     P1&(~(1<<(x)))	 //打开某个灯,开多个灯用 ON(m) & ON(n)
#define OFF(x)    P1|(1<<(x))	 	 //关闭某个灯,关多个灯用 OFF(m)| OFF(n)
#define on(x)	  ON(x)				 //包含大小写
#define off(x)	  OFF(x)

#define ledon     0					 //某个灯,打开
#define ledoff    1					 //某个灯,关闭

sbit led0=P1^0;     
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;	
sbit ledLock=P2^5;	//锁定当前8个led的状态,0锁定 ,1不锁定

#endif

/*************二进制输入宏****************************/
#ifndef _LongToBin_
#define LongToBin(n) \ 			   
(					 \ 
((n >> 21) & 0x80) | \ 
((n >> 18) & 0x40) | \ 
((n >> 15) & 0x20) | \ 
((n >> 12) & 0x10) | \ 
((n >> 9)  & 0x08) | \ 
((n >> 6)  & 0x04) | \ 
((n >> 3)  & 0x02) | \ 
((n ) & 0x01) 		 \ 
)
#define  bin(n)  LongToBin(0x##n##l)
#define  BIN(n)  bin(n)
#define  B(n)    bin(n)
#define  b(n)    bin(n)			  
#endif

/*************单个数据位的置位宏*********************/
#ifndef   _BIT_
#define   BIT(n)   (1<<n)
#define   bit(n)   BIT(n)
#endif

#define high	1   //高电平
#define low		0   //低电平


sbit beep=P2^3;     //蜂鸣器

extern void delayms(u16 ms);
extern void delayXus(u8 us); //函数执行(8+6x)个机器周期, 即t=(8+6x)*1.085
/


#endif  

 


#ifndef _TIMER0_H
#define _TIMER0_H
#include "my51.h"


extern u8   timeMultiple1Flag; //中断时间复用置位标志,须手动清零
extern u8   timeMultiple2Flag; //中断时间复用置位标志,须手动清零
extern void T0_work(); 		   //该函数未实现,需外部实现
extern void initT0(u8 ms,u16 t_multiple1,u16 t_multiple2) ; //定时器初始化


#endif  

 


#include "timer0.h"

u8   TH0Cout=0 ;	     //初值	
u8   TL0Cout=0 ;	   
u16  T0IntCouts1=0;     	 //中断计数
u16  T0IntCouts2=0;     	 //中断计数
u16  timeMultiple1=0;     //中断复用时间的倍数
u16  timeMultiple2=0;     //中断复用时间的倍数
u8   timeMultiple1Flag=0; //中断时间复用置位标志,须手动清零
u8   timeMultiple2Flag=0; //中断时间复用置位标志,须手动清零

//开启定时器,定时完成后需要手动关闭TR0,否则将循环定时
//参数一是定时的毫秒数,参数二和三是定时基时的倍率数(定时复用)
void initT0(u8 ms,u16 t_multiple1,u16 t_multiple2)  	 //定时器初始化设定,ms取值不超过65
{	
	u16   N=11059.2*ms/12; 				 //定时器总计数值
	TR0=STOP;							 //停掉定时器
	ET0=CLOSE;							 //关定时器中断

	//对于110592晶振,ms为5的整数倍时没有计算误差,但ms最大不超过71毫秒
	TH0Cout =(65536-N)/256;      	 	 //装入计时值零头计数初值
	TL0Cout =(65536-N)%256;
	if(0==t_multiple1)	  //0倍的基准时间是不合理的,至少1倍
	{
		t_multiple1=1;	
	}
	if(0==t_multiple2)	  //0倍的基准时间是不合理的,至少1倍
	{
		t_multiple2=1;	
	}
	timeMultiple1=t_multiple1;		 //倍时
	timeMultiple2=t_multiple2;		 //倍时
	TMOD &= 0xf0;					 //清定时器0配置
	TMOD |= 0x01; 					 //配置定时器0的工作方式为1
	
	EA =OPEN;   		//打开总中断
	ET0=OPEN;   		//打开定时器中断

	TH0=TH0Cout;  		//定时器装入初值
	TL0=TL0Cout;
	TR0=START;	 		//启动定时器
}
void T0_times() interrupt 1 	  	  //T0定时器中断函数
{
	TH0=TH0Cout;   			  	  	  //重装初值
	TL0=TL0Cout;
	if(++T0IntCouts1==timeMultiple1)  //判断是否复用定时器
	{	
		T0IntCouts1=0; 		 	  	  //中断次数清零,重新计时
		timeMultiple1Flag=1;		  //复用定时器标志,须在T0_work()中手动清零
	}
	if(++T0IntCouts2==timeMultiple2)  //判断是否复用定时器
	{	
		T0IntCouts1=0;			  	  //这个也要清,防止到达最小公倍数时乱掉
		T0IntCouts2=0; 		 	  	  //中断次数清零,重新计时
		timeMultiple2Flag=1;	  	  //复用定时器标志,须在T0_work()中手动清零
	}
	T0_work();     				  	  //调用工作函数
}
  

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

51单片机学习笔记:定时器产生PWM可调方波,控制led灯亮度 的相关文章

随机推荐

  • 手把手教你研发自己的智能无人机

    1 让智能无人机梦想变成现实 对于大多数极客学员来说 xff0c 自己组装一台无人机 xff0c 可以航拍 xff0c 可以目标跟踪 xff0c 是心中
  • 软件工程复习之软件生命周期

    生命周期 基本概念 xff1a 生命周期 xff1a 1995过程的划分 xff1a 基本过程 xff1a 开发过程包含的活动 xff1a 过程实现包含任务系统需求分析包含任务系统体系结构设计包含任务软件需求分析软件体系结构设计包含任务 支
  • 先验分布与后验分布,认真看看这篇

    此文主要参考 huaxiaozhuan com 编辑 Python与算法社区 公众号 在贝叶斯学派中 xff0c 先验分布 43 数据 xff08 似然 xff09 61 后验分布 例如 xff1a 假设需要识别一大箱苹果中的好苹果 坏苹果
  • 置信度&置信区间,这篇讲解我给100分!

    今天这篇聊聊统计学里面的置信度和置信区间 xff0c 好像没怎写过统计学的东西 xff0c 这篇试着写一写 1 点估计 在讲置信度和置信区间之前先讲讲点估计 xff0c 那什么是点估计呢 xff1f 给你举两个例子你就知道了 现在你想要知道
  • sklearn 实战指南

    0 引言 Sklearn 全称 Scikit Learn 是基于 Python 语言的机器学习工具 它建立在 NumPy SciPy Pandas 和 Matplotlib 之上 xff0c 里面的 API 的设计非常好 xff0c 所有对
  • 绘制频率分布直方图的三种方法,总结的很用心!

    直方图能帮助迅速了解数据的分布形态 xff0c 将观测数据分组 xff0c 并以柱状条表示各分组中观测数据的个数 简单而有效的可视化方法 xff0c 可检测数据是否有问题 xff0c 也可看出数据是否遵从某种已知分布 本次案例通过生成深圳市
  • Python 列表如何转化为二叉树?

    Day46 列表转化为二叉树 已知列表nums xff0c 将其转化为二叉树 举例 xff1a nums 61 3 9 20 None None 15 7 xff0c 转化为二叉树后 节点3的左子节点9 xff0c 右子节点20 xff0c
  • Peter Norvig 给程序员们的一份传世典文:10年编程无师自通

    你好 xff0c 我是zhenguo 这篇文章的作者 xff1a Peter Norvig xff0c 可以说是程序员中最牛叉的人物之一 xff0c 现任谷歌研究总监 xff0c 是誉满全球的人工智能专家 xff0c 著有 Artifici
  • 全球最优秀的14位程序员

    接下来带你一起膜拜大神 xff08 排名不分先后 xff09 1 Linus Torvalds Linus Torvalds 是开源操作系统Linux和Git之父 1997 2003年 xff0c Torvalds在硅谷Transmeta
  • 《数据分析咖哥十话》包邮送3本

    文末留言包邮送三本 小雪求职记 入秋以来 xff0c 市场就开始不景气 xff0c 我们的女主人公小雪从一家互联网公司的运营岗毕 xff08 cai xff09 业 xff08 yuan xff09 以来 xff0c 三个月都没接到任何面试
  • 梳理机器学习常用算法(含深度学习)

    你好 xff0c 我是你们的老朋友 xff0c zhenguo xff01 机器学习的任务主要分为三类 xff1a 监督学习非监督学习强化学习 监督学习是指在训练过程中 xff0c 模型是根据给定的输入和输出标签来学习的 监督学习的任务主要
  • 机器学习:单或双变量常用分析技巧

    你好 xff0c 我是你们的老朋友 xff0c zhenguo xff01 在机器学习EDA阶段 xff0c 变量分析及可视化是常做的事情 xff0c 这篇文章总结变量分析中 xff0c 最常使用的单变量 xff0c 双变量分析以及可视化
  • 【计算机三级网络技术】 第三篇 IP地址规划技术

    文章目录 一 IP 地址规划以及划分地址新技术1 IP地址的标准分类 xff08 第一阶段 xff09 2 划分子网的三级地址结构 第二阶段 3 构成超网的无类域间路由技术 第三阶段 4 网络地址转换技术 第四阶段 二 IP 地址分类1 A
  • 机器学习:处理缺失值方法总结

    你好 xff0c 我是你们的老朋友 xff0c zhenguo 处理缺失值是在进行机器学习时非常重要的一个步骤 缺失值会影响机器学习模型的准确度 xff0c 因此在训练模型之前 xff0c 通常需要先处理掉缺失值 这篇文章 xff0c 总结
  • 机器学习储备(8):numpy之linspace 和 logspace

    1 linspace在numpy中是创建等差数列 xff0c 先看例子 xff1a A 61 np linspace 1 11 11 结果 xff1a array 1 2 3 4 5 6 7 8 9 10 11 因此可以看到lisapce接
  • 矩阵特征值的求解例子

    请点击上面公众号 xff0c 免费订阅 实例 阐述算法 xff0c 通俗易懂 xff0c 助您对算法的理解达到一个新高度 包含但不限于 xff1a 经典算法 xff0c 机器学习 xff0c 深度学习 xff0c LeetCode 题解 x
  • 51单片机学习笔记:串口接收和发送数据

    芯片STC89C52RC 在PC端向单片机发送任意数据后 单片机向PC端发送4行文本 由于在windos下 回车换行用 r n include lt reg52 h gt include 34 MY51 h 34 void initSer
  • 51单片机学习笔记:利用ADC0804模数转换器采集电压

    电位器调节待检测电压值 在数码管上显示出来 代码大多从书上搬过来的 书上例5 3 1要求前3个数码管显示AD转换后的8位数字量 即0 255 我这里让前4个数码管显示具体电压值 比如1 352 include lt reg52 h gt i
  • 51单片机学习笔记,模拟iic总线连续读写24c02存储器

    AT24C02A 2K SERIAL EEPROM Internally organized with 32 pages of 8 bytes each the 2K requires an 8 bit data word address
  • 51单片机学习笔记:定时器产生PWM可调方波,控制led灯亮度

    使用定时器T0产生PWM方波 用按键调整占空比 20级可调 控制led灯的亮度等级 include 34 my51 h 34 include 34 timer0 h 34 define grading 20 亮度20级变化 sbit key