A. 51单片机制作简易数字频率计程序
这里有一个四位数码管的频率计,供参考
#include<reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //所需的段的位码
//ucharwei[4]={0XEf,0XDf,0XBf,0X7f};//位的控制端 (开发板)
ucharwei[4]={0X80,0X40,0X20,0X10};//位的控制端 (仿真)
uintz,x,c,v,date; //定义数据类型
uintdispcount=0;
uintlck=0;
uintdisp=0;
/******************************************************************
延时函数
******************************************************************/
voiddelay(uchart)
{
uchari,j;
for(i=0;i<t;i++)
{
for(j=13;j>0;j--);
{;
}
}
}
/**********************************************************************
数码管动态扫描
*********************************************************************/
voidxianshi()
{
/*****************数据转换*****************************/
z=date/1000; //求千位
x=date%1000/100; //求百位
c=date%100/10; //求十位
v=date%10; //求个位
P2=wei[0];
P0=an[z];
delay(50);
P2=wei[1];
P0=an[x];
delay(50);
P2=wei[2];
P0=an[c];
delay(50);
P2=wei[3];
P0=an[v];
delay(50);
}
/*************************************************************************
定时器初值1ms
**************************************************************************/
voidinitTimer(void)
{
TMOD=0x0;
TH0=0xe3;
TL0=0xc;
}
/*************************************************************************
定时器函数
**************************************************************************/
voidtimer0(void)interrupt1
{
TH0=0xe3;
TL0=0xc;
lck++;
if(lck==1000)
{
disp=dispcount;
lck=0;
dispcount=0;
}
}
/*************************************************************************
中断函数
**************************************************************************/
voidint0(void)interrupt0
{
dispcount++;//每一次中断,计数加一
}
/*************************************************************************
主函数
**************************************************************************/
voidmain(void)
{
IT0=1;//INT0下降沿中断
EX0=1;//允许INT1中断
initTimer();//装入初值
TR0=1;
ET0=1;
EA=1;
while(1)
{
date=disp;
xianshi();
}
}
B. 求51单片机测量正弦波(20~100hz)的频率的c程序,最好是已经通过测试过的
首先使用电压比较器电路将正弦波转化成方波,以方便单片机接收,参考下图(该电路可接收峰峰值正负12V的正弦波),如果你的正弦波电路和单片机电路使用了不同的电源,则还需进行隔离处理
#include<AT89X51.H>
//********数码管位代码表(P0口)**********//
unsignedcharcodedispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//********数码管段代码表(P2口,共阴且高位接a,低位接h笔段)**********//
unsignedcharcodedispcode[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,
0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00};
//********8位数据缓冲器**********//
unsignedchardispbuf[8];
unsignedchartemp[8];
unsignedchardispcount;
unsignedcharT0count;
unsignedchartimecount;
bitflag;
unsignedlongx;
//*********初始化模块**********//
voidinitial(void){
TMOD=0x15;
TH0=0;
TL0=0;
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
TR1=0;
TR0=0;
ET0=1;
ET1=1;
EA=1;
}
//******************************************************//
//*********显示模块**********//
voiddataDisplay(){
unsignedchari;
for(i=0;i<8;i++){
temp[i]=0;
}
i=0;
while(x/10){
temp[i]=x%10;
x=x/10;
i++;
}
temp[i]=x;
for(i=0;i<8;i++){
dispbuf[i]=temp[i];
}
P2=dispcode[dispbuf[dispcount]];
P0=dispbit[dispcount];
dispcount++;
if(dispcount==8){
dispcount=0;
}
}
//******************************************************//
//*********信号频率测量模块**********//
floatfrequency(floatfreq){
initial();
TR0=1;TR1=1;
if(timecount==250){
TR0=0;
freq=T0count*65536+TH0*256+TL0;
return(freq);
}
}
//******************************************************//
//*********信号周期测量模块**********//
floatcycle(floatcount){
initial();
if(P3_4==1){
TR0=1;TR1=1;
if(P3_4==0){
TR0=0;
count=1000000/(timecount*4000+TH1*256+TL1-61536);
}
}
return(count);
}
//******************************************************//
//*********定时中断服务程序1**********//
voidt1(void)interrupt3using0{
//initial();
//TR0=1;
//TR1=1;
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
timecount++;
}
//******************************************************//
//*********定时中断服务程序2**********//
voidt0(void)interrupt1using0{
//initial();
//TR0=1;
//TR1=1;
T0count++;
}
//******************************************************//
//*********主函数**********//
voidmain(void){
while(1){
x=frequency(x);
if(x<100){
x=cycle(x);
}
dataDisplay();
}
}
//******************************************************//
C. 51单片机控简易频率计的程序
1M,似乎不太好弄,如果要求比较精确的话;
100HZ~1M,换成同期:1US~10MS,周期/2=(0.5US~5MS),0.5US的脉宽....24M晶振都做不到的;检测一个脉宽起码也行四五条指令吧。。。
用汇编:
loop:
JB DATA_IN,$;高电平等待
JNB DATA_IN,$;低电平等待
INC TIMES;脉宽数加1
AJMP loop;
再用定时器定时:如:10MS,记录这10MS内TIMES变化了多少次,再换算成频率;注意误差范围。。。。频率低的话10MS得换大些。。
显示部分也可用定时器来做。。
综合以上,应该还是能做的;
如能选些6T 或 1T的51单片机肯定没问题,传统的12T的估计有点难