基于Atmega8的频率计原程序.docx

上传人:b****2 文档编号:1939089 上传时间:2022-10-25 格式:DOCX 页数:15 大小:100.62KB
下载 相关 举报
基于Atmega8的频率计原程序.docx_第1页
第1页 / 共15页
基于Atmega8的频率计原程序.docx_第2页
第2页 / 共15页
基于Atmega8的频率计原程序.docx_第3页
第3页 / 共15页
基于Atmega8的频率计原程序.docx_第4页
第4页 / 共15页
基于Atmega8的频率计原程序.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

基于Atmega8的频率计原程序.docx

《基于Atmega8的频率计原程序.docx》由会员分享,可在线阅读,更多相关《基于Atmega8的频率计原程序.docx(15页珍藏版)》请在冰豆网上搜索。

基于Atmega8的频率计原程序.docx

基于Atmega8的频率计原程序

基于Atmega8的频率计原程序+图

基于Atmega8单片机的频率计

基于Atmega8单片机的频率计

前言:

Atmega8-是8位AVR单片机,(8-Kbyteself-programmingFlashProgramMemory,1-KbyteSRAM,512ByteEEPROM,6or8Channel10-bitA/D-converter.Upto16MIPSthroughputat16Mhz.2.7-5.5Voltoperation.);Nokia3310LCD

实验目标

频率计是我们经常会用到的实验仪器之一,本实验要使用单片机和计数电路及液晶器件来设计一个宽频的频率计。

期望达到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

#include"lcd.h"

#include"bmp.h"

unsignedlongcounter;

unsignedcharcountlow;

unsignedcharfre[]="00.000000";

unsignedchartime[]="00:

00:

00";

#pragmainterrupt_handlertimer2_ovf_isr:

iv_TIMER2_OVF

voidtimer2_ovf_isr(void)

{

unsignedchari;

//TCCR2=0;

PORTB&=~0X02;//关闭闸门

//读取计数值

counter=TCNT1;//读取T/C1计数值(频率值的高16位)

counter=counter*256;//计算频率值的高16位

countlow=(PIND&0b11000000)|(PINC&0b00111111);

//读取计数值的低8位

counter=counter+countlow;//计算频率值

PORTD|=0X01;//74LS393清零

TCNT1=0;

PORTD&=~0X01;//关闭清零

TCNT2=0X80;//定时时间1秒

PORTB|=0X02;//打开闸门

//实时时钟显示

time[7]++;

fre[0]=counter/10000000+0x30;

counter=counter%10000000;

fre[1]=counter/1000000+0x30;

counter=counter%1000000;

fre[3]=counter/100000+0x30;

counter=counter%100000;

fre[4]=counter/10000+0x30;

counter=counter%10000;

fre[5]=counter/1000+0x30;

counter=counter%1000;

fre[6]=counter/100+0x30;

counter=counter%100;

fre[7]=counter/10+0x30;

fre[8]=counter%10+0x30;

LCD_write_String(0,2,fre);

LCD_draw_map(14,2,Bmp003,7,14);//显示小数点

LCD_draw_map(62,2,MHz,22,14);//显示频率单位

if(time[7]>(9+0x30))

{

time[6]++;

time[7]-=10;

}

if(time[6]>(5+0x30))

{

time[4]++;

time[6]-=6;

}

if(time[4]>(9+0x30))

{

time[3]++;

time[4]-=10;

}

if(time[3]>(5+0x30))

{

time[1]++;

time[3]-=6;

}

if(time[1]>(9+0x30))

{

time[0]++;

time[1]-=10;

}

LCD_write_String(2,4,time);

LCD_draw_map(16,4,Bmp002,7,14);//显示“:

”字符

LCD_draw_map(37,4,Bmp002,7,14);

}

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

voidmain(void)

{

unsignedchari;

OSCCAL=0xA3;//8M系统内部时钟校准

//设置MCU的I/O口

DDRB|=LCD_RST|LCD_DC|LCD_CE|SPI_MOSI|SPI_CLK;

DDRB|=0x02;//计数闸门

DDRD|=0X01;//74LS393清零

//DDRD|=0X08;//LED

//DDRD&=~0X20;

DDRC&=0B11000000;

DDRD&=0B00111111;

SPSR|=BIT(SPI2X);//设置SPI时钟倍速

SPCR|=BIT(SPE)|BIT(MSTR);//使能SPI接口,主机模式,4M时钟

LCD_init();

//LCD_clear();//清屏

LCD_draw_map(12,0,Bmp001,60,13);

ASSR=1<

TCNT2=0X80;//定时时间1秒

TCCR2=(1<

TIMSK|=BIT(TOIE2);//允许TC2溢出中断

TCCR1B|=BIT(CS12)|BIT(CS11)|BIT(CS10);//时钟外部T1输入,上升源驱动

SEI();

while

(1)

{

}

}

3310液晶显示源代码:

#include

#include

#include"lcd.h"

#include"6x8.h"

#include"chinese.h"

/*----------

LCD_init:

3310LCD初始化

编写日期:

2004-8-10

最后修改日期:

2004-8-10

------------*/

voidLCD_init(void)

{

PORTB&=~LCD_RST;//产生一个让LCD复位的低电平脉冲

delay_1us();

PORTB|=LCD_RST;

PORTB&=~LCD_CE;//关闭LCD

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);//设定显示模式,正常显示

PORTB&=~LCD_CE;//关闭LCD

//LCD_clear();

}

/*--------

LCD_clear:

LCD清屏函数

编写日期:

2004-8-10

最后修改日期:

2004-8-10

-------------*/

voidLCD_clear(void)

{

unsignedinti;

LCD_write_byte(0x0c,0);

LCD_write_byte(0x80,0);

for(i=0;i<504;i++)

LCD_write_byte(0,1);

}

/*---------

LCD_set_XY:

设置LCD坐标函数

输入参数:

X:

0-83

Y:

0-5

编写日期:

2004-8-10

最后修改日期:

2004-8-10

-----------*/

voidLCD_set_XY(unsignedcharX,unsignedcharY)

{

LCD_write_byte(0x40|Y,0);//column

LCD_write_byte(0x80|X,0);//

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1