单片机测量信号频率

仿真原理图如下:
MCU和LCD1602显示模块:
单片机测量信号频率_第1张图片
启动及清零信号控制模块:
单片机测量信号频率_第2张图片

C语言代码如下:

/*----------------------------------------
FileName: main.c
Function:测量0 ~ 9999Hz之间的数字信号的频率
Author: Zhang Kaizhou
Date: 2019-6-5 22:39:16
---------------------------------------*/
#include "FrequencyMeasure.h"

bit flag = 0;
uint freq = 0, count = 0, time = 10; // 定时器Timer0溢出次数

void main()
{
	LCDInit();
	displayInit();
	freqMeasure();
	display(freq);
	while(1);
}

void freqMeasure()
{
	Dclr = 0; // 产生D触发器的清零正脉冲
	delay(5);
	Dclr = 1;
	
	TMOD = 0x59; // Timer1 非门控 方式一 计数器;Timer0 门控 方式一定时器
	TH0 = (65536 - 50000) / 256; // Timer0 定时50ms 赋初值
	TL0 = (65536 - 50000) % 256;
	TH1 = 0x00; // Timer1 计数 赋初值0
	TL1 = 0x00;
	TR0 = 1; // 启动Timer0
	TR1 = 1; // 启动Counter1
	ET0 = 1; // 开外部中断0
	EA = 1; // 开全局中断
	
	startSignal = 0; // 产生测量正脉冲信号 启动测量
	delay(5);
	startSignal = 1;
	while(!flag); // 测量中
	
	Dclr = 0; // 产生D触发器清零正脉冲 终止测量
	delay(5);
	Dclr = 1;
	TR0 = 0;
	TR1 = 0;
	count = TH1 * 256 + TL1;
	freq = count * 2; // freq = count / time(s)
}

void timer0() interrupt 1
{
	TH0 = (65536 - 50000) / 256;
	TL0 = (65536 - 50000) % 256;
	time--;
	if(!time)
	{
		flag = 1;
	}
}
/*-----------------------------
FileName:display.c
Function: LCD1602显示函数
Author: Zhang Kaizhou
Date: 2019-6-5 22:43:18
------------------------------*/
#include "FrequencyMeasure.h"

uchar code table0[] = {"Period Measure"}; // 每行的字符数据
uchar code table1[] = {"Period:0000"};
uchar code table2[] = {"0123456789"};
uchar num, ge = 0, shi = 0, bai = 0, qian = 0;

/*初始化LCD1602的设置*/
void LCDInit()
{
	lcden = 0; // 拉低使能端,准备产生使能高脉冲信号
	writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口)
	writeCommand(0x0c); // 开显示,不显示光标
	writeCommand(0x06); // 写一个字符后地址指针自动加1
	writeCommand(0x01); // 显示清零,数据指针清零
}

/*LCD上电界面*/
void displayInit()
{
	writeCommand(0x80); // 将数据指针定位到第一行首
	for(num = 0; num < strlen(table0); num++)
	{
		writeData(table0[num]);
		delay(5);
	}
	
	writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首
	for(num = 0; num < strlen(table1); num++)
	{
		writeData(table1[num]);
		delay(5);
	}
}

/*LCD显示函数*/
void display(uint freq)
{
	if(freq < 10) // 10us以下
	{
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x01);
		writeData(table2[freq]);
	}else if(freq < 100 && freq >= 10){ // 10us ~99us
		shi = freq / 10;
		ge = freq % 10;
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x02);
		writeData(table2[shi]);
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x01);
		writeData(table2[ge]);
	}else if(freq < 1000 && freq >= 100){ // 100us ~ 999us
		bai = freq / 100;
		shi = freq % 100 / 10;
		ge = freq % 10;
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x03);
		writeData(table2[bai]);
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x02);
		writeData(table2[shi]);
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x01);
		writeData(table2[ge]);
	}else if(freq < 10000 && freq >= 1000){ // 100us ~ 999us
		qian = freq / 1000;
		bai = freq % 1000 / 100;
		shi = freq % 100 / 10;
		ge = freq % 10;
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x04);
		writeData(table2[qian]);
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x03);
		writeData(table2[bai]);
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x02);
		writeData(table2[shi]);
		writeCommand(0x80 + 0x40 + strlen(table1) - 0x01);
		writeData(table2[ge]);
	}
}

/*写指令函数*/
void writeCommand(uchar command)
{
	lcdrs = 0; // 命令选择
	lcdrw = 0;
	P0 = command;
	delay(5);
	
	lcden = 1; // 产生一个正脉冲使能信号
	delay(5);
	lcden = 0;
}

/*写数据函数*/
void writeData(uchar dat)
{
	lcdrs = 1; // 数据选择
	lcdrw = 0;
	P0 = dat;
	delay(5);
	
	lcden = 1;
	delay(5);
	lcden = 0;
}

/*延时函数*/
void delay(uchar xms)
{
	uint i, j;
	for(i = xms; i > 0; i--)
		for(j = 110; j > 0; j--);
}
/*----------------------------
FileName: FrequencyMeasure.h
Function: 头文件
Author: Zhang Kaizhou
Date: 2019-6-5 22:45:16
-----------------------------*/
#include 
#include 
#define uchar unsigned char
#define uint unsigned int

sbit lcdrs = P1^2; // LCD数据/命令选择端
sbit lcdrw = P1^3; // LCD读写选择端
sbit lcden = P1^4; // LCD使能端,高脉冲有效
sbit Dclr = P1^5; // D触发器清零端
sbit startSignal = P1^6; // 启动信号频率测量启动信号

void startMeasure();
void display(uint period);
void LCDInit();
void displayInit();
void writeCommand(uchar command);
void delay(uchar xms);
void writeData(uchar dat);
void freqMeasure();

你可能感兴趣的:(C51)