标题:
基于MSP430G2553单片机的简易频率计程序(1Hz-60KHz)
[打印本页]
作者:
曾今何在cjhz
时间:
2019-5-21 21:56
标题:
基于MSP430G2553单片机的简易频率计程序(1Hz-60KHz)
一个简易频率计,
通过定时器
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
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1