采用单片机及液晶器件的宽频的频率计设计,Digital frequency meter
关键字:ATMEGA8,频率计电路图
我们常用到的实验仪器之一——频率计,本实验要使用单片机和计数电路及液晶器件来设计一个宽频的频率计。
期望达到10Hz-1.1G范围的频率精确测量。
实验电路图(初步方案)
1) 计数及显示电路:
2)前置放大及分频电路:
设计思路
频率的测量实际上就是在1S时间内对信号进行计数,计数值就是信号频率。用单片机设计频率计通常采用两种办法,1)使用单片机自带的计数器对输入脉冲进行计数,或者测量信号的周期;2)单片机外部使用计数器对脉冲信号进行计数,计数值再由单片机读取。
由于单片机自带计数器输入时钟的频率通常只能是系统时钟频率的几分之一甚至几十分之一,因此采用单片机的计数器直接测量信号频率就受到了很大的限制。
本实验电路采用方式2,使用一片74LS393四位双二进制计数器和Atmega8的 T1计数器组成了24位计数器,最大计数值为16777215。如果输入信号经过MB501分频器进行64分频后再进行测量,则固定1S时基下最高测量频率为1073.741760Mhz。
为了方便得到准确的1秒钟测量闸门信号,我们使用了Atmega8的异步实时时钟功能,采用32.768Khz的晶振由TC2产生1秒钟的定时信号。
测量原理:
单片机打开测量闸门,即PB1输出高电平,同时TC2定时器启动。74LS393开始对输入脉冲进行计数,74LS393每计数达256时,Atmega8的T1计数器也向上计数1次。当1S定时到达时,单片机产生中断,PB1输出低电平关闭测量闸门,然后Atmega8读取74LS393和T1的计数值,然后送LCD显示。
实验进展
2004-09-27
根据设计思路编写程序初步获得了一些实验结果,如下图所示。下图是测量8M有源晶振的输出结果。
由于1S的测量闸门时间在业余条件下不好测试,因此,实验程序中在LCD上同时显示实时时钟用于判断1S闸门时间的准确性。实验中,我使用CDMA手机上显示的GPS卫星精确时间进行比较。手机时间显示的最小单位是分钟,测量时一旦手机分钟值发生跳变,则立即记录下LCD显示的秒值,这样的话让频率计运行一段时间后,再多次记录下LCD显示的秒,就可以准确判断频率计的异步时钟是否准确。实验过程中,我让频率计走了10个小数左右,测量的1S时钟还是非常准确的。
#include
#include
#includeLCD.h
#include 6x8.h
#include chinese.h
#include
#includeLCD.h
#include 6x8.h
#include chinese.h
/*-----------------------------------------------------------------------
LCD_init : 3310LCD初始化
LCD_init : 3310LCD初始化
编写日期 :2004-8-10
最后修改日期 :2004-8-10
-----------------------------------------------------------------------*/
void LCD_init(void)
{
PORTB &= ~LCD_RST; // 产生一个让LCD复位的低电平脉冲
delay_1us();
PORTB |= LCD_RST;
最后修改日期 :2004-8-10
-----------------------------------------------------------------------*/
void LCD_init(void)
{
PORTB &= ~LCD_RST; // 产生一个让LCD复位的低电平脉冲
delay_1us();
PORTB |= LCD_RST;
PORTB &= ~LCD_CE ; // 关闭LCD
delay_1us();
PORTB |= LCD_CE; // 使能LCD
delay_1us();
delay_1us();
PORTB |= LCD_CE; // 使能LCD
delay_1us();
LCD_write_byte(0x21, 0); // 使用扩展命令设置LCD模式
LCD_write_byte(0xc8, 0); // 设置偏置电压
LCD_write_byte(0x06, 0); // 温度校正
LCD_write_byte(0x13, 0); // 1:48
LCD_write_byte(0x20, 0); // 使用基本命令
LCD_clear(); // 清屏
LCD_write_byte(0x0c, 0); // 设定显示模式,正常显示
LCD_write_byte(0xc8, 0); // 设置偏置电压
LCD_write_byte(0x06, 0); // 温度校正
LCD_write_byte(0x13, 0); // 1:48
LCD_write_byte(0x20, 0); // 使用基本命令
LCD_clear(); // 清屏
LCD_write_byte(0x0c, 0); // 设定显示模式,正常显示
PORTB &= ~LCD_CE ; // 关闭LCD
//LCD_clear();
}
//LCD_clear();
}
/*-----------------------------------------------------------------------
LCD_clear : LCD清屏函数
LCD_clear : LCD清屏函数
编写日期 :2004-8-10
最后修改日期 :2004-8-10
-----------------------------------------------------------------------*/
void LCD_clear(void)
{
unsigned int i;
最后修改日期 :2004-8-10
-----------------------------------------------------------------------*/
void LCD_clear(void)
{
unsigned int i;
LCD_write_byte(0x0c, 0);
LCD_write_byte(0x80, 0);
LCD_write_byte(0x80, 0);
/*-----------------------------------------------------------------------
LCD_set_XY : 设置LCD坐标函数
LCD_set_XY : 设置LCD坐标函数
输入参数:X :0-83
Y :0-5
Y :0-5
编写日期 :2004-8-10
最后修改日期 :2004-8-10
-----------------------------------------------------------------------*/
void LCD_set_XY(unsigned char X, unsigned char Y)
{
LCD_write_byte(0x40 | Y, 0); // column
LCD_write_byte(0x80 | X, 0); // row
}
最后修改日期 :2004-8-10
-----------------------------------------------------------------------*/
void LCD_set_XY(unsigned char X, unsigned char Y)
{
LCD_write_byte(0x40 | Y, 0); // column
LCD_write_byte(0x80 | X, 0); // row
}
/*-----------------------------------------------------------------------
LCD_write_char : 显示英文字符
LCD_write_char : 显示英文字符
输入参数:c :显示的字符;
编写日期 :2004-8-10
最后修改日期 :2004-8-10
-----------------------------------------------------------------------*/
void LCD_write_char(unsigned char c)
{
unsigned char line;
最后修改日期 :2004-8-10
-----------------------------------------------------------------------*/
void LCD_write_char(unsigned char c)
{
unsigned char line;
//c -= 32;
//for (line=0; line<6; line++)
//LCD_write_byte(font6x8[c][line], 1);
for (line=0; line<7; line++)
LCD_write_byte(font7x13[c][line], 1);
for (line=7; line<14; line++)
LCD_write_byte(font7x13[c][line], 1);
//LCD_write_byte(font6x8[c][line], 1);
for (line=0; line<7; line++)
LCD_write_byte(font7x13[c][line], 1);
for (line=7; line<14; line++)
LCD_write_byte(font7x13[c][line], 1);
}
/*-----------------------------------------------------------------------
LCD_write_char : 英文字符串显示函数
LCD_write_char : 英文字符串显示函数
输入参数:*s :英文字符串指针;
X、Y : 显示字符串的位置
X、Y : 显示字符串的位置
-----------------------------------------------------------------------*/
void LCD_write_String(unsigned char X,unsigned char Y,char *s)
{
unsigned char line;
unsigned char i=0;
while (*s)
{
LCD_set_XY(X+i*7,Y);
for (line=0; line<7; line++)
LCD_write_byte(font7x13[*s-0X30][line], 1);
void LCD_write_String(unsigned char X,unsigned char Y,char *s)
{
unsigned char line;
unsigned char i=0;
while (*s)
{
LCD_set_XY(X+i*7,Y);
for (line=0; line<7; line++)
LCD_write_byte(font7x13[*s-0X30][line], 1);
LCD_set_XY(X+i*7,Y+1);
for (line=7; line<14; line++)
LCD_write_byte(font7x13[*s-0X30][line], 1);
s++;
i++;
}
}
/*-----------------------------------------------------------------------
LCD_write_chi: 在LCD上显示汉字
for (line=7; line<14; line++)
LCD_write_byte(font7x13[*s-0X30][line], 1);
s++;
i++;
}
}
/*-----------------------------------------------------------------------
LCD_write_chi: 在LCD上显示汉字
输入参数:X、Y :显示汉字的起始X、Y坐标;
ch_with :汉字点阵的宽度
num :显示汉字的个数;
line :汉字点阵数组中的起始行数
row :汉字显示的行间距
-----------------------------------------------------------------------*/
void LCD_write_chi(unsigned char X, unsigned char Y,
unsigned char ch_with,unsigned char num,
unsigned char line,unsigned char row)
{
unsigned char i,n;
ch_with :汉字点阵的宽度
num :显示汉字的个数;
line :汉字点阵数组中的起始行数
row :汉字显示的行间距
-----------------------------------------------------------------------*/
void LCD_write_chi(unsigned char X, unsigned char Y,
unsigned char ch_with,unsigned char num,
unsigned char line,unsigned char row)
{
unsigned char i,n;
LCD_set_XY(X,Y); //设置初始位置
for (i=0;i{
for (n=0; n{
if (n==ch_with) //写汉字的下半部分
{
if (i==0) LCD_set_XY(X,Y+1);
else
LCD_set_XY((X+(ch_with+row)*i),Y+1);
}
LCD_write_byte(china_char[line+i][n],1);
}
i++;
LCD_set_XY((X+(ch_with+row)*i),Y);
}
}
for (n=0; n
if (n==ch_with) //写汉字的下半部分
{
if (i==0) LCD_set_XY(X,Y+1);
else
LCD_set_XY((X+(ch_with+row)*i),Y+1);
}
LCD_write_byte(china_char[line+i][n],1);
}
i++;
LCD_set_XY((X+(ch_with+row)*i),Y);
}
}
/*-----------------------------------------------------------------------
LCD_write_chi: 汉字移动
LCD_write_chi: 汉字移动
输入参数:X、Y :显示汉字的起始X、Y坐标;
T :移动速度;
T :移动速度;
-----------------------------------------------------------------------*/
voidLCD_move_chi (unsigned char X, unsigned char Y, unsigned char T)
{
unsigned char i,n,j=0;
unsigned char buffer_h[84]={0};
unsigned char buffer_l[84]={0};
voidLCD_move_chi (unsigned char X, unsigned char Y, unsigned char T)
{
unsigned char i,n,j=0;
unsigned char buffer_h[84]={0};
unsigned char buffer_l[84]={0};
for (i=0; i<156; i++)
{
buffer_h[83] = china_char[i/12][j];
buffer_l[83] = china_char[i/12][j+12];
j++;
if (j==12) j=0;
{
buffer_h[83] = china_char[i/12][j];
buffer_l[83] = china_char[i/12][j+12];
j++;
if (j==12) j=0;
for (n=0; n<83; n++)
{
buffer_h[n]=buffer_h[n+1];
buffer_l[n]=buffer_l[n+1];
}
{
buffer_h[n]=buffer_h[n+1];
buffer_l[n]=buffer_l[n+1];
}
LCD_set_XY(X,Y);
for (n=0; n<83; n++)
{
LCD_write_byte(buffer_h[n],1);
}
for (n=0; n<83; n++)
{
LCD_write_byte(buffer_h[n],1);
}
LCD_set_XY(X,Y+1);
for (n=0; n<83; n++)
{
LCD_write_byte(buffer_l[n],1);
}
for (n=0; n<83; n++)
{
LCD_write_byte(buffer_l[n],1);
}
delay_nms(T);
}
}
}
}
/*-----------------------------------------------------------------------
LCD_draw_map : 位图绘制函数
LCD_draw_map : 位图绘制函数
-----------------------------------------------------------------------*/
void LCD_draw_map(unsigned char X,unsigned char Y,unsigned char *map,
unsigned char Pix_x,unsigned char Pix_y)
{
unsigned int i,n;
unsigned char row;
void LCD_draw_map(unsigned char X,unsigned char Y,unsigned char *map,
unsigned char Pix_x,unsigned char Pix_y)
{
unsigned int i,n;
unsigned char row;
if (Pix_y%8==0) row=Pix_y/8; //计算位图所占行数
else
row=Pix_y/8+1;
else
row=Pix_y/8+1;
for (n=0;n{
LCD_set_XY(X,Y);
for(i=0; i{
LCD_write_byte(map[i+n*Pix_x], 1);
}
Y++; //换行
}
}
LCD_set_XY(X,Y);
for(i=0; i
LCD_write_byte(map[i+n*Pix_x], 1);
}
Y++; //换行
}
}
/*-----------------------------------------------------------------------
LCD_write_byte : 使用SPI接口写数据到LCD
LCD_write_byte : 使用SPI接口写数据到LCD
输入参数:data :写入的数据;
command :写数据/命令选择;
command :写数据/命令选择;
-----------------------------------------------------------------------*/
void LCD_write_byte(unsigned char data, unsigned char command)
{
PORTB &= ~LCD_CE ; // 使能LCD
void LCD_write_byte(unsigned char data, unsigned char command)
{
PORTB &= ~LCD_CE ; // 使能LCD
SPDR = data; // 传送数据到SPI寄存器
while ((SPSR & 0x80) == 0); // 等待数据传送完毕
PORTB |= LCD_CE ; // 关闭LCD
}
}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
发布评论请先 登录
相关推荐
基于STM32单片机的语音播报体温计设计
语音播报体温计系统包括温度采集模块,语音播放模块,显示模块,其中核心 CPU采用单片机 STM32,STM32在电子行业运用广泛。温度采集模块使用 MLX90614红外传感器采集体温数据,语音播放模块
频率计的使用方法
频率计,作为电子测量领域的重要工具,主要用于测量信号的频率。在现代电子工程、通信、航空航天等领域,频率计的应用日益广泛。然而,对于许多初学者或新用户来说,如何正确使用频率计可能是一个挑
频率计的工作原理和分类详解
在电子工程、通信和科研领域,频率计是一种不可或缺的电子测量仪器。它以其高精度、高速度和高分辨率的频率测量能力,为科研和工程实践提供了极大的便利。本文将深入解析频率计的工作原理,并详细介绍其分类,以期为读者提供全面而深入的了解。
频率计的基本概念和组成部分
在现代电子科技领域,信号的频率测量是不可或缺的一部分。频率计,作为专门用于测量信号频率的电子设备,其精准度和可靠性对于电子设备的调试、维护和研发都至关重要。本文将详细介绍频率计的基本概
频率计的基本原理及分类 频率计的功能特点及应用场景
在现代电子技术领域中,频率是一个极其重要的物理量。无论是无线通信、雷达探测,还是音频处理、电子测量,频率的准确测量和控制都至关重要。因此,频率计作为专门用于测量信号频率的仪器,其性能和
频率计有哪些作用
频率计又称为频率计数器,是一种专门对被测信号频率进行测量的电子测量仪器。其主要由四个部分构成:时基(T)电路、输入电路、计数显示电路以及控制电路。又称为频率计数器,是一种专门对被测信号
频率计的原理
公司主营出售/回收:示波器、频谱分析仪、网络分析仪、信号发生器、万用表/示波器校准仪、手机综合测试仪、噪声系数分析仪、数据采集器、NI-GPIB卡、阻抗/LCR测试仪,音频分析仪、蓝牙/WANL测试仪、电源、电池测试仪、探头/配件、天馈线测试仪、光谱分析仪 频率计、功率计
基于FPGA设计频率计方案介绍分享
off。
2频率计介绍
频率计又称为[频率计数器],是一种专门对被测信号频率进行测量的电子测量仪器。频率计主要由四个部分构成:时基(T)电
发表于 03-31 16:22
基于51单片机的智能频率计毕设,C代码,仿真,原理图,论文
;
(3)测量误差:低于0.1%;
(4)频率测量结果采用LCD1602液晶显示;
系统概述
本设计给出了一种以AT89C52单片机为控制核心的数字
发表于 03-18 12:57
基于单片机的数字频率计的实现论文分享
频率计测频原理方框图如图1所示。被测输入信号通过脉冲形成电路进行放大与整形(可由放大器与门电路组成),然后送到单片机入口,单片机计数脉冲的输入个数。计数结果经LED数码管显示,从而得到被测信号
发表于 02-15 16:17
•823次阅读
评论