找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3438|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

基于MSP430G2553的頻率計(jì)設(shè)計(jì)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:435817 發(fā)表于 2019-3-18 17:41 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
數(shù)字式頻率計(jì)
一、設(shè)計(jì)概述
在電子技術(shù)中,頻率是最基本的參數(shù)之一,數(shù)字頻率計(jì)具有精度高、使用方便、測(cè)量迅速、以及便于實(shí)現(xiàn)測(cè)量過(guò)程自動(dòng)化等優(yōu)點(diǎn),是近代電子技術(shù)領(lǐng)域的重要工具之一,在許多領(lǐng)域得到廣泛應(yīng)用。本系統(tǒng)以超低功耗MSP430G2553單片機(jī)為核心處理芯片來(lái)測(cè)量信號(hào)的頻率,通過(guò)定時(shí)器A采用計(jì)數(shù)法完成信號(hào)頻率測(cè)量,并將被測(cè)頻率值通過(guò)LCD12864液晶串行顯示。頻率可測(cè)量范圍在1Hz到999MHz之間。如需要,范圍可繼續(xù)擴(kuò)寬,頻率計(jì)的誤差在1%以?xún)?nèi)。
二、原理圖
基于MSP430G2553的頻率計(jì)設(shè)計(jì)原理圖如圖1所示,通過(guò)串口方式液晶顯示,只需配置單片機(jī)三個(gè)口線(xiàn)便可以實(shí)現(xiàn)對(duì)頻率的測(cè)量。其中待測(cè)頻率信號(hào)從P1.0口輸入,然后可以直接在液晶屏上顯示。

三、引腳說(shuō)明
(一)MSP430G2553引腳功能說(shuō)明
由原理圖可以看出,430單片機(jī)的最小系統(tǒng)用到1腳電源、16腳復(fù)位端、20腳接地端、配置P1.0口為待測(cè)信號(hào)輸入端,P1.4為串行數(shù)據(jù)輸出口,P1.5為串行時(shí)鐘輸出口,如表1所示。
表1  MSP430G2553引腳功能說(shuō)明

   
(二)LCD12864引腳功能說(shuō)明
LCD12864液晶顯示屏用到1、2腳,電源接口線(xiàn),19、20腳背光電源接口線(xiàn),15腳并行/串行接口選擇,5腳串行數(shù)據(jù)口,6腳串行的同步時(shí)鐘。LCD12864引腳功能如表2所示。
表2  LCD12864接口說(shuō)明

   
四、軟件設(shè)計(jì)流程圖
系統(tǒng)軟件設(shè)計(jì)包括初始化模塊、中斷模塊和信號(hào)頻率顯示模塊。
(一)主函數(shù)

主函數(shù)流程圖如圖2所示。在主程序中,主要對(duì)單片機(jī)配置進(jìn)行初始化和屏幕初始化,以及頻率信號(hào)數(shù)據(jù)的處理并實(shí)時(shí)顯示。
(二)單片機(jī)初始化函數(shù)

單片機(jī)初始化函數(shù)包括對(duì)看門(mén)狗定時(shí)器模式的設(shè)置、I/O口輸入/輸出功能的配置。定時(shí)器A所需時(shí)鐘源、分頻系數(shù)的選擇,并將總中斷打開(kāi)。函數(shù)流程圖如圖3所示。
(三)中斷函數(shù)

中斷函數(shù)流程圖如圖4所示。當(dāng)定時(shí)器A溢出后就進(jìn)入中斷,count就加上65535。
(四)頻率顯示函數(shù)
頻率顯示流程圖如圖5所示。頻率顯示函數(shù)包含對(duì)定時(shí)器A相關(guān)內(nèi)容的操作,將定時(shí)器A計(jì)數(shù)寄存器內(nèi)容清零后,設(shè)置定時(shí)器A的工作模式,產(chǎn)生1s 計(jì)數(shù)閘門(mén),關(guān)閉定時(shí)器A,記下count的值即為所測(cè)得頻率的大小。最后根據(jù)數(shù)據(jù)的大小,按不同的單位將數(shù)據(jù)通過(guò)12864液晶顯示屏串行顯示出來(lái)。

五、程序源代碼
/***************************************************************
基于定時(shí)器A,采用計(jì)數(shù)法完成信號(hào)頻率的測(cè)量
使用片內(nèi)時(shí)鐘DOC,時(shí)鐘頻率默認(rèn)值
采用12864串行顯示
頻率測(cè)量范圍:1Hz -- MHz(只要需要,范圍可以繼續(xù)擴(kuò)寬,誤差在1%以?xún)?nèi))
被測(cè)信號(hào)輸入管腳P1.0
WR數(shù)據(jù)引腳    P1.4
SCLK模擬時(shí)鐘引腳   P1.5
PSB串行/并行選擇引腳  接GND
*****************************************************************/
#include<msp430g2553.h>
#define uint unsigned int
#define uchar unsigned char
#define ulint unsigned long int
ulint count=0;
void delay(uint t);
void delay1(void);
void int_430(void);
void sendbyte(uchar zdata);
void write_com(uchar cmdcode);
void write_data(uchar Dispdata);
void lcdinit();
void print_string( char *s);
void display(void);
/*************主函數(shù)************/
void main()
{
int_430();
lcdinit();
while(1)
  {
   display();
    count=0;
  }
}
/*************延時(shí)函數(shù)************/
void delay(uint t)
{
  uinti,j;
for(i=0;i<t;i++)
   for(j=0;j<10;j++);
}
//1s延時(shí)的計(jì)數(shù)閘門(mén)
void delay1(void)
{
unsigned long i;
for(i=0;i<119000;i++)
  {
   _NOP();   // 該函數(shù)用來(lái)產(chǎn)生一個(gè) MSP430 系統(tǒng)時(shí)鐘周期的延時(shí)
  }
}
/*************430初始化函數(shù)************/
void int_430(void)
{
WDTCTL=WDTPW+WDTHOLD;   // 關(guān)閉看門(mén)狗
P1SEL&=~BIT4;
P1DIR|= BIT4;
P1OUT&=~BIT4;
P1SEL&=~BIT5;
P1DIR|= BIT5;
P1OUT&=~BIT5;
P1SEL|=BIT0;        // 設(shè)置 P1.0 為 TimerA 外部計(jì)數(shù)信號(hào)輸入口
P1DIR&=~BIT0;      // 設(shè)置 P1.0 為輸入口
  //TimerA 配置
TACTL=TASSEL_0;   // 定時(shí)器 A 時(shí)鐘源選擇:TACLK
TACTL=ID_3;        // 計(jì)數(shù)時(shí)鐘分頻系數(shù)選擇:1
  CCTL0= CCIE;       //開(kāi)中斷
  CCR0= 65535;
_EINT();
}
/*************數(shù)據(jù)傳送函數(shù)************/
void sendbyte(uchar zdata)
{
  ucharcode_seg7,serial_clk, serial_shift;
code_seg7=zdata;
serial_shift=0x80;
for(serial_clk=0; serial_clk<8; serial_clk++)
  {
   if(code_seg7&serial_shift)
    {
     P1OUT|=BIT4;    //SID為1
    }
   else
    {
     P1OUT&=~BIT4;   //SID為0
    }
   P1OUT&=~BIT5;     //產(chǎn)生時(shí)鐘信號(hào)下沿
   P1OUT|=BIT5;       //產(chǎn)生時(shí)鐘信號(hào)上沿
   serial_shift=serial_shift>>1;  //準(zhǔn)備發(fā)送下一位數(shù)據(jù)
  }
}
/*************寫(xiě)命令函數(shù)************/
void write_com(uchar cmdcode)
{                   //串口控制格式(11111AB0)
                       //A數(shù)據(jù)方向控制,A=H時(shí)讀,A=L時(shí)寫(xiě)
                   //B數(shù)據(jù)類(lèi)型選擇,B=H時(shí)為顯示數(shù)據(jù),B=L時(shí)為命令
sendbyte(0xf8);     //MCU向LCD發(fā)命令
sendbyte(cmdcode & 0xf0);         //發(fā)高四位數(shù)據(jù)(數(shù)據(jù)格式D7D6D5D4_0000)
sendbyte((cmdcode << 4) & 0xf0);    //發(fā)低四位數(shù)據(jù)(數(shù)據(jù)格式D3D2D1D0_0000)
delay(2);   //延時(shí)等待
}
/*************寫(xiě)數(shù)據(jù)函數(shù)************/
void write_data(uchar Dispdata)
{
sendbyte(0xfa);            //MCU向LCD發(fā)數(shù)據(jù)
sendbyte(Dispdata & 0xf0);   //發(fā)高四位數(shù)據(jù)
sendbyte((Dispdata << 4) & 0xf0);   //發(fā)低四位數(shù)據(jù)
delay(2);
}
/*************LCD初始化函數(shù)************/
void lcdinit()
{
delay(20000);       //復(fù)位等待(內(nèi)部自帶上電復(fù)位電路),時(shí)間較長(zhǎng)
write_com(0x30);    //功能設(shè)定:基本指令集操作
delay(50);          //延時(shí)等待
write_com(0x0c);    //整體顯示,關(guān)游標(biāo)
delay(50);
}
/*************送字符串函數(shù)************/
void print_string( char *s)
{
while(*s > 0)       //C語(yǔ)言里字符串末尾自動(dòng)加“\0”(ASCII碼值為0)
  {
    delay(50);
   write_data(*s);   //發(fā)送字符對(duì)應(yīng)的ASCII碼,12864指針可設(shè)置自動(dòng)指向下一個(gè)顯示地址
   s++;
  }
}
/*************頻率顯示函數(shù)************/
void display(void)
{
  ulinta1,a2,a3,a4,a5,a6,a7,a8,a9;   // 聲明計(jì)數(shù)數(shù)據(jù)變量
TAR=0x0000;        // 定時(shí)器 A 計(jì)數(shù)寄存器內(nèi)容清零
TACTL=MC_2;      // 定時(shí)器 A 工作模式選擇:連續(xù)模式
delay1();            // 產(chǎn)生 1s 計(jì)數(shù)閘門(mén)
TACTL=MC_0;     // 定時(shí)器 A 工作模式選擇:停止模式
  count+=TAR;
write_com(0x01);    //清屏指令
if(count>=1000000)
  {
   a1=count/100000000;
   a2=count%100000000/10000000;
   a3=count%100000000%10000000/1000000;
   a4=count%100000000%10000000%1000000/100000;
   a5=count%100000000%10000000%1000000/100000;
   a6=count%100000000%10000000%1000000%100000/10000;
   a7=count%100000000%10000000%1000000%100000%10000/1000;
   a8=count%100000000%10000000%1000000%100000%10000%1000/100;
   a9=count%100000000%10000000%1000000%100000%10000%1000%100/10;
   write_com(0x03);
   write_com(0x80);       //第一行首地址0x80
   print_string("德州儀器MSP430 ");    //第一行顯示(必須加一個(gè)空格否則不能下載)
   write_com(0x90);
   print_string("頻率: ");
    write_com(0x93);       //第二行首地址0x90,從第四個(gè)開(kāi)始顯示
   write_data(a1+0x30);    //發(fā)送dat1的ASCII碼,顯示dat1的值
   write_data(a2+0x30);    //發(fā)送dat1的ASCII碼,顯示dat2的值
   write_data(a3+0x30);    //發(fā)送dat1的ASCII碼,顯示dat3的值
   write_data('.');          //發(fā)送"."
   write_data(a4+0x30);    //發(fā)送dat1的ASCII碼,顯示dat4的值
   write_data(a5+0x30);    //發(fā)送dat1的ASCII碼,顯示dat5的值
   write_data(a6+0x30);    //發(fā)送dat1的ASCII碼,顯示dat6的值
   write_data(a7+0x30);    //發(fā)送dat1的ASCII碼,顯示dat7的值
   write_data(a8+0x30);    //發(fā)送dat1的ASCII碼,顯示dat8的值
    write_data(a9+0x30);    //發(fā)送dat1的ASCII碼,顯示dat9的值
   write_com(0x88);
   print_string("單位: ");
   write_data('M');        //發(fā)送H的ASCII碼,顯示M
   write_data('H');        //發(fā)送H的ASCII碼,顯示H
   write_data('z');        //發(fā)送z的ASCII碼,顯示z;
   delay(500);
  }
  else
  {
   if(count>=1000)
    {
     a1=count/100000;
     a2=count%100000/10000;
     a3=count%100000%10000/1000;
     a4=count%100000%10000%1000/100;
     a5=count%100000%10000%1000/100;
     a6=count%100000%10000%1000%100%10;
     write_com(0x03);
     delay(50);    //延時(shí)
     // 讀定時(shí)器 A 計(jì)數(shù)寄存器內(nèi)容
     write_com(0x80);    //第一行首地址0x80
     print_string("德州儀器MSP430 ");    //第一行顯示(必須加一個(gè)空格否則不能下載)
     write_com(0x90);
     print_string("頻率: ");
     write_com(0x94);    //第二行首地址0x90,從第四個(gè)開(kāi)始顯示
      write_data(a1+0x30);    //發(fā)送dat1的ASCII碼,顯示dat1的值
     write_data(a2+0x30);    //發(fā)送dat1的ASCII碼,顯示dat2的值
     write_data(a3+0x30);    //發(fā)送dat1的ASCII碼,顯示dat3的值
     write_data('.');          //發(fā)送"."
     write_data(a4+0x30);    //發(fā)送dat1的ASCII碼,顯示dat4的值
      write_data(a5+0x30);    //發(fā)送dat1的ASCII碼,顯示dat5的值
     write_data(a6+0x30);    //發(fā)送dat1的ASCII碼,顯示dat6的值
     write_com(0x88);
     print_string("單位: ");
     write_data('K');    //發(fā)送H的ASCII碼,顯示K
     write_data('H');    //發(fā)送H的ASCII碼,顯示H
     write_data('z');     //發(fā)送z的ASCII碼,顯示z
     delay(500);        //較長(zhǎng)時(shí)間延時(shí),保證下次操作前LCD完成上述功能處于非忙狀態(tài)
    }
   else
    {
     count*=1000;
     a1=count/100000;
     a2=count%100000/10000;
     a3=count%100000%10000/1000;
     a4=count%100000%10000%1000/100;
      a5=count%100000%10000%1000/100;
     a6=count%100000%10000%1000%100%10;
     write_com(0x03);
     delay(50);          //延時(shí)
     // 讀定時(shí)器 A 計(jì)數(shù)寄存器內(nèi)容
     write_com(0x80);    //第一行首地址0x80
     print_string("德州儀器MSP430 ");    //第一行顯示(必須加一個(gè)空格否則不能下載)
     write_com(0x90);
     print_string("頻率: ");
     write_com(0x94);       //第二行首地址0x90,從第四個(gè)開(kāi)始顯示
     write_data(a1+0x30);    //發(fā)送dat1的ASCII碼,顯示dat1的值
     write_data(a2+0x30);    //發(fā)送dat1的ASCII碼,顯示dat2的值
     write_data(a3+0x30);    //發(fā)送dat1的ASCII碼,顯示dat3的值
     write_data('.');          //發(fā)送"."
     write_data(a4+0x30);    //發(fā)送dat1的ASCII碼,顯示dat4的值
     write_data(a5+0x30);    //發(fā)送dat1的ASCII碼,顯示dat5的值
     write_data(a6+0x30);    //發(fā)送dat1的ASCII碼,顯示dat6的值
     write_com(0x88);
     print_string("單位: ");
     write_data('H');    //發(fā)送H的ASCII碼,顯示H
     write_data('z');    //發(fā)送z的ASCII碼,顯示z
     delay(500);       //較長(zhǎng)時(shí)間延時(shí),保證下次操作前LCD完成上述功能處于非忙狀態(tài)
    }
  }
}
#pragma vector = TIMER0_A0_VECTOR   //Timer_A中斷向量
__interrupt void Tiemr_A(void)
{
  count+=65535;
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:336842 發(fā)表于 2019-4-12 09:48 | 只看該作者
大俠跪求proteus圖啊啊啊
回復(fù)

使用道具 舉報(bào)

板凳
ID:498097 發(fā)表于 2019-6-3 19:53 | 只看該作者
學(xué)習(xí)了,謝謝樓主
回復(fù)

使用道具 舉報(bào)

地板
ID:584195 發(fā)表于 2021-8-17 09:18 | 只看該作者
寫(xiě)得非常好!給你點(diǎn)贊~
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表