機(jī)電之家資源網(wǎng)
單片機(jī)首頁(yè)|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
ATMEGA8單片機(jī)頻率計(jì)程序與電路圖
ATMEGA8單片機(jī)頻率計(jì)程序與電路圖
 更新時(shí)間:2009-11-30 16:14:02  點(diǎn)擊數(shù):0
【字體: 字體顏色

原理上采用32.768K外部晶振產(chǎn)生異步時(shí)鐘信號(hào) ,作為M8定時(shí)器2de時(shí)鐘源,設(shè)定1024de預(yù)分頻,可以得到TCNT2溢出de精確時(shí)間為1s,在溢出中斷時(shí)控制74ls00與非門進(jìn)而控制被測(cè)信號(hào)de通斷,累計(jì)1s 內(nèi)計(jì)數(shù)器獲得de值,經(jīng)過(guò)簡(jiǎn)單de運(yùn)算則可獲得被測(cè)信號(hào)de頻率

M8 采用內(nèi)部 8M 內(nèi)部RC震蕩 工作模式 , 電路采用74ls393 對(duì)被測(cè)信號(hào)進(jìn)行預(yù)分頻,相當(dāng)于擴(kuò)張T1計(jì)數(shù)器de位數(shù),T1 為16位,74ls393為8位,擴(kuò)展后為24位,T1不溢出de話 最高可測(cè) 16.777216M ,溢出則累計(jì)中斷次數(shù)然后進(jìn)行累加即可。(另外添加74ls393進(jìn)行預(yù)分頻de目deshi為了解決T1引腳時(shí)鐘信號(hào)不宜大于單片機(jī)工作頻率de二分之一de問題)

目前測(cè)頻 4M 已經(jīng)成功通過(guò),由于沒有函數(shù)信號(hào)發(fā)生器,所以其他高頻還沒有做測(cè)試

PCB原理圖

/////////////////////////////以下為程序, 只有一個(gè)文件 main.c /////////////////////////////////

#include <avr/io.h>
#include <avr/iom8.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <stdio.h>

/*----------------------常用參數(shù)定義-------------------*/

#define P0 0
#define P1 1
#define P2 2
#define P3 3
#define P4 4
#define P5 5
#define P6 6
#define P7 7

#define FREQ 8
#define uint unsigned int
#define uchar unsigned char

/*----------------------某些端口操作-------------------*/

#define SET_DOOR PORTB|=_BV(P1)
#define CLR_DOOR PORTB&=~_BV(P1)

#define SET_CLEAR PORTB|=_BV(P2)
#define CLR_CLEAR PORTB&=~_BV(P2)

/*----------------------1602定義-------------------*/

#define SET_LCD_RS PORTD|=_BV(P2)
#define CLR_LCD_RS PORTD&=~_BV(P2)

#define SET_LCD_RW PORTD|=_BV(P3)
#define CLR_LCD_RW PORTD&=~_BV(P3)

#define SET_LCD_E PORTD|=_BV(P4)
#define CLR_LCD_E PORTD&=~_BV(P4)

#define SET_74LS595_SHIFT PORTB|=_BV(P0)
#define CLR_74LS595_SHIFT PORTB&=~_BV(P0)

#define SET_74LS595_DI PORTD|=_BV(P6)
#define CLR_74LS595_DI PORTD&=~_BV(P6)

#define SET_74LS595_CLK PORTD|=_BV(P7)
#define CLR_74LS595_CLK PORTD&=~_BV(P7)

void LCD_ON(void);     //啟動(dòng)LCD
void LongConvertToChar(unsigned long WD);
void LCDInit(void);
void WritEDAtaLCD(unsigned char WDLCD);
void WriteCommandLCD(unsigned char WCLCD);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y,unsigned char *DData);
void WritEDAtaTo595(unsigned char WDLCD);

const unsigned char Owner[] = {"Hello World !!!"};
const unsigned char uctech[] = {"INPUT FREQUENCE:"};
const unsigned char   Init[] = {"Initialization."};
unsigned char net[16] =         {"Axin & Cornsoup"};
unsigned char Net_Pointer=0;//net[] de指針

unsigned char Timer1_Counter_H=0;
unsigned char Timer1_Counter_L=0;
unsigned long Frequence=0;
unsigned char T2_OV_Time=1; //T2溢出對(duì)應(yīng)de時(shí)間
unsigned char T1_OV_Times=0; //T1溢出次數(shù)


/*----------------------串口定義-------------------*/

unsigned char SetPrintfConvertMode=0; //使用printf作其他轉(zhuǎn)換,并非輸出到UART

void Uart_Init(void);

int System_putchar(char c, FILE *stream);
int System_getchar(FILE *stream);

FILE mystd = FDEV_SETUP_STREAM(System_putchar, System_getchar,_FDEV_SETUP_RW);

/*----------------------常用函數(shù)定義------------------*/

void delay_nms(unsigned int ms)                //N ms延時(shí)函數(shù)
{
uint i;
for(i=0;i<ms;i++)
   _delay_loop_2(FREQ*250);
}

/*----------------------系統(tǒng)初始化函數(shù)定義------------------*/

void IO_INIT(void);


/////////////////////////////////////////////////////////////////


int main(void)
{
wdt_disable();
IO_INIT();
Uart_Init();
LCD_ON();                    //初始化 LCD1602 并顯示制作者信息
delay_nms(1500);
DisplayListChar(0, 0, uctech); //輸出英文 "Input Frequence:" 到LCD1602 第一行

DisplayListChar(0, 5, Init);    //顯示稍等

CLR_DOOR;                       //關(guān)閉閥門
_delay_loop_2(5);
SET_CLEAR;
_delay_loop_2(5);               //清空74ls393數(shù)據(jù)
CLR_CLEAR;

TCNT1H=0;
TCNT1L=0;                        //清空T1計(jì)數(shù)器

ASSR=_BV(AS2);                          //允許異步時(shí)鐘
TCCR2=_BV(CS22)|_BV(CS20);       
TCCR1B=_BV(CS12)|_BV(CS11);            //外部T1引腳輸入 下降沿有效 (一定要下降沿)
TIMSK=_BV(TOIE1)|_BV(TOIE2);           //允許溢出中斷

sei();

while(1);
}

/*----------------------系統(tǒng)初始化函數(shù)實(shí)體------------------*/

void IO_INIT(void)
{
DDRB|=0x0f;
PORTB&=0x0f;
DDRC|=0x00;
PORTC&=0x00;
DDRD|=0xdc;
PORTD&=0xdc;
}

/*----------------------系統(tǒng)中斷函數(shù)實(shí)體-----------------*/

ISR(TIMER1_OVF_vect) //定時(shí)器1溢出中斷
{
T1_OV_Times++;
}


ISR(TIMER2_OVF_vect) //定時(shí)器2溢出中斷
{
if(T2_OV_Time==2)
   {
    CLR_DOOR;

    Timer1_Counter_L=TCNT1L;   //讀取TCNT1數(shù)據(jù)要按照順序,先低8位后高8位
    Timer1_Counter_H=TCNT1H;
  
    Frequence=((unsigned long)Timer1_Counter_H<<16)|((unsigned long)Timer1_Counter_L<<8)|((PINC&0x3c)>>2)|((PINC&0x03)<<6)|(PINB&0x30);
   
    if(T1_OV_Times!=0)        //其實(shí)這個(gè)shi多余de,這里目deshi測(cè)量16.7M 以上de頻率 不過(guò)我們測(cè)量de頻率不可能達(dá)到這個(gè)
     {
      Frequence+=(unsigned long)0xffff*0xff*T1_OV_Times;
      T1_OV_Times=0;
     }
   
    //printf("\n\nTCNT1H: 0X%X TCNT1L: 0X%x",Timer1_Counter_H,Timer1_Counter_L);
    //printf("\nOverFlowTimes %d",T1_OV_Times);
   
    LongConvertToChar(Frequence);   //把Frequence 轉(zhuǎn)換后de數(shù)據(jù) 放到 net[]數(shù)組里面
    DisplayListChar(0, 5, net);     //把net[]de數(shù)據(jù)輸出到LCD
  
    SET_CLEAR;                  //一定要先把 74ls393 清零 再對(duì)TCNT1 清零
    _delay_loop_2(2);           //適當(dāng)延時(shí),其實(shí)可不要
    CLR_CLEAR;
    _delay_loop_2(2);
   
    TCNT1H=0x00;
    TCNT1L=0x00;   

    T2_OV_Time=1;             //啟動(dòng)下一次測(cè)量
   }
else
   {
    SET_DOOR;  
    T2_OV_Time=2;       
   }
}

/*----------------------LCD_1602函數(shù)實(shí)體------------------*/

void LCD_ON(void)
{
delay_nms(400); //啟動(dòng)等待,等LCD講入工作狀態(tài)
LCDInit(); //LCD初始化
delay_nms(100); //延時(shí)片刻(可不要)
DisplayListChar(0, 0, Owner);
DisplayListChar(0, 5, net);
}

void UsePrintfToConvert(unsigned long WD)   //利用 printf de轉(zhuǎn)換功能 爽! ^.^
{
SetPrintfConvertMode=1; //設(shè)置 printf 為自定義轉(zhuǎn)換模式
printf("%13ld Hz",WD);    //net[]數(shù)組總共有 16 個(gè)成員 與LCD1602de一行16個(gè)位對(duì)應(yīng)
SetPrintfConvertMode=0;   //還原 printf 為 Uart 輸出模式

/*---------為輸出數(shù)據(jù)添加逗號(hào) 999,999,999 ------------*/


    net[2]=net[4];
net[3]=net[5];
net[4]=net[6];
if(net[2]!= ||net[3]!= ||net[4]!= )
{
   if(net[4]!=-)
    {
     net[5]=,;
    }
}
net[6]=net[7];
net[7]=net[8];
net[8]=net[9];
if(net[6]!= ||net[7]!= ||net[8]!= )
{
   if(net[8]!=-)
    {
    net[9]=,;
    }
}
}

void LongConvertToChar(unsigned long WD)
{
UsePrintfToConvert(WD);
}

void WritEDAtaTo595(unsigned char WDLCD) // 74hc595 串行轉(zhuǎn)并行輸出
{
unsigned char i;
CLR_74LS595_CLK;
for(i=0;i<8;i++)
   {
    CLR_74LS595_SHIFT;
    if(WDLCD&0x01)
     {
      SET_74LS595_DI;
     }
    else
     {
      CLR_74LS595_DI;
     }
    WDLCD>>=1;
    SET_74LS595_SHIFT;
   }
_delay_loop_2(1);
SET_74LS595_CLK;
}

//寫數(shù)據(jù)
void WritEDAtaLCD(unsigned char WDLCD)
{
delay_nms(1);//適當(dāng)加延時(shí),避免 LCD1602 繁忙
WritEDAtaTo595(WDLCD);
SET_LCD_RS;
CLR_LCD_RW;
CLR_LCD_E; //若晶振速度太高可以在這后加小de延時(shí)
_delay_loop_2(1);
SET_LCD_E;
}

//寫指令
void WriteCommandLCD(unsigned char WCLCD)
{
delay_nms(1);//適當(dāng)加延時(shí),避免 LCD1602 繁忙
WritEDAtaTo595(WCLCD);
CLR_LCD_RS;
CLR_LCD_RW;
CLR_LCD_E;
_delay_loop_2(1);
SET_LCD_E;
}


void LCDInit(void) //LCM初始化
{
WritEDAtaTo595(0);
WriteCommandLCD(0x38); //三次顯示模式設(shè)置,不檢測(cè)忙信號(hào)
delay_nms(15);
WriteCommandLCD(0x38);
delay_nms(5);
WriteCommandLCD(0x38);
delay_nms(5);

WriteCommandLCD(0x38); //顯示模式設(shè)置,開始要求每次檢測(cè)忙信號(hào)
WriteCommandLCD(0x08); //關(guān)閉顯示
WriteCommandLCD(0x01); //顯示清屏
WriteCommandLCD(0x06); // 顯示光標(biāo)移動(dòng)設(shè)置
WriteCommandLCD(0x0C); // 顯示開及光標(biāo)設(shè)置
}

//按指定位置顯示一個(gè)字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //當(dāng)要顯示第二行時(shí)地址碼+0x40;
X |= 0x80; // 算出指令碼
WriteCommandLCD(X); //這里不檢測(cè)忙信號(hào),發(fā)送地址碼
WritEDAtaLCD(DData);
}

//按指定位置顯示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
{
unsigned char ListLength;

ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>=0x20) //若到達(dá)字串尾則退出
{
   if (X <= 0xF) //X坐標(biāo)應(yīng)小于0xF
    {
     DisplayOneChar(X, Y, DData[ListLength]); //顯示單個(gè)字符
     ListLength++;
     X++;
    }
}
}

/*----------------------串口函數(shù)實(shí)體------------------*/


void Uart_Init(void)
{
UCSRB=_BV(RXEN)|_BV(TXEN);
UBRRL=51;  
stdout=&mystd;
stdin=&mystd;
}

int System_putchar(char c, FILE *stream)
{
if(SetPrintfConvertMode==1)
{
   net[Net_Pointer]=c;
   Net_Pointer++;
   if(Net_Pointer>=16)
   {
    Net_Pointer=0;
   }
  
}
else
{
   if (c == \n)
   System_putchar(\r, stream);
   loop_until_bit_is_set(UCSRA, UDRE);
   UDR = c;
}

return 0;
}


int System_getchar( FILE *stream)
{
loop_until_bit_is_set(UCSRA,RXC);
return UDR;
}

  • 上一篇: ATmega128實(shí)現(xiàn)一個(gè)工業(yè)設(shè)備的主控制板
  • 下一篇: 沒有了
  • 發(fā)表評(píng)論   告訴好友   打印此文  收藏此頁(yè)  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評(píng)論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對(duì)此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請(qǐng)聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國(guó)行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營(yíng)許可證:浙B2-20080178-1