打印
[51单片机]

51单片机作方波发生器及其存在问题

[复制链接]
2347|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lvsezhidu|  楼主 | 2025-4-28 22:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.12MHZ晶振下所能产生最小方波周期是8us,即高频率是125KHZ
用AT89C51单片机Proteus8.6仿真,用STC89C52RC单片机下载结果一样。
代码如下:
 #include <REG51.h>    //AT89S52 @12MHZ晶振
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
void main()           //产生周期T=8us的方波
{
    while(1)
       {
           P1=~P1;  //每加1个_nop_(); 周期延长2us                                      
        }
}

而采用赋值语句达到同样的结果,代码则是这样的:
 void main()           //产生周期T=8us的方波 12MHZ晶振
{
    while(1)
       {
           P1=0xff; _nop_();_nop_();   //不知为何两句的空操作数不一样多?
           P1=0x00;                         //把两个P1口的赋值顺序改变结果仍不变
        }
}

2.定时器中断方式
#include <reg52.h>            //AT89S52单片机头文件
#define LED P1

#define T0_CNT 1         //定时时间1us,12MHZ晶振
// =========主程序==========================
void main(void)
{   
        TMOD = 0x02;                 //T0模式2,定时
        //IE = 0x82;                 //使能T0中断
        EA = 1; ET0 = 1;               //使能T0中断
  TH0 = 256-T0_CNT ;  //载入定时初值
        TL0 = 256-T0_CNT ;  //载入定时初值
        TR0 = 1;                     //启动T0
        while(1);                   //等待中断
}
//======== T0中断=========================
void T0_zd (void) interrupt 1    //中断编号1
{   
     LED = ~LED;    //
}

定时器定时反而更不准了,结果是高低电平各10us的方波,T0_CNT的值一直改到10结果都一样,把T0_CNT的值逐次加一,一直加到19,则出现周期可变的矩形波,T0_CNT改到20以上才出现方波,用AT89C51单片机Proteus8.6仿真,用STC89C52RC单片机下载结果一样。
3.定时器查询方式
#include <reg52.h>            //52单片机头文件
#define LED P1

#define T0_CNT 1       //定时时间1us,12MHZ晶振
//T0_CNT=1~7:产生周期为14us方波
//T0_CNT=8:产生周期为7us+9us矩形波
//T0_CNT=9:产生周期为18us方波
//T0_CNT=10:产生周期为9us+11us矩形波
//T0_CNT=11:产生周期为22us方波
//T0_CNT=12:产生周期为11us+13us矩形波
//T0_CNT=13:产生周期为26us方波
//T0_CNT=14:产生周期为15us+13us矩形波
//T0_CNT=15:产生周期为30us方波
//T0_CNT=16:产生周期为15us+17us矩形波
//T0_CNT=17:产生周期为34us方波
//T0_CNT=18:产生周期为19us+17us矩形波
//T0_CNT=19:产生周期为38us方波
//T0_CNT=20:产生周期为19us+21us矩形波
//T0_CNT=21:产生周期为42us方波
//T0_CNT=22:产生周期为23us+21us矩形波
//T0_CNT>=23:产生方波
// =========主程序==========================
void main(void)
{   
        TMOD = 0x02;          //T0模式2,定时
  TH0 = 256-T0_CNT ;  //载入定时初值
        TL0 = 256-T0_CNT ;  //载入定时初值
        TR0 = 1;            //启动T0
        while(1)           //产生周期为14us的方波
        {
                while(0 == TF0);   //等待T0溢出
                TF0=0;             //清除T0溢出标志
                LED = ~LED;       //
        }
}



     用AT89C51单片机Proteus8.6仿真,未使用单片机下载。
    定时器查询方式的结果则与定时器中断方式有所不同,这就好像三极管有最佳线性区一样,难道51定时器定时难道也有个最佳的定时区?个中缘由还请高手解答。
       综上所述,普通51单片机作方波发生器,并不能按理论设想的一样,想获得较高的频率确实不容易,最终的结果还要通过实验来确定,如果想要获得较高的频率,可以换其它单片机。

使用特权

评论回复

相关帖子

沙发
STCMCUNT015| | 2025-4-29 11:02 | 只看该作者
用管脚兼容的 AI8051U的 时钟分频输出功能,
有 T0CLKO, T1CLKO, T2CLKO, T3CLKO, T4CLKO,AI8051U手册下载地址:https://www.stcai.com/cp_ai8051uxl

使用特权

评论回复
板凳
xionghaoyun| | 2025-4-29 15:58 | 只看该作者
51的代码看得痛苦

使用特权

评论回复
地板
chineseboyzxy| | 2025-4-29 17:15 | 只看该作者
想要准确的输出时序,感觉还是汇编来的比较准。

使用特权

评论回复
5
alienmiller| | 2025-4-29 19:49 | 只看该作者
本帖最后由 alienmiller 于 2025-4-29 19:50 编辑

12M左右的晶振,1M的运行速度,理论上可以。

使用特权

评论回复
6
coody| | 2025-4-29 23:42 | 只看该作者
用STC89C52RC可以用定时器2,16为自动重装硬件输出方波,不需要中断处理。
如果使用STC8系列,则可以输出方波的方法就更多了,都不需要中断处理,纯硬件输出。

使用特权

评论回复
7
zzele| | 2025-4-30 06:31 | 只看该作者
现在的单片机内置PLL都大幅提升主频了,试试看

使用特权

评论回复
8
lvsezhidu|  楼主 | 2025-5-1 19:24 | 只看该作者
感谢各位大侠相助,看来自己的单片机学习不能固步不前了,应该与时俱进,不断学习新知识。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

24

帖子

0

粉丝