找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2529|回复: 9
打印 上一主题 下一主题
收起左侧

c51单片机利用定时器0产生38khz方波的问题

[复制链接]
跳转到指定楼层
楼主
ID:879924 发表于 2021-11-5 03:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. void khz(uchar aa)
  2. {
  3.     for(a=aa;a>0;a--)       //这个for语句可以得到准确的26.3波特率
  4.     {
  5.         out=0;
  6.         i=7;            
  7.         while(i>0) i--;    //38kHZ  
  8.         out=1;            
  9.     }
  10. }
复制代码
调用 khz(116);即可产生38.5khz
但如果改成
  1. void khz()
  2. {
  3.     for(a=116;a>0;a--)   
  4.     {
  5.         out=0;
  6.         i=7;            
  7.         while(i>0) i--;   
  8.         out=1;            
  9.     }
  10. }
复制代码

调用 khz();频率就会变成50khz
请问两组代码为什么会出现这样的差异?另外下面的一段代码是像利用定时器生成38khz方波,环境是stc90c51rc+12mhz时钟,定时器初始化后,这里是13us的溢出中断,取反各一次后是26us,主函数没有任何其他语句,按道理应该是获得38KHZ的方波啊,但是示波器显示是26KHZ,请大神明示~~~

  1. void Timer0_Routine(void) interrupt 1
  2. {
  3.         TL0=0xF3;
  4.         TH0=0xFF;                                                               
  5.         IR_OUT=~IR_OUT;
  6. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2021-11-5 05:48 | 只看该作者
输出高速脉冲用定时器模式2比较合适。
  1. #include<reg52.h>

  2. sbit IR_OUT=P1^0;

  3. void Timer0Init(void)//13微秒@12.000MHz
  4. {
  5.         TMOD= 0x02;                //设置定时器模式
  6.         TL0 = 0xF3;                //设置定时初始值
  7.         TH0 = 0xF3;                //设置定时重载值
  8.         TR0 = 1;
  9.         EA  = 1;
  10.         ET0 = 1;
  11. }

  12. void main()
  13. {
  14.         Timer0Init();
  15.         while(1);
  16. }

  17. void Timer0_Routine(void) interrupt 1
  18. {
  19.         IR_OUT=~IR_OUT;
  20. }
复制代码
回复

使用道具 举报

板凳
ID:198543 发表于 2021-11-5 09:42 | 只看该作者
本帖最后由 nbhmwj 于 2021-11-5 09:56 编辑

1.  38KHZ变成26KHZ的原因是响应中断程序使用SJMP  #ADDRESS指令  需2个机器周期,进入中断程序后,由于TL0=0xF3;  TH0=0xFF; 两条指令需要2*2=4个机器周期,12M晶振,1个机器周期1us,故增加了6us,从而增中了脉冲的周期,故变成了26KHZ。
2.  可以调整程序将IR_OUT=~IR_OUT;移到第一位置,同时将TL0赋值0xF6

; .\T0int.SRC generated from: T0int.c
; COMPILER INVOKED BY:
;        d:\Keil_v4\C51\BIN\C51.EXE T0int.c BROWSE DEBUG OBJECTEXTEND SRC(.\T0int.SRC)

$NOMOD51

NAME        T0INT

P0        DATA        080H
P1        DATA        090H
P2        DATA        0A0H
P3        DATA        0B0H
T0        BIT        0B0H.4
AC        BIT        0D0H.6
T1        BIT        0B0H.5
T2        BIT        090H.0
EA        BIT        0A8H.7
IE        DATA        0A8H
EXF2        BIT        0C8H.6
RD        BIT        0B0H.7
ES        BIT        0A8H.4
IP        DATA        0B8H
RI        BIT        098H.0
INT0        BIT        0B0H.2
CY        BIT        0D0H.7
TI        BIT        098H.1
INT1        BIT        0B0H.3
RCAP2H        DATA        0CBH
PS        BIT        0B8H.4
SP        DATA        081H
T2EX        BIT        090H.1
OV        BIT        0D0H.2
RCAP2L        DATA        0CAH
C_T2        BIT        0C8H.1
WR        BIT        0B0H.6
RCLK        BIT        0C8H.5
TCLK        BIT        0C8H.4
SBUF        DATA        099H
PCON        DATA        087H
SCON        DATA        098H
TMOD        DATA        089H
TCON        DATA        088H
IE0        BIT        088H.1
IE1        BIT        088H.3
B        DATA        0F0H
CP_RL2        BIT        0C8H.0
ACC        DATA        0E0H
ET0        BIT        0A8H.1
ET1        BIT        0A8H.3
TF0        BIT        088H.5
ET2        BIT        0A8H.5
TF1        BIT        088H.7
TF2        BIT        0C8H.7
RB8        BIT        098H.2
TH0        DATA        08CH
EX0        BIT        0A8H.0
IT0        BIT        088H.0
TH1        DATA        08DH
TB8        BIT        098H.3
EX1        BIT        0A8H.2
IT1        BIT        088H.2
TH2        DATA        0CDH
P        BIT        0D0H.0
SM0        BIT        098H.7
TL0        DATA        08AH
SM1        BIT        098H.6
TL1        DATA        08BH
SM2        BIT        098H.5
TL2        DATA        0CCH
PT0        BIT        0B8H.1
PT1        BIT        0B8H.3
RS0        BIT        0D0H.3
PT2        BIT        0B8H.5
TR0        BIT        088H.4
RS1        BIT        0D0H.4
TR1        BIT        088H.6
TR2        BIT        0C8H.2
PX0        BIT        0B8H.0
PX1        BIT        0B8H.2
DPH        DATA        083H
DPL        DATA        082H
EXEN2        BIT        0C8H.3
REN        BIT        098H.4
T2CON        DATA        0C8H
RXD        BIT        0B0H.0
TXD        BIT        0B0H.1
IR_OUT        BIT        090H.0
F0        BIT        0D0H.5
PSW        DATA        0D0H
?PR?Timer0Init?T0INT SEGMENT CODE
?PR?main?T0INT       SEGMENT CODE
?PR?Timer0_Routine?T0INT                 SEGMENT CODE
        EXTRN        CODE (?C_STARTUP)
        PUBLIC        Timer0_Routine
        PUBLIC        main
        PUBLIC        Timer0Init
; #include<reg52.h>
;
; sbit IR_OUT=P1^0;
;
; void Timer0Init(void)//13微秒@12.000MHz

        RSEG  ?PR?Timer0Init?T0INT
Timer0Init:
                        ; SOURCE LINE # 5
; {
                        ; SOURCE LINE # 6
;        // TMOD= 0x02;                //设置定时器模式
;         TL0 = 0xF3;                //设置定时初始值
                        ; SOURCE LINE # 8
        MOV          TL0,#0F3H
;         TH0 = 0xFF;                //设置定时重载值
                        ; SOURCE LINE # 9
        MOV          TH0,#0FFH
;         TR0 = 1;
                        ; SOURCE LINE # 10
        SETB         TR0
;         EA  = 1;
                        ; SOURCE LINE # 11
        SETB         EA
;         ET0 = 1;
                        ; SOURCE LINE # 12
        SETB         ET0
; }
                        ; SOURCE LINE # 13
        RET         
; END OF Timer0Init

;
; void main()

        RSEG  ?PR?main?T0INT
main:
                        ; SOURCE LINE # 15
; {
                        ; SOURCE LINE # 16
;         Timer0Init();
                        ; SOURCE LINE # 17
        LCALL        Timer0Init
?C0002:
;         while(1);
                        ; SOURCE LINE # 18
        SJMP         ?C0002
; END OF main

CSEG        AT        0000BH
        LJMP        Timer0_Routine

; }
;
; void Timer0_Routine(void) interrupt 1

        RSEG  ?PR?Timer0_Routine?T0INT
        USING        0
Timer0_Routine:
                        ; SOURCE LINE # 21
; {
;         TL0=0xF3;
                        ; SOURCE LINE # 23
        MOV          TL0,#0F3H
;         TH0=0xFF;                                                               
                        ; SOURCE LINE # 24
        MOV          TH0,#0FFH
;         IR_OUT=~IR_OUT;
                        ; SOURCE LINE # 25
        CPL          IR_OUT
;                
; }                                                                ; SOURCE LINE # 27
        RETI        
; END OF Timer0_Routine

        END


回复

使用道具 举报

地板
ID:198543 发表于 2021-11-5 09:54 | 只看该作者
本帖最后由 nbhmwj 于 2021-11-5 11:02 编辑

上一层楼已编缉修改完成。
回复

使用道具 举报

5#
ID:879924 发表于 2021-11-5 11:05 来自手机 | 只看该作者
wulin 发表于 2021-11-5 05:48
输出高速脉冲用定时器模式2比较合适。

您好,换了模式2 还是那样
回复

使用道具 举报

6#
ID:879924 发表于 2021-11-5 11:13 来自手机 | 只看该作者
nbhmwj 发表于 2021-11-5 09:42
1.  38KHZ变成26KHZ的原因是响应中断程序使用SJMP  #ADDRESS指令  需2个机器周期,进入中断程序后,由于TL0 ...

感谢您给了专业的解释。汇编不是很懂。 后来我换成自动重装模式2,中断里只有IR_OUT=~IT_OUT 还是26khz。而且如果我改成F6,就会变成55.5khz。简直要崩溃了。对了我的晶振显示11.965mhz不是12mhz应该没问题吧? 新手一枚,还请大神赐教
回复

使用道具 举报

7#
ID:624769 发表于 2021-11-5 13:58 | 只看该作者
macboa 发表于 2021-11-5 11:13
感谢您给了专业的解释。汇编不是很懂。 后来我换成自动重装模式2,中断里只有IR_OUT=~IT_OUT 还是26khz ...

单片机型号? 如果软件延时,单片机的型号,直接影响,延时的时间。

按你代码带来的结果,初步判断你是 STC 15系列单片机,

所以, void khz(uchar aa) 的话,编译以后 是: DJNZ R7  计数, 步进为4
void khz() 的话,编译以后 是: DJNZ D8  计数, 步进为5,  两者比例关系差不多就是  4:5     基本吻合 38Khz :  50Khz

最后,除非你会玩汇编,不然要精确计时的话,还是老老实实用定时器吧。
回复

使用道具 举报

8#
ID:879924 发表于 2021-11-5 15:33 来自手机 | 只看该作者
188610329 发表于 2021-11-5 13:58
单片机型号? 如果软件延时,单片机的型号,直接影响,延时的时间。

按你代码带来的结果,初步判断你 ...

我是用的st90c51rc 然后晶振是11.0592mhz。快愁死我了
回复

使用道具 举报

9#
ID:879924 发表于 2021-11-5 15:40 | 只看该作者
感觉51hei真好 很活跃。csdn问个问题好久都没人回。
回复

使用道具 举报

10#
ID:624769 发表于 2021-11-5 15:57 | 只看该作者
STC90C51RC  有T2定时器, 可以直接方波输出,你试试那个吧。

另外,如果你开了 6T 模式, 11.0592 的晶振是会翻倍成: 22.1184 的。按你说的各种线索看,不排除这个可能,你最好确认一下。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表