#include <msp430g2553.h>
#include <math.h>
unsigned int FRE=0;
int i=0;
unsigned char flag1=0;
unsigned char flag2=0;
unsigned int adc_sample=0;
unsigned int adc_max=0;
unsigned int temp=0;
#define SET_LCD_1602_E P2OUT |= 0x04 //P2.2
#define CLR_LCD_1602_E P2OUT &= ~0x04
#define SET_LCD_1602_RS P2OUT |= 0x01 //P2.0
#define CLR_LCD_1602_RS P2OUT &= ~0x01
#define SET_LCD_1602_RW P2OUT |= 0x02 //P2.1
#define CLR_LCD_1602_RW P2OUT &= ~0x02
#define LCD_IO_OUT P1OUT
#define LCD_IO_DIR P1DIR
#define LCD_IO_IN P1IN
#define LCD_IO_SEL P1SEL
#define uchar unsigned char
#define uint unsigned int
void IO_Init(void);
void LCD_Init(void);
void LCD_Check_busy(void); //检测LCD是否在忙,即能否接收数据和指令
void LCD_Write_Command(uchar command);
void LCD_Write_Data(uchar dat);
void LCD_Set_xy( uchar x, uchar y );
uchar LCD_Read_Sta(void);
uchar LCD_Read_Data(uchar x,uchar y);
void User_def_char(uchar n,uchar *s); //输入用户自定义字符(5*8点阵字符),0~7共8个字符
void LCD_Disp_char(uchar x,uchar y,uchar dat);
void LCD_Disp_string(uchar x,uchar y,uchar *s);
uchar large=0; //当large为1时,为5*8点阵;为0时,为5*10点阵
uchar LCDBuf1[6];
//uchar LCDBuf2[5];
uchar LCDBuf2[]={"HZ"};
uchar LCDBuf3[]={"MV"};
void main()
{
WDTCTL = WDTPW + WDTHOLD;
DCOCTL |= ( DCO0 + DCO1 );
DCOCTL |= ( MOD4 + MOD3 + MOD2 + MOD1 + MOD0);//微调DCOCLK
BCSCTL1 |= ( RSEL0 + RSEL2 + RSEL3);//14.8M SMCLK
IO_Init();
LCD_Init();
//测频初始
TA0CTL |= TASSEL_0 + MC_1;
TA0CCR0 = 0xffff;
TA1CTL |= TASSEL_1 + MC_1 + TAIE;
TA1CCR0 = 32767;
TA1CCTL0 |= CCIE;
P1DIR &= ~BIT0; //p1.0设置为输入
P1SEL |= BIT0; //普通IO口
__bis_SR_register(GIE);
while(1)
{
if(0==flag1)
{
;
}
else
{
flag1=0;
TA0CTL |= TACLR;
TA0CTL = TASSEL_0 + MC_1;
TA1CTL = TASSEL_1 + MC_1 + TAIE;
}
while(0==flag1);
flag1=0;
//显示频率
for( i=0;i<5;i++)
{
temp = FRE/(10000/(unsigned int)(pow(10,i)));
LCDBuf1[i] = temp + '0';
FRE = FRE%(10000/(unsigned int)(pow(10,i)));
}
LCDBuf1[5] = 0;
LCD_Disp_string(0,0,LCDBuf1);
LCD_Disp_string(5,0,LCDBuf2);
LCD_Disp_string(12,0,"fr");
//测幅初始
flag2=1;
TA1CTL = TASSEL_1 + MC_1 + TAIE;
TA1CCR0 = 32767;//打开时钟
//ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
//ADC10CTL1 = INCH_1 + ADC10SSEL_3 + CONSEQ_2;
//ADC10AE0 = 0x02;
//ADC10DTC0 = ADC10B1;
//ADC10DTC1 = 0xC8;
//ADC10CTL0 &= ~ENC; // 先关闭adc,待到BUSY位清零,每次都必须等待
//while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
//ADC10SA = (unsigned int)adc_sample; // Data buffer start
//ADC10CTL0 |= ENC + ADC10SC;
ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON;
ADC10CTL1 = INCH_1 + ADC10SSEL_3 + CONSEQ_0;
ADC10AE0 = 0x02;
ADC10CTL0 |= ADC10ON;
do{
ADC10CTL0 |= ENC+ADC10SC;
while((ADC10CTL0 &ADC10IFG)==0);
adc_sample = ADC10MEM;
if(adc_max<adc_sample)
{
adc_max = adc_sample;
}
}while(0==flag1);
adc_max = adc_max*(3300/1023);
//while(0==flag1);
flag2=0;
/*
//筛选
for(int i=0;i<200;i++)
{
if(adc_sample[i]>adc_max)
{
adc_max=adc_sample[i];
}
}
*/
//显示幅值
for(i=0;i<5;i++)
{
temp = adc_max/(10000/(unsigned int)(pow(10,i)));
LCDBuf1[i] = temp + '0';
adc_max = adc_max%(10000/(unsigned int)(pow(10,i)));
}
LCDBuf1[5] = 0;
LCD_Disp_string(0,1,LCDBuf1);
LCD_Disp_string(5,1,LCDBuf3);
LCD_Disp_string(12,1,"ok");
adc_max = 0;
}
}
// Timer A1 interrupt service routine
#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer1_A (void)
{
if(0==flag2)
{
TA0CTL = 0;
TA1CTL = 0;
TA1CTL |= TACLR;
FRE=TA0R;
flag1=1;
TA0CTL = TASSEL_0 + MC_0;
TA1CTL = TASSEL_1 + MC_0;
//TA0CTL |= TACLR;
//TA0CTL = TASSEL_0 + MC_1;
//TA1CTL = TASSEL_1 + MC_1 + TAIE;
//测了一次还没开
}
else
{
TA1CTL = TASSEL_1 + MC_0;
flag1=1;
}
}
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
flag1=1;
ADC10CTL0 &= ~ENC;
}
void IO_Init(void)
{
LCD_IO_SEL &=~ 0xF0;//1111 0000
//LCD_IO_DIR |= 0x07 ;
P2DIR |= 0x07; //0111 2.0 2.1 2.2设置为输出
P2SEL &=~ 0x07; //0111
}
void LCD_Init(void)
{
LCD_Write_Command(0x28);
LCD_Write_Command(0x0F);
LCD_Write_Command(0x06);
LCD_Write_Command(0x01);
}
void LCD_Check_busy(void)
{
uchar flag=0x80;
flag &= LCD_Read_Sta();
while(flag == 0x80)
{
__delay_cycles(100);
flag &= LCD_Read_Sta();
}
}
void LCD_Write_Command(uchar command)
{
LCD_Check_busy();
CLR_LCD_1602_RS;
CLR_LCD_1602_RW;
CLR_LCD_1602_E;
uchar temp;
temp = command & (0x3C);
if((temp==(0x26))||(temp==(0x2C))||(temp==(0x36))||(temp==(0x3C)))
large = 0; //为5*10点阵
else
large = 1;
LCD_IO_DIR |= 0xF0;
LCD_IO_OUT = (command&(0XF0))+(LCD_IO_OUT&(0x0F));
SET_LCD_1602_E;
CLR_LCD_1602_E;
command <<= 4;
LCD_IO_OUT = (command&(0XF0))+(LCD_IO_OUT&(0x0F));
SET_LCD_1602_E;
CLR_LCD_1602_E;
}
void LCD_Write_Data(uchar dat)
{
LCD_Check_busy();
SET_LCD_1602_RS;
CLR_LCD_1602_RW;
CLR_LCD_1602_E;
LCD_IO_DIR |= 0xF0;
LCD_IO_OUT = (dat&(0XF0))+(LCD_IO_OUT&(0x0F));
SET_LCD_1602_E;
CLR_LCD_1602_E;
dat <<= 4;
LCD_IO_OUT = (dat&(0XF0))+(LCD_IO_OUT&(0x0F));
SET_LCD_1602_E;
CLR_LCD_1602_E;
}
void LCD_Set_xy(uchar x,uchar y)
{
uchar address;
if (y == 0)
address = 0x80 + x;
else
address = 0xC0 + x;
LCD_Write_Command(address);
}
uchar LCD_Read_Sta(void)
{
uchar sta;
CLR_LCD_1602_RS; //读入状态信息高四位数据
SET_LCD_1602_RW;
CLR_LCD_1602_E;
LCD_IO_DIR &=~ 0xF0;
SET_LCD_1602_E;
__delay_cycles(10);
sta = LCD_IO_IN;
CLR_LCD_1602_E;
SET_LCD_1602_E; //读入状态信息低四位数据
__delay_cycles(10);
uchar temp;
temp = LCD_IO_IN;
CLR_LCD_1602_E;
sta &= 0xF0;
temp >>= 4;
temp &= 0x0F;
sta = sta + temp;
return(sta);
}
uchar LCD_Read_Data(uchar x,uchar y)
{
uchar dat;
LCD_Set_xy(x,y); //确定读取数据坐标
SET_LCD_1602_RS; //读取数据高四位
SET_LCD_1602_RW;
CLR_LCD_1602_E;
LCD_IO_DIR &=~ 0xF0;
SET_LCD_1602_E;
__delay_cycles(10);
dat = LCD_IO_IN;
CLR_LCD_1602_E;
SET_LCD_1602_E; //读取数据低四位
__delay_cycles(10);
uchar temp;
temp = LCD_IO_IN;
CLR_LCD_1602_E;
dat &= 0xF0;
temp >>= 4;
temp &= 0x0F;
dat = dat + temp;
return(dat);
}
void User_def_char(uchar n,uchar *s)
{
int i;
char addr = 0x40;
n <<= 3;
addr += n;
for(i=0;i<8;i++,addr++)
{
LCD_Write_Command(addr);
LCD_Write_Data( *s );
s++;
}
}
void LCD_Disp_char(uchar x,uchar y,uchar dat)
{
LCD_Set_xy(x,y);
LCD_Write_Data(dat);
}
void LCD_Disp_string(uchar x,uchar y,uchar *s)
{
LCD_Set_xy(x,y);
while (*s)
{
LCD_Write_Data( *s );
s++;
}
}
|