找回密码
 立即注册

QQ登录

只需一步,快速开始

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

频率计数器程序

[复制链接]
跳转到指定楼层
楼主
ID:410884 发表于 2018-10-17 04:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <AT89x52.h>
#include <stdio.h>
#include <math.h>
#include <intrins.h>

float p;
char idata buff[20];
unsigned char time;
unsigned char T1inter;
unsigned char GATE = 1;        //测量中断,0表示开始测量
unsigned char FLAG = 0;      //是否分频选择,0不分频,1分频
unsigned char LCD_Wait(void);
void LCD_Write(bit style, unsigned char input);
void LCD_SetDisplay(unsigned char DisplayMode);
void LCD_SetInput(unsigned char InputMode);
void LCD_Initial();
void GotoXY(unsigned char x, unsigned char y);
void Print(unsigned char *str);

/****************************************
*   模块名称:LCD1602显示程序           *
*****************************************/
/***********************Port Definitions*********************/
sbit LcdRs = P1^0;   //定义端口
sbit LcdRw = P1^1;
sbit LcdEn = P2^5;
sfr  DBPort= 0x80;        //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

/************************内部等待函数************************/
unsigned char LCD_Wait(void)
{
    LcdRs=0;         //寄存器选择输入端     1:数据 0:指令
    LcdRw=1;    _nop_(); //RW:为0:写状态;为1:读状态;
    LcdEn=1;    _nop_();    //使能输入端,读状态,高电平有效;写状态,下降沿有效
    LcdEn=0;
    return DBPort;      
}
/***********************向LCD写入命令或数据*******************/
#define LCD_COMMAND 0      // Command
#define LCD_DATA 1      // Data
#define LCD_CLEAR_SCREEN    0x01      // 清屏
#define LCD_HOMING          0x02      // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
    LcdEn=0;
    LcdRs=style;
    LcdRw=0;        _nop_();
    DBPort=input;    _nop_();//注意顺序
    LcdEn=1;        _nop_();//注意顺序
    LcdEn=0;        _nop_();
    LCD_Wait();   
}
/********************设置显示模式****************************/
#define LCD_SHOW            0x04    //显示开
#define LCD_HIDE            0x00    //显示关      

#define LCD_CURSOR            0x02     //显示光标
#define LCD_NO_CURSOR        0x00    //无光标            

#define LCD_FLASH            0x01    //光标闪动
#define LCD_NO_FLASH        0x00    //光标不闪动

void LCD_SetDisplay(unsigned char DisplayMode)
{
    LCD_Write(LCD_COMMAND, 0x08|DisplayMode);   
}
/*********************设置输入模式****************************/
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN    0x00      // default

#define LCD_MOVE 0x01         // 画面可平移
#define LCD_NO_MOVE    0x00      //default

void LCD_SetInput(unsigned char InputMode)
{
    LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
/******************初始化LCD*********************************/
void LCD_Initial()
{
    LcdEn=0;
    LCD_Write(LCD_COMMAND,0x38);    //8位数据端口,2行显示,5*7点阵
    LCD_Write(LCD_COMMAND,0x38);
    LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标
    LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
    LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动
}

/*************************************************************/
void GotoXY(unsigned char x, unsigned char y)
{
if(y==0)
        LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
        LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
void Print(unsigned char *str)
{
    while(*str!='\0')
    {
        LCD_Write(LCD_DATA,*str);
        str++;
    }
}
/**************************ms延时子程序********************/
void Delay(unsigned int t)      //t随着数值越大,误差趋于平衡.
{
unsigned char i;
     while(t--)
       {
         for(i=0;i<123;i++){;}
       }
}
//配置计数器0、1,定时器2
//
void Init_timer(void)
{
TMOD=0x95;                      //工作方式1 内部寄存器控制的计数功能
TH0=0x00;                         //T0高八位的初值
TL0=0x00;                         //T0低八位初值
TH1=0x00;                         //T1高八位的初值
TL1=0x00;                         //T1低八位初值
EA=1;                            //开启整体中断允许
ET0=1;                           //开启定时器0中断允许
ET1=1;                             //开启T1中断允许
TR0=1;                             //关闭T0 T1 等待INT0中断打开T0 T1
TR1=1;
EX0=1;
IT0=1;
RCAP2H=(65536-62500)/256; //在程序初始化的时候给RCAP2L和RCAP2H赋值,
RCAP2L=(65536-62500)%256; //TH2和TL2将会在中断产生时自动使TH2=RCAP2H,TL2=RCAP2L。
TH2=RCAP2H;               //12M晶振下每次中断62.5ms(1s=1000ms=62.5ms×16)
TL2=RCAP2L;
ET2=1;                    //打开定时器2中断     
TR2=1;                    //定时器2开始计时      
}

  
     
/***************主程序**************/
void main()
{
P1_2=0;
//P1_4=0;
Init_timer();
LCD_Initial();       //LCD初始化
while(1)
{;}

}
void Out_interrupt(void)interrupt 0
{
float t0cont,t1cont;
//测量开始标志,GATE=0 开始测量 打开T0 T1
/*if(!GATE)
{
TR0=0;
TR1=0;                       //关TO T1
GATE=~GATE;
}
else
{
TR0=1;
TR1=1;                       //开TO T1
GATE=~GATE;
}*/    TR0=0;
    TR1=0;
    t0cont=TH0*256+TL0;
      t1cont=65535*T1inter+TH1*256+TL1;
    //p=(t0cont/t1cont)*1000000;
    p=t0cont;
    GotoXY(0,1);
    sprintf(buff,"%4.4fKHz",p);
      Print(buff);
    /*if(!FLAG)
    {
    //分频使能无效 不分频
    P1_4=0;
    //分频标志回置 不分频
    FLAG=~FLAG;
    //显示
    GotoXY(0,1);
    sprintf(buff,"%8.4fKHz",p);
      Print(buff);
    //标准时钟溢出清零
    T1inter=0;
    }
    else
    {
    GotoXY(0,1);
    sprintf(buff,"%8.4fHz",p);
      Print(buff);
    T1inter=0;
    }*/
    //重置初值,为下一次测量做准备
    TR0=1;
    TR1=1;
    TH0=0;                         //T0高八位的初值
    TL0=0;                         //T0低八位初值
    TH1=0;                       //T1高八位的初值
    TL1=0;
   //中断后开始读数显示     
                                                                                                     
}
void Timer0_isr(void)interrupt 1
{    //分频
    FLAG=~FLAG;
    //计数=(65535-初值)  初值0xFD1F     
       TH0=0x00;     
    TL0=0x00;
    //分频使能
    P1_4=~P1_4;         
}
void Timer1_isr(void)interrupt 3
{    T1inter++;
       TH1=0;      //计数=(65535-初值)  初值0x159F=5535
    TL1=0;
    if(T1inter==4)
    {      
    T1inter=0;
    }
}
void timer2(void) interrupt 5 //定时器2中断(62.5ms)
{
    time++;
    TF2=0;                    //定时器2的中断标志位TF2不能够由硬件清零,所以要在中断服务程序中将其清零
    if (time==4)             //定时0.25s时间到  
    {
    time=0;                //计时清0               
    P1_2=~P1_2;        
    }
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2018-10-17 13:25 | 只看该作者
补全原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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