- #include<msp430g2553.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define BIT(x) (1<<(x))
- #define Range_3V 0 //量程為0~3V
- #define Range_15V 1 //量程為0~15V
- /*********************************************************
- 函數聲明
- *********************************************************/
- void System_Init(void);
- void ADC_Init(void);
- void LCD_Init();
- void LCD_Send(uchar type,uchar transdata);
- void Delay_nms(uint n);
- void LCD_Pos(uchar x,uchar y);
- void LCD_Display_String(const uchar *pt,uchar num);
- void LCD_Display(long int Data);
- void LCD_Display_Digit(long int num);
- uchar LCD_Table[]={'0','1','2','3','4','5','6','7','8','9','.','V'};
- long int Voltage; //全局變量Voltage
- uint Voltage_Range;
- /*********************************************************
- 函數功能:系統初始化
- 入口參數:無
- 出口參數:無
- 函數說明:無
- *********************************************************/
- void System_Init(void)
- {
- WDTCTL = WDT_ADLY_1000; //看門狗工作在定時器模式,1s中斷一次
- IE1 |= WDTIE; //使能看門狗中斷
- P1DIR |= BIT0 + BIT1; //相應的位端口設置為輸出
- P1SEL |= BIT4; //P1.4為A4通道
- Voltage_Range = Range_15V; //Range_3V即量程為3V,Range_15V即量程為15V
- ADC_Init(); //ADC初始化;
- LCD_Init(); //液晶初始化
- }
- /*********************************************************
- 函數功能:ADC初始化
- 入口參數:無
- 出口參數:無
- 函數說明:無
- *********************************************************/
- void ADC_Init (void)
- {
- ADC10CTL0 &= ~ENC; //復位轉換允許位
- ADC10CTL0 |= ADC10ON + ADC10SHT_0 + SREF_0 + ADC10IE ;
- //設置轉換控制寄存器ADC10CTL0,ADC10ON=0x010,使ADC10內核工作
- //ADC10SHT_0=0*0x800u,確定采樣周期為4xADC10CLKs
- //SREF_0=0*0x2000u,選擇參考電壓為VR+=AVCC,VR-=AVSS
- //ADC10IE=0x00使對應通道轉換后產生中斷
- ADC10CTL1 |= INCH_4 + CONSEQ_0;
- //設置AD轉換控制寄存器ADC10CTL1,INCH_0=0*0x1000u,選擇通道A4
- //CONSEQ_1=1*2u,設置工作模式為單通道、單次轉換模式
- ADC10CTL0 |= ENC + ADC10SC;
- //設置轉換控制寄存器ADC12CTL0,ENC=0x002使轉換允許位為1
- //ADC12SC=0x001使采樣/轉換控制位為1
- _EINT(); //總中斷使能
- }
- /***************************ADC中斷函數****************************/
- #pragma vector = ADC10_VECTOR
- __interrupt void ADC10_Interrupt(void)
- {
- uint data;
- data = ADC10MEM; //將AD采樣值存入data
- if(Voltage_Range == Range_3V) //V(實際)=(VR+ - VR-)*data/1023 + VR-
- Voltage = (uint)(35.4*data/10.23); //Voltage是實際電壓值的1000倍
- else
- Voltage = (uint)(35.4*data/10.23*5.38);
- }
- /***************************WDT中斷函數****************************/
- #pragma vector = WDT_VECTOR
- __interrupt void watchdog_timer(void)
- {
- LCD_Display(Voltage); //顯示電壓值
- }
- /*********************************************************
- 函數名稱:LCD初始化函數
- 入口參數:無
- 出口參數:無
- 函數說明:無
- *********************************************************/
- void LCD_Init()
- {
- Delay_nms(5);
- LCD_Send(0,0x01); //清屏指令
- Delay_nms(5); //延時等待液晶完成復位
- LCD_Send(0,0x30); //功能設定:基本指令集操作
- Delay_nms(5);
- LCD_Send(0,0x02); //地址歸0
- Delay_nms(5);
- LCD_Send(0,0x0c); //開顯示,且關閉光標及其反白顯示
- Delay_nms(5);
- }
- /*********************************************************
- 函數功能:寫指令或數據
- 入口參數:type,transdata
- 出口參數:無
- 函數說明:無
- *********************************************************/
- void LCD_Send(uchar type,uchar transdata)
- {
- uchar firstbyte = 0xf8;
- uchar temp,i,j;
- if(type)
- firstbyte |= 0x02;
- P1OUT &= ~BIT1;
- for(j=3;j>0;j--)
- {
- switch(j)
- {
- case 3:temp=firstbyte;break;
- case 2:temp=transdata&0xf0;break;
- case 1:temp=(transdata<<4)&0xf0;break;
- }
- for(i=8;i>0;i--)
- {
- if(temp&0x80)
- P1OUT |= BIT0;
- else
- P1OUT &= ~BIT0;
- P1OUT |= BIT1;
- temp <<= 1;
- P1OUT &= ~BIT1;
- }
- Delay_nms(1);
- }
- P1OUT &= ~BIT0;
- }
- /**********************定位函數************************/
- void LCD_Pos(uchar x,uchar y)
- {
- int pos;
- switch(x)
- {
- case 1:pos=0x80;break;
- case 2:pos=0x90;break;
- case 3:pos=0x88;break;
- case 4:pos=0x98;break;
- default:pos=0x80;
- }
- pos += y;
- LCD_Send(0,pos);
- }
- /*********************************************************
- 函數功能:字符串顯示函數
- 入口參數:*pt ,num
- 出口參數:無
- 函數說明:無
- *********************************************************/
- void LCD_Display_String(const uchar *pt,uchar num)
- {
- uchar i;
- for(i = 0;i < (num*2);i++)
- LCD_Send(1,*(pt++));
- }
- /*********************************************************
- 函數功能:數字顯示函數
- 入口參數:num
- 出口參數:無
- 函數說明:無
- *********************************************************/
- void LCD_Display_Digit(long int num)
- {
- uint SHOW[7],i=0;
- SHOW[0]=(num/10000)%10; //十位
- SHOW[1]=(num/1000)%10; //個位
- SHOW[2]=10; //.
- SHOW[3]=(num/100)%10; //十分位
- SHOW[4]=num/10%10; //百分位
- SHOW[5]=num%10; //千分位
- SHOW[6]=11; //V
- switch(Voltage_Range)
- {
- case Range_3V: for(i=1;i<7;i++)
- LCD_Send(1,LCD_Table[SHOW[i]]); break;
- case Range_15V: for(i=0;i<7;i++)
- {
- if(i==5)++i;
- LCD_Send(1,LCD_Table[SHOW[i]]);
- } break;
- default: break;
- }
- }
- /***********************延時函數*************************/
- void Delay_nms(uint n)
- {
- uchar i;
- while(n--)
- for(i=0;i<115;i++);
- }
- /*************************************************************
- 函數名稱:顯示函數
- 入口參數:Data
- 出口參數:無
- 函數說明:每行最多8個字,2個字母或數字相當于1個字的長度,注意
- 漢字沒法跨格顯示。
- *************************************************************/
- void LCD_Display(long int Data)
- {
- //LCD_Pos(1,0); //第一行
- //LCD_Display_String("",0);
- LCD_Pos(2,0); //第二行
- LCD_Display_String(" 數字式電壓表",7);
- LCD_Pos(3,0); //第三行
- LCD_Display_String("當前電壓:",5);
- LCD_Display_Digit(Data);
- //LCD_Pos(4,0); //第四行
- //LCD_Display_String(12.13);
- }
- /*********************************************************
- 函數名稱:主函數
- 入口參數:無
- 出口參數:無
- 函數說明:請看完最上面程序說明再運行程序
- *********************************************************/
- void main()
- {
- System_Init();
- while(1)
- {
- ADC10CTL0 |= ENC + ADC10SC; //開啟ADC轉換
- }
- }
復制代碼 |