跪求单片机at89c52频率计c语言程序

跪求单片机at89c52频率计c语言程序,第1张

方波叫函数发生器。频率计程序如下:

#include "reg51.h"

#define uchar unsigned char

uchar disp[8]={0,0,0,0,0,0,0,0}

uchar T0count,T1count

void delay(void)

{

uchar i

for(i=250i>0i--)

}

void display()

{

//uchar i,j,k=0x80

uchar dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}

uchar i,k

k=0x80

for(i=0i<8i++)

{

P2=0

P0=dispcode[disp[i]]

P0=~P0

P2=k

k=k>>1

delay()

}

P2=0

}

void calc()

{

uchar i

long frequency

frequency=(T0count*256+TH0)*256+TL0

for(i=7i>0i--)

{

disp[i]=frequency%10

frequency=frequency/10

}

disp[0]=frequency

}

void init()

{

T0count=0

T1count=0

TH0=0

TL0=0

}

void main()

{

init()

TMOD=0x15

TH1=(65536-5*110592/12)/256

TL1=(65536-5*110592/12)/256%10

ET1=1

ET0=1

EA=1

TR1=1

TR0=1

//以下四句的作用是在P1.0引脚上形成1000Hz的脉冲,用导线连接到P3.4作为测试用,如果是AT89S51,则四句不用。将其中

//高8位和低8位的初始值更改后可输出不同频率的脉冲。

/*

T2MOD=0x2

RCAP2H=245

RCAP2L=74

TR2=1

*/

while(1)

{

display()

}

}

void time0() interrupt 1

{

T0count++

}

void time1() interrupt 3

{

TH1=(65536-5*110592/12)/256

TL1=(65536-5*110592/12)/256%10

if(T1count==19)

{

calc()

init()

}

else T1count++

}

这里有一个四位数码管的频率计,供参考

#include <reg52.h>

#define uchar unsigned char

#define uint  unsigned  int

uchar duan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}  //所需的段的位码

//uchar wei[4]={0XEf,0XDf,0XBf,0X7f}                                 //位的控制端 (开发板)

uchar wei[4]={0X80,0X40,0X20,0X10}                                 //位的控制端 (仿真)

uint z,x,c,v, date //定义数据类型

uint dispcount=0

uint lck=0

uint disp=0

/******************************************************************

延时函数

******************************************************************/

void delay(uchar t)

{

  uchar i,j

   for(i=0i<ti++)

   {

     for(j=13j>0j--)

 { 

 }

   }

}

/**********************************************************************

                数码管动态扫描

*********************************************************************/

void xianshi()

 { 

 /*****************数据转换*****************************/ 

  z=date/1000  //求千位

  x=date%1000/100  //求百位

  c=date%100/10  //求十位

  v=date%10  //求个位

      P2=wei[0]

  P0=duan[z]

  delay(50)  

     P2=wei[1]

      P0=duan[x]

  delay(50)  

      P2=wei[2]

      P0=duan[c]

  delay(50)  

      P2=wei[3]

      P0=duan[v]

  delay(50)  

                 

       }

/*************************************************************************

                                定时器初值1ms

**************************************************************************/

void initTimer(void)

{

 TMOD=0x0

 TH0=0xe3

 TL0=0xc

}

/*************************************************************************

                                定时器函数

**************************************************************************/

void timer0(void) interrupt 1

{

 TH0=0xe3

 TL0=0xc

 lck++

 if(lck==1000)

       {

        disp=dispcount

      lck=0

dispcount=0

       }

}

/*************************************************************************

                                中断函数

**************************************************************************/

void int0(void) interrupt 0

{

dispcount++ //每一次中断,计数加一

}

/*************************************************************************

                                主函数

**************************************************************************/

void main(void)

{

IT0=1     //INT0下降沿中断

EX0=1     //允许INT1中断

initTimer() //装入初值

TR0=1

ET0=1

EA=1

while(1)

{

date=disp

xianshi()

}

}

定时器1对外部脉冲计数时TMOD高4位设置应该是5

因此TMOD=0x51

以下我的频率计程序:

#include <reg52.h>//因没用到STC12C5410专有特殊功能寄存器,此处用52或51的头文件均可

#define unit unsigned int

#define uchar unsigned char

//定义以I/O口的功能

sbit beiguang=P3^2//液晶屏背光

sbit rs=P1^3//液晶屏写选择,0命令 1数据

sbit rw=P1^4//液晶屏读写选择

sbit lcden=P1^5//液晶屏使能

sbit fm=P1^7//蜂鸣器

#define db P2 //定义P2为数据输出口,写数据时用db代替P2,增加液晶屏程序的通用性

//更改硬件接线时,只更改此处,而不必去更改液晶屏读写子程序

uchar aa,bb,cc//变量声明

unit dd,ee

void Delay1ms(unsigned int i) //1ms延时程序

{

unsigned int j

for(i>0i--)

{

for(j=0j<125j++)

{}

}

}

void init()//初始化设置

{

TMOD=0x15//定时器0作为计数器,定时器1作为定时器用

TH0=0//计数器清0

TL0=0

EA=1//开总中断

ET1=1//允许定时器1中断

TH1=0x4c

TL1=0x5c

TR0=1//启动计数器

TR1=1//启动定时器

aa=0

}

void write_com(uchar com)//向液晶屏写命令

{

db=com

rs=0

rw = 0

lcden=0

Delay1ms(10*12)

lcden=1

Delay1ms(10*12)

lcden=0

}

void write_date(uchar date)//向液晶屏写数据

{

db=date

rs=1

rw = 0

lcden=0

Delay1ms(10*12)

lcden=1

Delay1ms(10*12)

lcden=0

}

void init2()//液晶屏初始化

{

beiguang=0

rw=0

write_com(0x38)

Delay1ms(10*12)

write_com(0x0f)

Delay1ms(10*12)

write_com(0x06)

Delay1ms(10*12)

write_com(0x01)

Delay1ms(10*12)

}

void display4(unsigned int number) //单行多位显示程序

{

uchar A1,A2,A3,A4,A5

init2()//液晶屏初始化

A1=number/10000%10//分离出万,千,百,十,个,对于int型数据,最大不超过65535

A2=number/1000%10

A3=number/100%10

A4=number/10%10

A5=number%10

write_com(0x80)//第1个数据的位置设定,第1行第1列

Delay1ms(10)

write_date(0x30+A1)//写数据

Delay1ms(10)

write_date(0x30+A2)

Delay1ms(10)

write_date(0x30+A3)

Delay1ms(10)

write_date(0x30+A4)

Delay1ms(10)

write_date(0x30+A5)

Delay1ms(10)

write_com(0x87)//第6个数据'H'的位置,中间空85和86 二格

write_date('H')

Delay1ms(10)

write_date('z')

Delay1ms(10)

}

void main()//主程序很简单

{

init()//初始化

while(1)//循环程序

{

dd=bb*256+cc//0.5S的计数值

ee=2*dd//换算为1秒钟的计数值

if(aa==1)

{

if(TH0>12)//预判断,50ms内TH0>12,1s内计数值将超过可计数的最大值65535

fm=0//报警

}

display4(ee)//显示

fm=1//报警停止

}

}

void timer1()interrupt 3//注意:定时器1的中断序号为3

{

aa++

TH1=0x4c//11.0592Mhz

TL1=0x5c

if(aa==10)//中断10次,共0.5S

{

TR0=0//暂停计数

aa=0

bb=TH0//读出计数器数据

cc=TL0

TL0=0//计数器清0

TH0=0

TR0=1//重新启动

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/7695768.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-08
下一篇 2023-04-08

发表评论

登录后才能评论

评论列表(0条)

保存