历史上的今天
今天是:2025年01月26日(星期日)
2019年01月26日 | 51单片机使用定时器中断模拟PWM控制端口电压
2019-01-26 来源:eefocus
最近应实验室需求写一篇51单片机产生PWM的文章供参考.
单片机芯片STC89C52,晶振12MHz,编译环境Keil5.
分析:若使单片机端口为高电平, 则单片机输出电压为恒值5V. 反之低电平输出电压为0V. 但是我们如果在周期为T的时间内使单片机高电平出现t1秒, 低电平出现t2秒, 那么在周期内, 高电平出现的时间为
, 低电平时间为
. 由于周期T的时间极短, 那么在连续的时间t内, 相应端口输出电压为
.
实验使用定时器0, 定时器0由两个寄存器进行控制,分别为定时器/计数器工作方式寄存器TMOD, 定时器/计数器控制寄存器TCON.
TMOD是一个八位寄存器,如下:

TMOD寄存器高4位控制定时器1低四位控制定时器0:
1. GATE位为门控制位, 选择是否让外部中断控制定时器,此位一般置0, 即不让外部中断控制定时器.
2. C/T位为选择定时器/计数器模式选择, 此实验中使用定时器模拟时间周期T, 所以置0选择定时器模式.
3. M1和M0为定时器工作方式选择位, 控制方式如下:

一般在周期短,要求定时精度高的情况下选择方式2,但此实验选择方式1的16位计数器.
16位计数器的意思是周期T的长度不超过机器周期的
倍,在12MHz晶振的作用下,机器周期为1us,故周期T不超过65536us.
TCON控制寄存器寄存器的高4位用于控制定时/计数器的启动和中断申请, 低4位用于控制外部中断(此处不介绍).

TF1:定时器1溢出中断请求标志位。定时器1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。定时器1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
TR1:定时器1运行控制位。TR1置1时,定时器1开始工作;TR1置0时,定时器1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
TF0:定时器0溢出中断请求标志位,其功能与TF1类同。
TR0:定时器0运行控制位,其功能与TR1类同。
定时器工作方式: (以工作方式1为模板)
方式1为16位计数,由定时器的低8位 和 定时器的高8位组成。定时器的低8位溢出时向定时器的高8位进位+1,定时器的高8位溢出时,置位TCON中的TF0标志,然后定时器高8为与低8位请零, 并向CPU发出中断请求.
TL0->TH0->TF0->产生中断(TL0/TH0/TF0清零)
下面介绍个定时器0实现PWM控制LED亮度的代码:
利用定时器0产生周期为100*100us, 低电平持续时间为100*20us的方波.
方波如下:

因为这里我们是产生周期为10ms(100Hz)的PWM,所以可设置中断的时间基准为100us, 中断100次即为10ms. 并在中断里设置时间变量为n.
1、当n>20时(0< n 2、当20 3、当n=100时,表明周期T已满,n清零; 下面程序产生20%占空比的pwm: #include #define T 100 //定义时间进度为100个机器周期,即100us sbit LED=P1^0; unsigned int pwm_num=20; //PWM中低电平出现的时间t2 void main() { TMOD = 0x01; //选择为定时器0 工作方式1 TH0=(65536-T)/256; //定时器高八位 TL0=(65536-T)%256; //定时器低八位 TR0=1; //开启定时器 ET0=1; //开启定时器1的中断使能 EA=1; //开启总中断 while (1); //等待中断发生 } void Timer1() interrupt 1 //中断1(定时器0专用中断通道) { static unsigned char n; //静态变量n 可以看成每100us加一次的时间t TH0=(65536-T)/256; //重装定时器的值 TL0=(65536-T)%256; n++; //表明周期T已到100*100us if (n==100) n=0; LED = (n<=pwm_num) ? 0 : 1; //判断时间是否超过t2 } 最终实验现象为:LED灯亮度变低.
上一篇:51DIY音乐频谱显示
下一篇:8051指令集和汇编语言程序设计
史海拾趣
|
使用mc52i,每隔半小时通过向服务器传送一个UDP数据包,同时服务器也向mc52i发送短信,但是使用AT+CMGR指令,经常读取不到短信。 有没有做过类似工作的朋友帮帮忙,已经调试了几天了,问题依然存在… 查看全部问答> |
|
第一次做GPRS数据传输,用的是华为的GTM900B。希望各位能给个AT指令建立连接,传输数据的例子。 邮箱:amarantine33520@163.com 不胜感激!!!!!!!… 查看全部问答> |
|
刚接触wince,我的板子是用cf卡启动的,nk.bin,eboot.bin都可以生成,用eboot启动,用这句启动Loadcepc /v/e:0:11:10.1.12.155 eboot.bin,这个ip和我主机是在一个子网通过路由器连接的 ,启动后目标机会出现\"jumping xxxxx\",网上说这时pb但是target->c ...… 查看全部问答> |
|
希望在北京,对下面要做的有经验比较精通。可以合作,也可以外包。 要求为下面的应用选择合适的开发板和器件,ARM内核,linux系统,以太网支持有线和无线,红外和遥控器双向传输。 linux系统上有httpd(通过浏览器对设备进行设置)/dhcpcd(当有 ...… 查看全部问答> |
|
我用evc4.0写的应用程序编译通过了,为什么在pocketpc2003模拟器上找不到该文件呢? 我设置的是emulator startup server,程序会自动打开pocketpc2003模拟器但是就是不自动运行程序,我是新手,还不太懂,希望指点指点一下。 转自Tony嵌入式 http ...… 查看全部问答> |
|
想找一个低功耗单片机, 要求: 一块700MAh的一次性电池 能连续工作5年(4万小时) 单片机只用来显示时间。 请问高手,有没有这样一款单片机或FPGA 谢谢… 查看全部问答> |
|
/** ****************************************************************************** * @file USART/Printf/main.c * @author MCD Application Team * @version V3.5 ...… 查看全部问答> |
|
只有一个定时器的430,能否输出PWM的同时还能定时中断干其他活? 只有一个定时器的430,能否输出PWM的同时还能定时中断干其他活? 比如系统输出30K的PWM波形,同时还能有0.5秒的定时中断去执行其它任务。 大大能否贴个简单的代码指导一下啊?… 查看全部问答> |
|
英特尔Edison大赛初赛30强项目,看看有没有和你类似的创意 Intel在2014年推出了Edison模块,在2015年又为Edison模块举办了一个英特尔硬享公社Edison大赛,希望能够在移到端的应用找到一些突破。据说现在Intel每年卖出的各种CPU芯片,平均下来的价格是100多美元。这对于高端应用可能不是问题,但是在移到端这 ...… 查看全部问答> |




