一個簡易頻率計,通過定時器A采用計數法完成信號頻率測量,并將被測頻率值通過LCD12864液晶串行顯示。頻率可測量范圍在1Hz到60KHz之間。
11111.jpg (423.27 KB, 下載次數: 95)
下載附件
2019-5-21 21:55 上傳
單片機源程序如下:
- /*
- * 頭文件
- */
- #include<msp430g2553.h>
- #include "stdio.h"
- /*
- * 全局變量的定義和宏定義
- */
- unsigned int start,end;
- unsigned long int F = 0;
- unsigned char TA_overflow;
- unsigned int TA_i = 0;
- unsigned int port_i;
- unsigned chartab[]={"0123456789"};
- unsigned char a[8];
- unsigned char int_to_string[10];
- unsigned char int_array[10];
- #define uchar unsigned char
- #define uint unsigned int
- #define CS_0 P2OUT &= ~BIT0 //片選為低電平
- #define CS_1 P2OUT |= BIT0 //片選為高電平
- #define SID_0 P2OUT &= ~BIT1 //串行數據輸入為0
- #define SID_1 P2OUT |= BIT1 //串行數據輸入為1
- #define SCLK_0 P2OUT &= ~BIT2 //時鐘線拉低
- #define SCLK_1 P2OUT |= BIT2 //時鐘線拉高
- #define PSB_0 P2OUT &= ~BIT3 //出行輸入
- #define LCD_DIR_OUT P2DIR |= BIT0 + BIT1 + BIT2 + BIT3 //4個端口設置為輸出
-
- /********************************************************************
- * 名稱 : SendByte
- * 功能 : 發送數據
- * 輸入 : Dbyte
- * 輸出 : 無
- ***********************************************************************/
-
- void SendByte(uchar Dbyte)
- {
- uchari;
- LCD_DIR_OUT;
- for(i= 0;i < 8;i++)
- {
- if((Dbyte<< i) & 0x80)
- {
- SID_1;
- }
- else
- {
- SID_0;
- }
- SCLK_0;
- _delay_cycles(2);
- SCLK_1;
- }
- }
-
- /********************************************************************
- * 名稱 : Write_Instruction
- * 功能 : 向LCD寫指令
- * 輸入 : data
- * 輸出 : 無
- ***********************************************************************/
- void Write_Instruction(uchar data)
- {
- LCD_DIR_OUT;
- CS_1;
- SendByte(0xf8);
- SendByte(data& 0xf0);
- SendByte((data<< 4) & 0xf0);
- _delay_cycles(20);
- }
-
- /********************************************************************
- * 名稱 : Write_Data
- * 功能 :向LCD寫入數據
- * 輸入 : data
- * 輸出 : 無
- ***********************************************************************/
- void Write_Data(uchar data)
- {
- LCD_DIR_OUT;
- CS_1;
- SendByte(0xfa);
- SendByte(data& 0xf0);
- SendByte((data<< 4) & 0xf0);
- _delay_cycles(20);
- }
-
- /********************************************************************
- * 名稱 : LCD12864_Delay()
- * 功能 : 初始化LCD12864
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void LCD_Init()
- {
- LCD_DIR_OUT; //設置輸入方向為輸出
- PSB_0; //LCD為串行輸入方式
- Write_Instruction(0x30); //基本指令集
- _delay_cycles(10000);
- Write_Instruction(0x02); //地址歸位
- _delay_cycles(10000);
- Write_Instruction(0x0c); //整體顯示打開,游標關閉
- _delay_cycles(10000);
- Write_Instruction(0x01); //清除顯示
- _delay_cycles(10000);
- Write_Instruction(0x06); //游標右移
- _delay_cycles(10000);
- Write_Instruction(0x80); //設定顯示的起始地址
- _delay_cycles(10000);
- }
-
- /********************************************************************
- * 名稱 : Write_Pos
- * 功能 : 確定輸入數據的位置
- * 輸入 : x,y
- * 輸出 : 無
- ***********************************************************************/
- void Write_Pos(uchar x,uchar y)
- {
- uchar pos;
- if(x == 1) //第一行顯示
- x = 0x80;
- else if(x == 2) //第二行顯示
- x = 0x90;
- else if(x == 3) //第三行顯示
- x = 0x88;
- else if(x == 4) //第四行顯示
- x = 0x98;
- pos = x + y-1;
- Write_Instruction(pos);//顯示地址
- }
-
- /********************************************************************
- * 名稱 : Write_Word_To_12864
- * 功能 : 在坐標x,y處寫入數據
- * 輸入 : x,y,*word
- * 輸出 : 無
- ***********************************************************************/
- void Write_Word_To_12864(uchar x,uchary,uchar *word)
- {
- uchari;
- LCD_Init();
- Write_Pos(x,y);
- for(i= 0;*(word+i)!='\0';i++)
- {
- Write_Data(word[i]);
- }
- }
-
- void ShowInit()
- {
- Write_Word_To_12864(1,1,"頻率計:");
- _delay_cycles(50000);
- Write_Pos(2,7);
- Write_Data('H');
- Write_Data('z');
- _delay_cycles(10000);
- }
-
- void ShowF()
- {
- Write_Pos(2,4);
-
- if(F>= 100000)
- {
- Write_Data(tab[F/100000]);
- Write_Data(tab[F%100000/10000]);
- Write_Data(tab[F%10000/1000]);
- Write_Data(tab[F%1000/100]);
- Write_Data(tab[F%100/10]);
- Write_Data(tab[F%10]);
- _delay_cycles(1000);
- }
- elseif(F >= 10000)
- {
- Write_Data(tab[F/10000]);
- Write_Data(tab[F%10000/1000]);
- Write_Data(tab[F%1000/100]);
- Write_Data(tab[F%100/10]);
- Write_Data(tab[F%10]);
- _delay_cycles(1000);
- }
- elseif(F >= 1000)
- {
- Write_Data(tab[F/1000]);
- Write_Data(tab[F%1000/100]);
- Write_Data(tab[F%100/10]);
- Write_Data(tab[F%10]);
- _delay_cycles(1000);
- }
- elseif(F >= 100)
- {
- Write_Data(tab[F/100]);
- Write_Data(tab[F%100/10]);
- Write_Data(tab[F%10]);
- _delay_cycles(1000);
- }
- elseif(F >= 10)
- {
- Write_Data(tab[F/10]);
- Write_Data(tab[F%10]);
- _delay_cycles(1000);
- }
- else
- {
- Write_Data(tab[F]);
- _delay_cycles(1000);
- }
- }
- /********************************************************************
- * 名稱 : Init_uart0
- * 功能 : 初始化串口
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Init_uart0()
- {
- UCA0CTL1|=UCSWRST; //UCA0軟件復位
- //UCA0CTL0&=~UC7BIT;//字符長度為8
- UCA0CTL1|=UCSSEL_2;//選擇系統時鐘:SMCLK
- UCA0BR0=0x6D; //波特率為9600
- UCA0BR1=0;
- UCA0MCTL=0;//UCA0MCTL=UCBRS0;
- IE2=UCA0RXIE+UCA0TXIE;//開接收使能
- UCA0CTL1&=~UCSWRST;
- P1SEL|=BIT1+BIT2; //將P1.1 P1.2設為第二功能
- P1SEL2|=BIT1+BIT2;
- }
-
- /********************************************************************
- * 名稱 : Uart0Sends
- * 功能 : 串口發送數據
- * 輸入 : *s
- * 輸出 : 無
- ***********************************************************************/
- void Uart0SendsData(char *s)
- {
- while(*s!='\0')
- {
- UCA0TXBUF=*s;
- while((IFG2&UCA0TXIFG)==0); //查詢發送是否結束
- IFG2&=~UCA0TXIFG; //清除發送一標志位
- s++;
- }
- }
-
-
- /********************************************************************
- * 名稱 : Init_In
- * 功能 :初始化外部終端
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Init_In()
- {
- P1DIR|= BIT6;
- P1DIR&= ~BIT3;
- P1IES|= BIT3;
- P1IE|= BIT3;
- P1IFG&= ~BIT3;
- _EINT();
- }
-
-
- void Init_Timer()
- {
- TACCTL0 = CCIE; // CCR0 interruptenabled
- TACCR0 = 1;
- TACTL = TASSEL_1 + MC_1 + TAIE + TACLR; //up mode
- }
-
- /********************************************************************
- * 名稱 : Int_To_String
- * 功能 :將一個int型數據轉換為String型
- * 輸入 : now_f
- * 輸出 : 無
- ***********************************************************************/
- void Int_To_String(unsigned long int now_f)
- {
- intj = 0;
- for(j= 0; ;j++)
- {
- int_array[j]= now_f % 10 + 48 ;
- now_f= now_f / 10;
- if(now_f== 0) break;
- }
- inti = j ;
- for(i= j , j = 0; i >= 0; i--,j++)
- {
- int_to_string[j]= int_array[i];
- }
- }
- void main()
- {
- WDTCTL= WDTPW + WDTHOLD;
- P1DIR |= BIT7; // P1.0 output
- P1DIR |= BIT0;
-
- if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
- {
- while(1); // Ifcalibration constants erased
- // do not load, trap CPU!!
- }
- //1Mhz
- BCSCTL1 = CALBC1_1MHZ; // Set range
- DCOCTL = CALDCO_1MHZ; // Set DCO step +modulation */
-
-
- LCD_Init();
- Init_In();
- Init_Timer();
- Init_uart0();
- ShowInit();
- while(1)
- {
- ShowF();
- }
- }
- #pragma vector=PORT1_VECTOR
- __interrupt void port_1()
- {
-
- if(P1IFG& BIT3)
- {
- P1OUT^= BIT6;
- port_i++;
- if(port_i>=100)
- {
- port_i= 0;
- F=(unsigned long int)((1000000*100.0)/((TA_overflow*65536)+TAR));
- TA_overflow= 0;
- TACTL|= TACLR;
- }
- }
- P1IFG&= ~BIT3;
- }
-
- // Timer A0 interrupt service routine
- #pragma vector=TIMER0_A0_VECTOR
- __interrupt void Timer_A (void)
- {
- P1OUT^= BIT7;
- TA_i++;
- if(TA_i== 2000)
- {P1OUT^= BIT0;
- TA_i= 0;
- Int_To_String(F);
- unsignedchar *s = int_to_string;
- Uart0SendsData(s);
- Uart0SendsData("1000");
- }
- }
-
-
- #pragma vector=TIMER0_A1_VECTOR
- __interrupt void Timer_A1()
- {
- switch(TA0IV)
- {
- case2:break;
- case4:break;
- case10:TA_overflow++;break;
- }
- }
-
- /********************************************************************
- * 名稱 : usart0_rx
- * 功能:串口中斷入口
- ***********************************************************************/
- #pragma vector=USCIAB0RX_VECTOR
- __interrupt void usart0_rx(void)
- {
- while((IFG2&UCA0RXIFG)==0);
- //a=RXBUF0;
- //i++;
- a[0]=UCA0RXBUF;
- }
復制代碼
基于MSP430G2553的簡易頻率計.docx
(1.11 MB, 下載次數: 44)
2019-5-21 21:53 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|