#include<msp430.h>
#include"HAL_Dogs102x6.h"

char CharCode[10]={"0123456789"};
volatile unsigned int OneSecondFlag=0;	//定时1S标志
volatile unsigned int HInputWorkFlag=0;//高频待测信号工作状态标志   0：第一个上升沿
volatile unsigned long int HInputOverflowTime=0;//高频待测信号计数溢出次数
volatile unsigned int HROverflowTime=0;//高频基准信号计数溢出次数
volatile unsigned long int HInputNum=0;	//高频输入信号计数值
volatile unsigned long int HReferenceNum=0;//高频基准信号计数值
volatile unsigned int IsHighFrequenceFlag=1;//判断是否为高频标志位
volatile unsigned int HighFrequenceWaitFlag=1;//高频测量等待标志位

void UCSSet1();//ACLK设置，32.768KHZ
void UCSSet2();//MCLK,SMCLK设置，4MHZ
void IOInit();//IO引脚初始化
void TAInit1();//高频预测量定时器设置
void HFMeasure();//高频测量核心函数
void Display1();//高频结果显示函数
void ParameterInit();//参数初始化
void DelayMs(unsigned int i);

void main(void)
{
	WDTCTL=WDTPW+WDTHOLD;//关闭看门狗

	P1DIR|=BIT5+BIT1+BIT2+BIT3+BIT4;
	UCSSet1();
	UCSSet2();
	IOInit();
	Dogs102x6_init();//液晶屏初始化
	Dogs102x6_backlightInit();//背光度初始化
	Dogs102x6_setBacklight(11);
	Dogs102x6_setContrast(11);
	Dogs102x6_clearScreen();//清屏

	while(1)
	{
		ParameterInit();
		TAInit1();
		__enable_interrupt();//开启总中断
		HFMeasure();
		__disable_interrupt();
		if(IsHighFrequenceFlag==1)
		Display1();
		/*测试用*/
		//P1OUT^=BIT1;
	}
}

/*交互接口引脚设置*/
void IOInit()
{
	/*P2.0捕获器的输入设置*/
	//P2DIR&=~BIT0;
	//P2IN&=~BIT0;
	//P2IES&=~BIT0;	//上升沿触发
	//P2OUT&=~BIT0;
	//P2REN|=BIT0;	//配置下拉电阻
	P2SEL|=BIT0;	//声明作为TA1的捕获器1的输入

	/*P1.0中断触发设置*/
	//P1DIR&=~BIT0;	//P1.0设定为输入方向
	//P1IN&=~BIT0;	//输入初始为0
	//P1IES&=~BIT0;	//上升沿触发
	//P1OUT&=~BIT0;
	//P1REN|=BIT0;	//配置下拉电阻
	P1SEL|=BIT0;//声明P1.0将用作TA0CLK

}
/*时钟设置*/

void UCSSet1()
{
	  //P1DIR |= BIT0;                            // ACLK输出
	  //P1SEL |= BIT0;

	  P5SEL |= BIT4+BIT5;                       // 选择 XT1

	  UCSCTL6 &= ~(XT1OFF);                     // XT1开
	  UCSCTL6 |= XCAP_3;                        // 配置XT1电容
	  UCSCTL3 = 0;                              // FLL Reference Clock = XT1

	  do
	  {
	    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);// 清除XT2,XT1,DCO错误标志

	    SFRIFG1 &= ~OFIFG;
	  }while (SFRIFG1&OFIFG);

	  UCSCTL6 &= ~(XT1DRIVE_3);                 // Xtal is now stable, reduce drive strength
	  UCSCTL4 = SELA_0;
}

void UCSSet2()
{
	  P2DIR |= BIT2;                            // SMCLK输出
	  P2SEL |= BIT2;
	  P7DIR |= BIT7;                            // MCLK输出
	  P7SEL |= BIT7;

	  P5SEL |= BIT2+BIT3;                       // 选择XT2

	  UCSCTL6 &= ~XT2OFF;                       // 打开XT2
	  UCSCTL3 |= SELREF_2;                      // FLL基准选择
	  UCSCTL4 |= SELA_2;                        // ACLK=REFO,SMCLK=DCO,MCLK=DCO
	  do										//直到振荡稳定
	  {
	    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
	                                            // 清除XT2,XT1,DCO错误标志
	    SFRIFG1 &= ~OFIFG;
	  }while (SFRIFG1&OFIFG);
	  UCSCTL6 &= ~XT2DRIVE0;                    // 降低驱动
	  UCSCTL4 |= SELS_5 + SELM_5;               // SMCLK=MCLK=XT2
	}

void TAInit1()			//高频预测量定时器设置
{
	/*TB0设定1S间隔*/
	TB0CTL|=MC_0;		//关闭定时器
	TB0CTL|=TBCLR;		//计数器TA2清零
	TB0CCR0=32767;	//比较模式对比数值
	TB0CCTL0|=CCIE;		//CCRO比较中断使能
	TB0CTL|=TBSSEL_1+ID_0;//选择ACLK时钟32.768KHZ，初级1分频,关闭TA2IFG中断
	TB0EX0=TBIDEX_0;//二级1分频

	/*TA0设定待测信号计数*/
	TA0CTL|=MC_0;		//关闭定时器
	TA0CTL|=TACLR;		//计数器TA0清零
	TA0CCR0=100;	//比较模式对比数值
	TA0CCTL0|=CCIE;		//CCRO比较中断使能
	TA0CTL|=TASSEL_0+ID_1;//选择TA0CLK，即待测信号，初级2分频,关闭TA0IFG中断
	TA0EX0=TAIDEX_4;//二级5分频，总共为10分频

	/*TA1标准信号计数*/
	TA1CTL|=MC_0;		//关闭定时器
	TA1CTL|=TACLR;		//计数器TA1清零
	TA1CTL|=TASSEL_2+ID_0+TAIE;//选择SMCLK4MHZ，初级1分频,开启TA1IFG中断
	TA1EX0=TAIDEX_0;//二级1分频

}

/*TA2-CCR0中断服务函数*/
#pragma vector=TIMER0_B0_VECTOR		//CCR0中断标志
__interrupt void TA2Interrupt0()
{
	OneSecondFlag=1;	//1S标志位置位
	TB0CTL=MC_0;        //关闭定时器2
	TB0CTL&=~TBIE;
	/*测试用*/
	P1OUT^=BIT2;
	if(HInputOverflowTime==0)//溢出次数为0，表示实际信号为低频
	{
		TA0CTL|=MC_0;	//TA0直接关闭
		TA0CTL&=~TAIE;
		IsHighFrequenceFlag=0;//判断为低频
		HighFrequenceWaitFlag=0;//高频测量等待结束
		/*测试用*/
		P1OUT^=BIT3;
	}
}

/*TA0-CCR0中断服务函数*/
#pragma vector=TIMER0_A0_VECTOR		//CCR0中断标志
__interrupt void TA0Interrupt0()
{
	//__enable_interrupt();
	if(OneSecondFlag==0)	//表示还在1S的大闸门内
	{
		if(HInputWorkFlag==0)	//待测信号第一个闸门沿到来
		{
			TA0CCR0=10000;	//比较模式对比数值
			TA1CTL|=MC_2;	//标准信号开始同时进入连续技计数模式
			HInputWorkFlag=1;	//进入闸门内
		}
		else	//处于待测信号闸门内
		{
			HInputOverflowTime++;
			P1OUT^=BIT4;
		}
	}
	if(OneSecondFlag==1)	//表示1S的大闸门已经关闭
	{
		TA0CTL|=MC_0;	//关闭待测信号计数
		TA0CTL&=~TAIE;
		HInputOverflowTime++;
		TA1CTL&=~TAIE;
		TA1CTL|=MC_0;	//关闭标准信号计数
		HReferenceNum=TA1R;//暂时记录标准信号计数终值
		HighFrequenceWaitFlag=0;//高频测量等待结束
		P1OUT^=BIT5;
	}
}

/*TA1IFG中断服务函数*/
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TA1Interrupt1()
{
	switch(__even_in_range(TA0IV,14))
	{
		case 14:HROverflowTime++;break;
		default:break;
	}
}

/*高频测量主函数*/
void HFMeasure()
{
	OneSecondFlag=0;	//定时1S标志
	TB0CTL|=MC_1;//定时器2增模式
	TA0CTL|=MC_1;//定时器0增模式
	DelayMs(1500);
	//while(HighFrequenceWaitFlag);//高频测量等待
	//P1DIR|=BIT3;
	//P1OUT|=BIT3;
	TB0CTL|=MC_0;		//关闭定时器TB
	TA0CTL|=MC_0;		//关闭定时器
	TA1CTL|=MC_0;		//关闭定时器
	HInputNum=100*HInputOverflowTime;
	DelayMs(1);
	//HReferenceNum++;
	HReferenceNum+=HROverflowTime*65537;
	DelayMs(2);
}

/*ms延时函数*/
void DelayMs(unsigned int i)
{
	int j;
	for(j=0;j<i;j++)
	__delay_cycles(4000);

}

/*变量初始化函数*/
void ParameterInit()
{
	 HInputWorkFlag=0;//高频待测信号工作状态标志 0：第一个上升沿
	 HInputOverflowTime=0;//高频待测信号计数溢出次数
	 HROverflowTime=0;//高频基准信号计数溢出次数
	 HInputNum=0;	//高频输入信号计数值
	 HReferenceNum=0;//高频基准信号计数值
	 IsHighFrequenceFlag=1;//判断是否为高频标志位
	 HighFrequenceWaitFlag=1;//高频测量等待标志位

}
/*高频显示频率函数*/
void Display1()
{
	char LEDBuffer1[17];  //显示字符
	unsigned long int temp1;//计算中间缓冲变量
	unsigned int IntegerBuffer1=0;//整数部分
	unsigned int DecimalBuffer1=0;//小数部分
	if(HReferenceNum==0)
		HReferenceNum=1;
	temp1=HInputNum*4000;
	DelayMs(2);
		IntegerBuffer1=(temp1/HReferenceNum);
		DelayMs(5);
		DecimalBuffer1=((temp1%HReferenceNum)*1000)/HReferenceNum;
		DelayMs(2);
		LEDBuffer1[0]=CharCode[IntegerBuffer1/10000];
		IntegerBuffer1=IntegerBuffer1%10000;
		DelayMs(2);
		LEDBuffer1[1]=CharCode[IntegerBuffer1/1000];
		IntegerBuffer1=IntegerBuffer1%1000;
		DelayMs(2);
		LEDBuffer1[2]=CharCode[IntegerBuffer1/100];
		IntegerBuffer1=IntegerBuffer1%100;
		DelayMs(2);
		LEDBuffer1[3]=CharCode[IntegerBuffer1/10];
		IntegerBuffer1=IntegerBuffer1%10;
		DelayMs(2);
		LEDBuffer1[4]=CharCode[IntegerBuffer1];
		DelayMs(2);
		LEDBuffer1[5]='.';
		DelayMs(2);
		LEDBuffer1[6]=CharCode[DecimalBuffer1/1000];
		DecimalBuffer1=DecimalBuffer1%1000;
		DelayMs(2);
		LEDBuffer1[7]=CharCode[DecimalBuffer1/100];
		DecimalBuffer1=DecimalBuffer1%100;
		DelayMs(2);
		LEDBuffer1[8]=CharCode[DecimalBuffer1/10];
		DecimalBuffer1=DecimalBuffer1%10;
		DelayMs(2);
		LEDBuffer1[9]=CharCode[DecimalBuffer1];
		DelayMs(2);
		LEDBuffer1[10]='K';
		LEDBuffer1[11]='H';
		LEDBuffer1[12]='Z';
		LEDBuffer1[13]=' ';
		LEDBuffer1[14]=' ';
		LEDBuffer1[15]=' ';
		LEDBuffer1[16]='\0';
		Dogs102x6_clearScreen();//清屏
		Dogs102x6_stringDraw(3, 0, &LEDBuffer1[0], 0);//10列，20行；&为取数组首地址，0表示白底黑字
		Dogs102x6_clearRow(4);//清除第4行显示
		DelayMs(50);
	}

