21058|17

160

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

利用定时器控制蜂鸣器的频率 [复制链接]

题目要求: 同时用两个定时器控制蜂鸣器发声,定时器0控制频率,定时器1控制同个频率持续的时间,间隔300毫秒,依次输出1,10,50,100,200,400,800,1K (HZ)的方波。

本人编写的程序如下:

#include
#define uint unsigned int
#define uchar unsigned char
sbit beem=P2^3;                                        // 控制蜂鸣器的IO是P23
uchar count,count01;                        // 定时器0和定时器1的内部加1变量
void main ()
{
        TMOD=0x11;                                        // T0和T1 的工作方式为方式1
        TH1=(65536-46082)/256;                // 装入初值 50ms
        TL1=(65535-46082)%256;
        EA=1;                                                // 开总中断
        ET1=1;                                                // 开T1 中断
        TR1=1;                                                // 启动T1中断

        TH0=(65536-46082)/256;                /* 同上 此时启动T0中断 */
        TL0=(65535-46082)%256;
        EA=1;
        ET0=1;
        TR0=1;         
       
       
        while (1)                                        // 大循环

        {
                if (count==6)                        //T1 6*50毫秒之后开始执行下面程序,起到延时的作用
                        {
                                count=0;
                                if (count01==2)                //T0 控制蜂鸣器的频率,晶振频率为11.0592MHZ,蜂鸣器频率为800HZ
                                        {
                                                count01=0;
                                                beem=~beem;
                                        }
                        }
                else
                        beem=1;

        }

}

void timer1 () interrupt 3
{
        TH1=(65536-46082)/256;
        TL1=(65535-46082)%256;
        count++;
       

}

void timer0 () interrupt 1
{
        TH0=(65536-230)/256;
        TL0=(65535-230)%256;
        count01++;
}  


问题:

主程序T0控制蜂鸣器频率部分,貌似出了问题,但是楼主思考纠结了半天,找不到突破口,希望高人指点指点。
此帖出自51单片机论坛

最新回复

while(1)这个循环有问题题吧,个人拙见,  详情 回复 发表于 2017-7-25 17:04
点赞 关注
 

回复
举报

4008

帖子

0

TA的资源

版主

推荐
 
300毫秒怎么出1HZ?
此帖出自51单片机论坛

点评

好问题,把300ms 延长到10s如何?  详情 回复 发表于 2014-4-15 14:21
 
 
 

回复

3404

帖子

6

TA的资源

裸片初长成(初级)

沙发
 
没有时间帮你看程序了,建议用potues和keil联调进行仿真,这样会比较方便找找问题。
给个建议,把控制蜂鸣器直接放到定时器0中。如果在大循环中出现count01==2这样的语句,有可能把count01==2这个条件丢了,改成>=2的形式,或者多加个>2时的条件判断并进行处理可能会好一些。
此帖出自51单片机论坛

点评

谢谢版主的回答,根据你的提示我回头又看了下程序,把蜂鸣器放在了T0里,主程序的思路如下你觉得这样可行吗? void mian () { 开T1中断; 开T0中断; while (1); } 然后T1的中断控  详情 回复 发表于 2014-4-14 20:13
 
 
 

回复

160

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
jishuaihu 发表于 2014-4-14 11:00
没有时间帮你看程序了,建议用potues和keil联调进行仿真,这样会比较方便找找问题。
给个建议,把控制蜂鸣 ...

谢谢版主的回答,根据你的提示我回头又看了下程序,把蜂鸣器放在了T0里,主程序的思路如下你觉得这样可行吗?

void mian ()
{
       开T1中断;
       开T0中断;
       while (1);
}

然后T1的中断控制为300ms, 而T0中断程序中来控制蜂鸣器的频率,
这样可行吗?如果不可行的话,问题出在了哪里?此时while (1);去掉可以吗?
此帖出自51单片机论坛
 
 
 

回复
维尔港 该用户已被删除
5
 
提示: 作者被禁止或删除 内容自动屏蔽
 
 
 

回复

160

帖子

0

TA的资源

一粒金砂(中级)

6
 
huo_hu 发表于 2014-4-14 23:43
300毫秒怎么出1HZ?

好问题,把300ms 延长到10s如何?
此帖出自51单片机论坛
 
 
 

回复

160

帖子

0

TA的资源

一粒金砂(中级)

7
 
谢谢各位的帮忙,昨天又研究了半天,终于开始开窍了,思路豁然开朗,Timer01其实就是一个延时程序,在timer01中断程序中需要注意的是要关闭timer0 的中断,然后改变频率,再开timer0的中断。早之前我没有timer01控制timer0中断的这个概念,所以写的程序出了问题,今天我终于写出了这个程序,感觉其实就是关键思路卡在了这里。

原题目做一些修改:


题目要求: 同时用两个定时器控制蜂鸣器发声,Timer0 控制频率,Timer01 控制同个频率持续的时间,间隔5秒,依次循环输出25,50,100,200,400,800(HZ)的方波。

分析程序:
频率是等比数列,编程序时候可以用"frequency*=2",再赋值给Timer0中断程序中控制频率的变量,用Timer01控制每次蜂鸣器延时的时间,并且每次改变一次“frequency”变量。

Timer01 的中断程序如下:

void timer1 () interrupt 3
{
        TH1=(65536-46082)/256;
        TL1=(65535-46082)%256;
        count++;

        if (count==100)
        {
           count=0;
                   TR0=0;
                   beem=1;
                  TH0=(65536-230)/256;
                  TL0=(65535-230)%256;                       
                   count01=0;
                   frequency*=2;
                   if (frequency==32)
                           frequency=1;
                   TR0=1;
                }
}


Timer0  的中断程序如下:

void timer0 () interrupt 1
{
        TH0=(65536-625)/256;
        TL0=(65535-625)%256;
        count01++;
        if (count01==frequency)
                {
                               count01=0;
                         beem=~beem;
                }

}


主程序初始化各个变量,开启 timer0 和 timer01 ,然后大循环:

void main ()
{
            frequency=1;  
        TMOD=0x11;                                // T0和T1 的工作方式为方式1
        TH1=(65536-46082)/256;              // 装入初值 50ms
        TL1=(65535-46082)%256;
        EA=1;                               // 开总中断
        ET1=1;                              // 开T1 中断
        TR1=1;                              // 启动T1中断

        TH0=(65536-230)/256;       /* 同上 此时启动T0中断 */
        TL0=(65535-230)%256;
        EA=1;
        ET0=1;
        TR0=1;


        while (1)                            // 大循环

        {

        }

}
此帖出自51单片机论坛
 
 
 

回复

160

帖子

0

TA的资源

一粒金砂(中级)

8
 
本帖最后由 五加一等于六 于 2014-4-17 19:07 编辑

还有一个问题跟大家讨论一下, Timer01 控制蜂鸣器同频率发声延续的时间,每次进入timer01中断程序都会计时 50ms而 每次进入timer01中断程序之后也要进入一次timer0的中断程序,timer0时间计时为625μs, timer01控制的延时实际为 100×(50ms + 625μs)= 5.0625s,  真实情况是否如此?
此帖出自51单片机论坛
 
 
 

回复

4008

帖子

0

TA的资源

版主

9
 
1个定时器就可以搞定了
此帖出自51单片机论坛

点评

后来我想了想, 一个定时器就搞定了,斑竹我的疑问是如果timer0和timer1 两个同时用的时候,是否是先后进入,timer1计时一次timer0也计时一次?那么用timer1计时的时间是有误差的,误差就是timer0的计时时间?  详情 回复 发表于 2014-4-18 21:40
 
 
 

回复

160

帖子

0

TA的资源

一粒金砂(中级)

10
 
huo_hu 发表于 2014-4-17 21:30
1个定时器就可以搞定了

后来我想了想, 一个定时器就搞定了,斑竹我的疑问是如果timer0和timer1 两个同时用的时候,是否是先后进入,timer1计时一次timer0也计时一次?那么用timer1计时的时间是有误差的,误差就是timer0的计时时间?
此帖出自51单片机论坛

点评

你说的是两个定时器同步的问题,两个定时器不能同时启动所以没法完整的同步. 另外软件重装方式时每中断定时会有偏差,所以尽量用硬件重装. 不过你的程序时间要求没有那么严格,把逻辑附加到时间计数上.  详情 回复 发表于 2014-4-20 10:30
 
 
 

回复

4008

帖子

0

TA的资源

版主

11
 
五加一等于六 发表于 2014-4-18 21:40
后来我想了想, 一个定时器就搞定了,斑竹我的疑问是如果timer0和timer1 两个同时用的时候,是否是先后进 ...


你说的是两个定时器同步的问题,两个定时器不能同时启动所以没法完整的同步.
另外软件重装方式时每中断定时会有偏差,所以尽量用硬件重装.
不过你的程序时间要求没有那么严格,把逻辑附加到时间计数上.
此帖出自51单片机论坛

点评

哦,看来我这位初学者,研究的问题越来越深入了,谢谢版主回复。  详情 回复 发表于 2014-4-20 13:10
 
 
 

回复

160

帖子

0

TA的资源

一粒金砂(中级)

12
 
huo_hu 发表于 2014-4-20 10:30
你说的是两个定时器同步的问题,两个定时器不能同时启动所以没法完整的同步.
另外软件重装方式时每中断 ...

哦,看来我这位初学者,研究的问题越来越深入了,谢谢版主回复。
此帖出自51单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

13
 
您好我也是初学者,我对你的程序有点疑问。
frequency被定义为频率,频率越高,高低电平改变也就越频繁,可是根据你的程序
void timer0 () interrupt 1
{
        TH0=(65536-625)/256;
        TL0=(65535-625)%256;
        count01++;
        if (count01==frequency)
                {
                               count01=0;
                         beem=~beem;
                }

}
当frequent越大时,意味着count01所需要的值越大,也就意味着进行if内部程序越不容易,也就意味着高低电平改变越不频繁,这是否就与frequent本身所定义得矛盾了?
此帖出自51单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

14
 
您应该是看郭天祥的视频,我跟你用的是同一套教学资源。
按照原题我也编了一个程序,不知是否可以.....(根据原题,即忽视了300ms无法出1hz的这个问题,假设晶振是12Mhz)
#include
#define uint unsight int
#define uchar unsight char
sbit beep=P2^3;//假设蜂鸣器是P2^3口
uint t=1;
void main()
{
        TMOD=ox11;//将定时器0和1工作方式都设置为方式1

        TH1=(65536-30000)/256;
        TL1=(65536-30000)%256;

        TH0=(65536-100)/256;
        TL0=(65536-100)%256;

        EA=1;
        ET1=1;
        ET0=1;

        beep=1;//蜂鸣器响
        TR1==0;
        TR0==0;//开始计时
        while(1)
        {
                while(t%8==1)
                {
                        if(m==500)//频率为1hz,其实根本等不到取反,t就已经进1了
                        {
                                m=0;
                                beep=~beep;
                        }
                }
                while(t%8==2)
                {
                        if(m==50)//频率为10hz
                        {
                                m=0;
                                beep=~beep;
                        }
                }//中途舍去其他几种频率,本质相同
                while(t%8==0)
                {
                        if(m==1)//频率为1Khz
                        {
                                m=0;
                                beep=~beep;
                        }
                }
        }
}
void time0() interrput 1//控制频率,单次为0.001s
{
        TH0=(65536-100)/256;
        TL0=(65536-100)%256;
        m++;
}
void time1() interrput 3//控制持续的时间,单次时间为0.3s
{
        TH1=(65536-30000)/256;
        TL1=(65536-30000)%256;
        t++;
        m=0;
}
此帖出自51单片机论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

15
 
此帖出自51单片机论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

16
 
fffqqs 发表于 2015-8-8 23:32
您应该是看郭天祥的视频,我跟你用的是同一套教学资源。
按照原题我也编了一个程序,不知是否可以.....( ...

我也是在用郭的教学资源  不过我想问一下那个频率怎么产生啊
此帖出自51单片机论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

17
 
fffqqs 发表于 2015-8-8 23:32
您应该是看郭天祥的视频,我跟你用的是同一套教学资源。
按照原题我也编了一个程序,不知是否可以.....( ...

你的程序错的一塌糊涂 !
此帖出自51单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

18
 
while(1)这个循环有问题题吧,个人拙见,
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表