stc89c52如何使用第三个定时器及c语言interruptt5

stc89c52rc单片机的第三个定时器怎么设置啊?麻烦把启动和中断格式程序写一下,在线等。。。。知道的帮帮_百度知道
stc89c52rc单片机的第三个定时器怎么设置啊?麻烦把启动和中断格式程序写一下,在线等。。。。知道的帮帮
急急急。。。知道的帮帮忙
提问者采纳
/配置定时器2控制寄存器;/,开外定时器2中断;&#47!;启动定时器2
void timer2() interrupt 5
&#47,这里其实不用配置;
&#47,T2MOD上电默认就是0!!,这里其实不用配置;//
&#47:EA=1,可按位操作,硬件不能清零;/
//初始化主函数
void init_main()
/24MHz晶振下定时25
TR2=1,这里赋值只是为了演示这个寄存器的配置
IE=0xA0,T2CON上电默认就是0;配置定时器2工作模式寄存器,这里赋值只是为了演示这个寄存器的配置
T2MOD=0,这里与定时器0和定时器1不同;
/ RCAP2H=(0xFFFF-50000)&#47!;/
&#47,自动重装
TH2=RCAP2H;/&#47/定时器2赋初值
T2CON=0;/ RCAP2L=(0xFFFF-510 0000开总中断; ET2=1! 定时器2必须由软件对溢出标志位清零!注意!!
TL2=RCAP2L
那我是12mhz的晶振,定0.5ms的时间可以吗?还有就是这个TF2是必须有的吧
提问者评价
其他类似问题
为您推荐:
stc89c52rc的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁trackbacks-0
尽量用最少的文字描述清楚问题。
事情起因是这样的:
  要做遥控小车的平台迁移,STM32开发板无法方便地供电,因此又拿出了尘封的51(STC89C52RC),搭配上最小系统板就可以用排针加杜邦线供电了。
测试的时候出了点问题,51开发板上用作显示的数码管会闪动,而在逻辑正确的情况下是不会出现这个情况的(后来发现数码管的位选段选信号有点小问题)。在排查过程中,一步一步找到了中断处理程序。
51一共有5个中断源,其中有2个定时器中断T0 T1,2个外部中断,1个串口中断。52比51多一个定时器中断T2。
定时器有4种工作模式,T0和T1的M1M0均为01的时候,也即TMOD为0x11时,是工作模式1,为16位定时器。不自动重装初值,需要手动重装初值。
初学51的入门书是郭天祥老师的&新概念51单片机C语言教程&,在第3章第5节讲述定时器中断的时候,为了讲述方便和容易理解,中断服务程序中是这样写的:
void T0_time() interrupt 1
TH0 = (65536-45872)/256;
TL0 = (65536-45872)%256;
这是在11.0592MHz晶振下50ms来一次中断的重装初值的方法。关于这个的解释是这样的。
在晶振为12M的时候,由于机器周期是12个时钟周期,机器周期为(1/12M)*12 = 1 (us)
也就是计一个数需要 1us
50ms需要 计50000个数
所要装入的总数是 65536-50000=15536
所要装入的初值是
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
在晶振为11.0592M的时候,机器周期为(1/11.0592M)*12 = 1 x 12 /11.0592 =1.085 (us)
100us,需要计 100/1.085 = 92.16个数,取整 92
所要装入的总数是 65536-92
所要装入的初值是
TH0=(65536-92)/256;
TL0=(65536-92)%256;
  其实我想说的是,虽然这样可能比较容易看懂(配合注释),但是就把这个表达式放在这儿而不把结果计算出来,会使效率大打折扣!
  其实在50ms下还好,因为总时间比较长,每次计算()/256的时间虽然是固定的,但是百分比较小,相对影响较小。
  当设定中断为100us来一次的时候,会使得计算表达式的时间所占百分比大大提升。由于100us = 0.1ms = 50ms / 500,也就是说,假设536-45872的时间消耗同一个数量级的(100us的时候中断服务程序中重装的初值45872变成了92),计算
的时间消耗百分比提升了500倍左右。
举个栗子:
void T0_time() interrupt 1 {
TH0 = (65536-45872)/256;
TL0 = (65536-45872)%256;
void T0_time() interrupt 1 {
TH0 = (65536-92)/256;
TL0 = (65536-92)%256;
TH0 = ()/256;
TL0 = ()%256;
都需要1us的时间。
在总时间为50ms时,前者所占百分比为 1/50k = 0.002%
在总时间为100us时,后者所占百分比为 1/100 = 1.000%
尼玛差了500倍左右!能想象吗?
别看绝对数字,因为这1us是我编出来的,实际上51属于低速芯片,而且还有其他事要做。事实上上中断里面除了重装初值还要做其他事情,却让这么一个简单的但没有化简的重装初值的表达式给占用了太多资源和时间。。
我好像说了好多废话,那我就直接说结论吧:就只是把结果计算出来,也就是把
TH0 = 255;
TL0 = 164;
其他啥都不改,然后把程序下载到芯片上,数码管的变化已经可以由人眼分辨我会乱说?
有的效率提升其实很简单。
PS1:我感觉51真的很慢。。或者应该说资源有限,需要尽量优化,或者不要轻易使用很小的定时器&&&&&它忙不过来。
举个例子吧,还是刚才那个项目:
void T0_IRQHandler() interrupt 1
TH0=(65536-52)/256;
TL0=(65536-52)%256;
pwmOutput();
也就是52 x 1.085 = 56.42 (us)来一次中断
当中断程序中不做其他事情,也就是没有pwmOutput()这个函数时,当然是能运行的。
而加入一个这样的pwmOutput()之后:
void pwmOutput(){
/* left side */
if(directionLeft == 1){
PWM_IN1_ON();
PWM_IN2_OFF();
else if(directionLeft == 2){
PWM_IN2_ON();
PWM_IN1_OFF();
else if(directionLeft == 0){
PWM_IN1_OFF();
PWM_IN2_OFF();
/*right side*/
if(directionRight == 1){
PWM_IN3_ON();
PWM_IN4_OFF();
//else if(directionRight == 2){
//backward
PWM_IN4_ON();
PWM_IN3_OFF();
}else if(directionRight == 0){
PWM_IN3_OFF();
PWM_IN4_OFF();
我注释掉了一部分。剩下的就很接近它的极限了。也就是说这样是能运行的,如果去掉/*left side*/的第二个else if,那么,pwmOutput()的运行时间将超过56.42 us,还没等这个函数运行完,下一次中断又来了。。也就是卡在这里出不去了0.0
void PWM_IN1_ON(){
PWM_Ch1 = ~PWM_Ch1;
void PWM_IN1_OFF(){
PWM_Ch1 = 0;
//直接把PWM_Ch1写上去会稍微强一点,因为不用跳转了
好像。。不对,上面的分析好像错了。。。(PS1是对的),因为是设定完初值之后定时器才开始工作的,所以放表达式好像和之前所说的效率无关了。。因为反正计算的这段时间它是停着的,只有等到计算好了之后才会生效。这样来说,
的差别只在于计时的准确性上,比如前者一个计时周期是1us + 0.01us,后者一个计时周期是1us + 0.001us
积累多了会有一点准确性上的误差,在不要求那么那么精准的地方还是推荐用表意更好的方式,demo方便阅读。如果是封装好了的那就另说了,因为毕竟每次都要重新计算确实有点浪费,封装好了就默认能看懂里面的,所以可以采用省时间省资源的方式。
但是刚才我分明是看到了修改之后有变化的。。绝对没有自行脑补。。
阅读(...) 评论()基于STC89C52定时器设计_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
基于STC89C52定时器设计
上传于||暂无简介
阅读已结束,如果下载本文需要使用2下载券
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩12页未读,继续阅读
你可能喜欢stc89c52很多有用程序_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
stc89c52很多有用程序
上传于||暂无简介
大小:18.63KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢STC89C52RC单片机温控直流电机。数码管总是闪,感觉应该是定时器的原因_百度知道
STC89C52RC单片机温控直流电机。数码管总是闪,感觉应该是定时器的原因
flag=1;&8;
dat=dat& delayus(20);
ds=1; ET0=1改了很多遍,b;10]。#include &
if(read_temperature()&gt,0x99; delayus(10); if(num& num=0;=pwm) {
P2=0void delay(uchar x){
_nop_();200) {
delay(50).h& P0=table_du[temp%100%10];
k=(j&32) {
} } if(read_temperature()&
num++;#define uchar unsigned char#define uint unsigned intbit flag,0x80;uchar code table_du[]={0xc0; TL0=()%256; b=ds_read_byte(); }uchar ds_read_byte(){ 256,0x12;100]; } if(num& ds=1; temp=temp*0; ds_reset(),要么数码管好了; P1=0xf7; ds=1; dat= delayus(14); }
pwm--; ds_write_byte(0xcc),0x00; delay(20);}uint read_temperature(){ uchar a,0x79;
if(read_temperature()&i++) {
ds=0,0x82;}void display(uint temp){ P0=table_du[temp/ _nop_();i++) {
j=ds_read_bit();b& | }
TH0=()&#47,k; for(a=x;200)
if(pwm&gt.; P1=0sbit ds=P3^5;reg52;a--)
for(b=200; delay(20); temp=temp&1;7)|(k&i&& delayus(5); temp=b;0;
void init_t0(){ TMOD=0x01, ds_write_byte(0xbe); for(i=0;}void ds_write_byte(uchar dat){ uchar i,电机就不能自动调速; ds=0;/ TH0=()/ }
P2=0x00;8; } delayus(6); for(i=0;256;
delay(100),0x10};
delay(100); TL0=()%256;=200)
if(pwm& ds=0.5,0x24;}void delayus(uint t){ while(t--);1),0x78;
pwm=1;a&gt,要么能自动调速;
while(1) { ds_reset(); temp=temp|a;
}void main(){
init_t0(),小弟初学者,0xf8; display(read_temperature()) ,0xb0; ds_write_byte(0x44);=200) {
delay(50);void tiaosu(uint temp),数码管就乱闪;P0=table1[temp%100/8; _nop_();}void t0() interrupt 1{ TR0=0,},j; delayus(80);/i&&gt,b;uchar code table1[]={0x40,0x02;&
TR0=1; EA=1,0xa4,0xf9;}void tiaosu (){ if(read_temperature()&gt。哪位大神帮我把这个程序改改;0,0x90;
ds=dat&0x01;32)
pwm++; a=ds_read_byte(); else
flag=0,0x30.h&
tiaosu (); ds_write_byte(0xcc),0x92;
delayus(6);#include &b--);}bit ds_read_bit(){
delay(20),0x19; P1=0
_nop_();}void ds_reset(){ ds=1
我有更好的答案
16的D / A转换器和DC功率和扭矩结合的控制算法模糊PID稳速控制系统构成的直流扭矩马达基于模糊PID的直流力矩电机速度控制,所述沉降时间是小于标准PID控制调节时间,80196KC微控制器。使用编码器。基于根据基于所述误差信号的二维模糊PID控制算法的设计模糊控制和PID控制相结合的方法进行分析 达到阈值来确定何时模糊控制和PID之间切换控制,稳态误差小于4 10千分之一。通过标准的PID和模糊PID分析和测得的数据的比较表明,模糊PID控制可以在没有过冲输出来实现
看清楚在回答好嘛?
其他类似问题
为您推荐:
直流电机的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 c语言interrupt 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信