1.1 單片機 選用MSP430G2553單片機,該單片機具有低功耗的特點,內(nèi)部自帶8路10位AD轉換器(ADC10),最高主頻可達16Mhz,對于一個簡易示波器來說這些特點足夠我們使用。 1.2 程控放大電路 程控放大電路的作用是對大信號進行衰減,對小信號進行放大,保證輸入到A/D轉換器的信號幅度在要求的輸入電壓范圍內(nèi),以達到最好的測量與觀察效果。采用模擬開關CD4051,配合精密電位器實現(xiàn)多擋垂直分辨率。在MSP430單片機中使用寄存器模塊設置通道號,通過寫入通道號控制模擬開關選通不同的反饋電阻,從而實現(xiàn)不同的放大倍數(shù),對信號進行不同程度的放大(衰減)。電路圖如下: 1.3 簡易調(diào)理電路 由于示波器觀察信號大多是正負電壓信號,考慮到ADC10一般使用的是單極性參考電壓(也可以使用寄存器設置雙極性參考電壓,這樣就不需要調(diào)理電路了,但最好加一級緩沖)。為了采樣到信號的負電壓,就需要給該信號疊加直流量,將負電壓部分信號抬高至零電平以上,因此采用信號調(diào)理電路。電路圖如下: 1.4 LCD顯示電路和按鍵電路 利用LCD的SPI通信模式與MSP430單片機連接,這樣可以得到不錯的通信速度,并且可以盡可能的減少MSP430引腳的占用,具體電路這里就不給出了。(按照spi連接) 利用簡單獨立按鍵實現(xiàn)放大倍數(shù)調(diào)節(jié),采樣頻率設置等功能即可。 2.軟件設計 2.1 單片機初始化 對P2口初始化,打開P2口的中斷;將通信方式設置為硬件spi通信模式(注意spi通信在上升沿還是在下降沿開始)。 - WDTCTL=WDTPW+WDTHOLD; //關看門狗
-
- P1OUT = 0x00; // P1 setup for LED & reset output
- P1DIR |= BIT0 + BIT2 + BIT3 + BIT4 + BIT5;
- P1SEL = BIT1 + BIT2 + BIT4;
- P1SEL2 = BIT1 + BIT2 + BIT4;
- P2REN |= 0x38;
- P2DIR = 0x07;
- P2OUT = 0;
- P2IE |= 0x38; // P1.4 interrupt enabled
- P2IFG &= ~0x38;
- will=0;
- UCA0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC + UCCKPH ; // 3-pin, 8-bit SPI master
- UCA0CTL1 |= UCSSEL_2; // SMCLK
- UCA0BR0 |= 0x04; // /2
- UCA0BR1 = 0; //
- UCA0MCTL = 0; // No modulation
- UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
- P1OUT &= ~BIT5; // Now with SPI signals initialized,
- P1OUT |= BIT5; // reset slave
- ADC10初始化,開啟參考源和中斷。
- ADC10CTL0 = ADC10SHT_0 + REFON + ADC10ON + ADC10IE;
- ADC10CTL1 = INCH_6;
- ADC10AE0 |= 0x40;
- 顯示初始化,對LCD的界面顯示初始化。
- Initial_ILI9340C();
- Delay_ms(300);
- LCD_TEST_SingleColor(Black);
- LCD_TEST_SingleColor(Black);
- LCD_TEST_PartColor(Blue);
- for(wh=22; wh<220 ;wh+=10)
- {
- LCD_draw_Line(wh,39,White);
- LCD_draw_Line(wh,79,White);
- LCD_draw_Line(wh,119,White);
- LCD_draw_Line(wh,159,White);
- LCD_draw_Line(wh,199,White);
- LCD_draw_Line(wh,239,White);
- LCD_draw_Line(wh,279,White);
- }
- Delay_ms(100);
- for(co=2; co<320 ;co+=10)
- {
- LCD_draw_Col(69,co,White);
- LCD_draw_Col(119,co,White);
- LCD_draw_Col(169,co,White);
- }
- Delay_ms(100);
復制代碼
2.2 程控選擇程序
根據(jù)按鍵的次數(shù),在P2口中斷改變will的值,并通過P2口輸出給CD4051的ABC開關選擇端,對放大倍數(shù)進行選擇。 - #pragma vector=PORT2_VECTOR
- __interrupt void Port_2(void)
- {
- if(P2IFG & 0x10)
- {
- while(0x10 & P2IN);
- will++;
- if(will==8)
- {
- will=7;
- }
- }
- if(P2IFG & 0x20)
- {
- while(0x20 & P2IN);
- will--;
- if(will==255)
- {
- will=0;
- }
- }
- if(P2IFG & 0x08)
- {
- while(0x08 & P2IN);
- chan++;
- if(chan==4)
- chan=0;
- }
- P2IFG &= ~0x38;
- P2OUT=will;
- }
復制代碼
2.3 采樣頻率設置
通過改變ADC10CTL1,通過按鍵次數(shù)對應值不同改變ADC10時鐘的頻率來調(diào)節(jié)電路的采樣頻率。 - switch(chan)
- {
- case 0: ADC10CTL1 = INCH_6; break;
- case 1: ADC10CTL1 |= ADC10DIV0 + ADC10DIV1; break;
- case 2: ADC10CTL1 |= ADC10DIV0 + ADC10DIV2; break;
- case 3: ADC10CTL1 |= ADC10DIV0 + ADC10DIV1 + ADC10DIV2; break;
- }
復制代碼
2.4 軟件觸發(fā)程序
只有在一定條件下才使lcd刷新,保證每次采集到的波形都從一點開始顯示,防止由于每次采集到的點不同導致波形一直移動。
ADC10CTL0 |= ENC + ADC10SC;
// Sampling and conversion start
__bis_SR_register(CPUOFF + GIE);
if(cir==0) key1 = ADC10MEM/5;
if(cir==1) key2 = ADC10MEM/5;
if(cir==2) key3 = ADC10MEM/5;
if(cir>2 && key1>key2 && key2>key3) //((key1-100)/2)>=(key2-100)
{
temp[0]=key1;
temp[1]=key2;
temp[2]=key3;
temp[cir]=ADC10MEM/5;
}
ADC10CTL0 &= ~ENC;
2.5 顯示刷新程序
示波器是一個動態(tài)顯示過程,因此在過程中可能會引起初始界面被部分覆蓋,以此需要定時刷新初始界面。
trig++;
if(trig%20==0)
{
for(wh=22; wh<220 ;wh+=10)
{
LCD_draw_Line(wh,39,White);
LCD_draw_Line(wh,79,White);
LCD_draw_Line(wh,119,White);
LCD_draw_Line(wh,159,White);
LCD_draw_Line(wh,199,White);
LCD_draw_Line(wh,239,White);
LCD_draw_Line(wh,279,White);
}
Delay_ms(300);
for(co=2; co<320 ;co+=10)
{
LCD_draw_Col(69,co,White);
LCD_draw_Col(119,co,White);
LCD_draw_Col(169,co,White);
}
Delay_ms(300);
}
附:源程序
- #include "msp430g2553.h" //STC12單片機頭文件
-
- //顏色定義
- #define Blue 0x001f
- #define Yellow 0xffe0
- #define Green 0x07e0
- #define Black 0x0000
- #define White 0xffff
- #define Red 0xf800
-
- //引腳定義
- #define R_ESET1 P1OUT|=BIT5; //液晶RESET引腳,接單片機IO引腳
- #define R_ESET0 P1OUT&=~BIT5;
- #define C_D1 P1OUT|=BIT3;//液晶D/CX引腳,數(shù)據(jù)/命令控制,接單片機IO引腳
- #define C_D0 P1OUT&=~BIT3;
- #define C_S1 P1OUT|=BIT0;//液晶片選CS,P1.4為單片機SPI總線的SS引腳,通過MSTR位配置為IO模式
- #define C_S0 P1OUT&=~BIT0;
-
- unsigned char MST_Data, SLV_Data, wh, temp[320], trig=0, key1, key2 ,key3 ,will ,chan=0;
- unsigned int co,cir;
-
-
- void delay(void)
- {
- unsigned int j;
- for(j=100;j>0;j--);
- }
- void Delay_us(int value)////延時函數(shù)_us
- {
- while (value)
- value--;
- }
-
- void Delay_ms(int value)////延時函數(shù)_ms
- {
- while (value){
- Delay_us(999);
- value--;
- }
- }
-
- void LCD_Writ_Bus(char a){ //數(shù)據(jù)寫入函數(shù) 8位
- C_S0;
- UCA0TXBUF = a;
- __delay_cycles(50);
- while (!(IFG2 & UCA0TXIFG));
- C_S1;
-
- }
-
- void LCD_WRITE_CMD(char cmd){//8 bit
- C_D0;
- LCD_Writ_Bus(cmd);
- }
-
- void LCD_WRITE_COM_DATA(char com_data){//8 bit
- C_D1;
- LCD_Writ_Bus(com_data);
- }
-
- void LCD_WRITE_DATA(int a){//16位數(shù)據(jù),分兩次,每次送8位
- C_D1;
- LCD_Writ_Bus(a>>8);
- LCD_Writ_Bus(a);
- }
-
- //設置繪點窗口,x=0~239,y=0~319
- void Address_set(unsigned int x1,unsigned int x2,unsigned int y1,unsigned int y2)
- {
- LCD_WRITE_CMD(0x2a); //x軸
- LCD_WRITE_DATA(x1);
- LCD_WRITE_DATA(x2);
- LCD_WRITE_CMD(0x2b); //y軸
- LCD_WRITE_DATA(y1);
- LCD_WRITE_DATA(y2);
- LCD_WRITE_CMD(0x2c);
- }
-
- void LCD_TEST_SingleColor(int Discolor){
- int i,j;
- Address_set(0,239,0,319);
-
- for (i=0;i<320;i++){
- for (j=0;j<240;j++){
- LCD_WRITE_DATA(Discolor);
- }
- }
- }
-
- void LCD_TEST_PartColor(int Discolor){
- int i,j;
- Address_set(0,19,0,319);
-
- for (i=0;i<320;i++){
- for (j=0;j<20;j++){
- LCD_WRITE_DATA(Discolor);
- }
- }
- Address_set(220,239,0,319);
-
- for (i=0;i<320;i++){
- for (j=220;j<240;j++){
- LCD_WRITE_DATA(Discolor);
- }
- }
- }
-
- //畫一條橫線
- void LCD_draw_Line(unsigned int x,unsigned int y,unsigned int color)
- { int i;
- Address_set(x,x+4,y,y);
- for (i=0;i<5;i++){
- LCD_WRITE_DATA(color);
- }
- }
-
- void LCD_draw_Col(unsigned int x,unsigned int y,unsigned int color)
- { int i;
- Address_set(x,x,y,y+4);
- for (i=0;i<5;i++){
- LCD_WRITE_DATA(color);
- }
- }
-
- //液晶主控初始化
- void Initial_ILI9340C(void)
- {
- LCD_WRITE_CMD(0xCB);
- LCD_WRITE_COM_DATA(0x39);
- LCD_WRITE_COM_DATA(0x2C);
- LCD_WRITE_COM_DATA(0x00);
- LCD_WRITE_COM_DATA(0x34);
- LCD_WRITE_COM_DATA(0x02);
-
- LCD_WRITE_CMD(0xCF);
- LCD_WRITE_COM_DATA(0x00);
- LCD_WRITE_COM_DATA(0XC1);
- LCD_WRITE_COM_DATA(0X30);
-
- LCD_WRITE_CMD(0xE8);
- LCD_WRITE_COM_DATA(0x85);
- LCD_WRITE_COM_DATA(0x00);
- LCD_WRITE_COM_DATA(0x78);
-
- LCD_WRITE_CMD(0xEA);
- LCD_WRITE_COM_DATA(0x00);
- LCD_WRITE_COM_DATA(0x00);
-
- LCD_WRITE_CMD(0xED);
- LCD_WRITE_COM_DATA(0x64);
- LCD_WRITE_COM_DATA(0x03);
- LCD_WRITE_COM_DATA(0X12);
- LCD_WRITE_COM_DATA(0X81);
-
- LCD_WRITE_CMD(0xF7);
- LCD_WRITE_COM_DATA(0x20);
-
- LCD_WRITE_CMD(0xC0); //Power control
- LCD_WRITE_COM_DATA(0x23); //VRH[5:0]
-
- LCD_WRITE_CMD(0xC1); //Power control
- LCD_WRITE_COM_DATA(0x10); //SAP[2:0];BT[3:0]
-
- LCD_WRITE_CMD(0xC5); //VCM control
- LCD_WRITE_COM_DATA(0x3e); //對比度調(diào)節(jié)
- LCD_WRITE_COM_DATA(0x28);
-
- LCD_WRITE_CMD(0xC7); //VCM control2
- LCD_WRITE_COM_DATA(0x86); //--
-
- LCD_WRITE_CMD(0x36); // Memory Access Control
- LCD_WRITE_COM_DATA(0xC8);
-
- LCD_WRITE_CMD(0x3A);
- LCD_WRITE_COM_DATA(0x55);
-
- LCD_WRITE_CMD(0xB1);
- LCD_WRITE_COM_DATA(0x00);
- LCD_WRITE_COM_DATA(0x18);
-
- LCD_WRITE_CMD(0xB6); // Display Function Control
- LCD_WRITE_COM_DATA(0x08);
- LCD_WRITE_COM_DATA(0x82);
- LCD_WRITE_COM_DATA(0x27);
-
- LCD_WRITE_CMD(0xF2); // 3Gamma Function Disable
- LCD_WRITE_COM_DATA(0x00);
-
- LCD_WRITE_CMD(0x26); //Gamma curve selected
- LCD_WRITE_COM_DATA(0x01);
-
- LCD_WRITE_CMD(0xE0); //Set Gamma
- LCD_WRITE_COM_DATA(0x0F);
- LCD_WRITE_COM_DATA(0x31);
- LCD_WRITE_COM_DATA(0x2B);
- LCD_WRITE_COM_DATA(0x0C);
- LCD_WRITE_COM_DATA(0x0E);
- LCD_WRITE_COM_DATA(0x08);
- LCD_WRITE_COM_DATA(0x4E);
- LCD_WRITE_COM_DATA(0xF1);
- LCD_WRITE_COM_DATA(0x37);
- LCD_WRITE_COM_DATA(0x07);
- LCD_WRITE_COM_DATA(0x10);
- LCD_WRITE_COM_DATA(0x03);
- LCD_WRITE_COM_DATA(0x0E);
- LCD_WRITE_COM_DATA(0x09);
- LCD_WRITE_COM_DATA(0x00);
-
- LCD_WRITE_CMD(0XE1); //Set Gamma
- LCD_WRITE_COM_DATA(0x00);
- LCD_WRITE_COM_DATA(0x0E);
- LCD_WRITE_COM_DATA(0x14);
- LCD_WRITE_COM_DATA(0x03);
- LCD_WRITE_COM_DATA(0x11);
- LCD_WRITE_COM_DATA(0x07);
- LCD_WRITE_COM_DATA(0x31);
- LCD_WRITE_COM_DATA(0xC1);
- LCD_WRITE_COM_DATA(0x48);
- LCD_WRITE_COM_DATA(0x08);
- LCD_WRITE_COM_DATA(0x0F);
- LCD_WRITE_COM_DATA(0x0C);
- LCD_WRITE_COM_DATA(0x31);
- LCD_WRITE_COM_DATA(0x36);
- LCD_WRITE_COM_DATA(0x0F);
-
- LCD_WRITE_CMD(0x11); //Exit Sleep
- Delay_ms(120);
-
- LCD_WRITE_CMD(0x29); //Display on
- LCD_WRITE_CMD(0x2c);
-
- }
-
- //LCD進入休眠狀態(tài)
- void LCD_Sleep_ILI9340C(void)
- {
- LCD_WRITE_CMD(0x28);//Display off
- Delay_ms(20);
- LCD_WRITE_CMD(0x10);//Enter Sleep mode
- }
- //LCD退出休眠狀態(tài)
- void LCD_ExitSleep_ILI9340C(void)
- {
- LCD_WRITE_CMD(0x11);//Exit Sleep
- Delay_ms(120);
- LCD_WRITE_CMD(0x29);//Display on
- LCD_WRITE_CMD(0x2c);
- }
-
- void main()
- {
- WDTCTL=WDTPW+WDTHOLD; //關看門狗
-
-
- P1OUT = 0x00; // P1 setup for LED & reset output
- P1DIR |= BIT0 + BIT2 + BIT3 + BIT4 + BIT5;
- P1SEL = BIT1 + BIT2 + BIT4;
- P1SEL2 = BIT1 + BIT2 + BIT4;
- P2REN |= 0x38;
- P2DIR = 0x07;
- P2OUT = 0;
- P2IE |= 0x38; // P1.4 interrupt enabled
- P2IFG &= ~0x38;
- will=0;
- UCA0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC + UCCKPH ; // 3-pin, 8-bit SPI master
- UCA0CTL1 |= UCSSEL_2; // SMCLK
- UCA0BR0 |= 0x04; // /2
- UCA0BR1 = 0; //
- UCA0MCTL = 0; // No modulation
- UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
- P1OUT &= ~BIT5; // Now with SPI signals initialized,
- P1OUT |= BIT5; // reset slave
-
- __delay_cycles(75); // Wait for slave to initialize
-
- Initial_ILI9340C();
- Delay_ms(300);
- LCD_TEST_SingleColor(Black);
- LCD_TEST_SingleColor(Black);
- LCD_TEST_PartColor(Blue);
- for(wh=22; wh<220 ;wh+=10)
- {
- LCD_draw_Line(wh,39,White);
- LCD_draw_Line(wh,79,White);
- LCD_draw_Line(wh,119,White);
- LCD_draw_Line(wh,159,White);
- LCD_draw_Line(wh,199,White);
- LCD_draw_Line(wh,239,White);
- LCD_draw_Line(wh,279,White);
- }
- Delay_ms(100);
- for(co=2; co<320 ;co+=10)
- {
- LCD_draw_Col(69,co,White);
- LCD_draw_Col(119,co,White);
- LCD_draw_Col(169,co,White);
- }
- Delay_ms(100);
-
- ADC10CTL0 = ADC10SHT_0 + REFON + ADC10ON + ADC10IE;
- ADC10CTL1 = INCH_6;
- ADC10AE0 |= 0x40; // PA.1 ADC option select
-
- while(1)
- {
- for(cir=0;cir<320;cir++)
- {
- ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
- __bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exi
- if(cir==0) key1 = ADC10MEM/5;
- if(cir==1) key2 = ADC10MEM/5;
- if(cir==2) key3 = ADC10MEM/5;
- if(cir>2 && key1>key2 && key2>key3) //((key1-100)/2)>=(key2-100)
- {
- temp[0]=key1;
- temp[1]=key2;
- temp[2]=key3;
- temp[cir]=ADC10MEM/5;
- }
- ADC10CTL0 &= ~ENC;
- switch(chan)
- {
- case 0: ADC10CTL1 = INCH_6; break;
- case 1: ADC10CTL1 |= ADC10DIV0 + ADC10DIV1; break;
- case 2: ADC10CTL1 |= ADC10DIV0 + ADC10DIV2; break;
- case 3: ADC10CTL1 |= ADC10DIV0 + ADC10DIV1 + ADC10DIV2; break;
- }
- }
-
- for(cir=0;cir<320;cir++)
- {
- Address_set(20+temp[cir],20+temp[cir],cir,cir);
- LCD_WRITE_DATA(Yellow);
- }
- Delay_ms(300);
- for(cir=0;cir<320;cir++)
- {
- Address_set(20+temp[cir],20+temp[cir],cir,cir);
- LCD_WRITE_DATA(Yellow);
- }
- Delay_ms(300);
- for(cir=0;cir<320;cir++)
- {
- Address_set(20+temp[cir],20+temp[cir],cir,cir);
- LCD_WRITE_DATA(Yellow);
- }
- Delay_ms(300);
- for(cir=0;cir<320;cir++)
- {
- Address_set(20+temp[cir],20+temp[cir],cir,cir);
- LCD_WRITE_DATA(Yellow);
- }
- Delay_ms(300);
- for(cir=0;cir<320;cir++)
- {
- Address_set(20+temp[cir],20+temp[cir],cir,cir);
- LCD_WRITE_DATA(Black);
- }
-
- trig++;
-
- if(trig%20==0)
- {
- for(wh=22; wh<220 ;wh+=10)
- {
- LCD_draw_Line(wh,39,White);
- LCD_draw_Line(wh,79,White);
- LCD_draw_Line(wh,119,White);
- LCD_draw_Line(wh,159,White);
- LCD_draw_Line(wh,199,White);
- LCD_draw_Line(wh,239,White);
- LCD_draw_Line(wh,279,White);
- }
- Delay_ms(300);
- for(co=2; co<320 ;co+=10)
- {
- LCD_draw_Col(69,co,White);
- LCD_draw_Col(119,co,White);
- LCD_draw_Col(169,co,White);
- }
- Delay_ms(300);
- }
- }
- }
- // ADC10 interrupt service routine
- #pragma vector=ADC10_VECTOR
- __interrupt void ADC10_ISR (void)
- {
- __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
- }
- #pragma vector=PORT2_VECTOR
- __interrupt void Port_2(void)
- {
- if(P2IFG & 0x10)
- {
- while(0x10 & P2IN);
- will++;
- if(will==8)
- {
- will=7;
- }
- }
- if(P2IFG & 0x20)
- {
- while(0x20 & P2IN);
- will--;
- if(will==255)
- {
- will=0;
- }
- }
- if(P2IFG & 0x08)
- {
- while(0x08 & P2IN);
- chan++;
- if(chan==4)
- chan=0;
- }
- P2IFG &= ~0x38;
- P2OUT=will;
- }
復制代碼
完整的Word格式文檔51黑下載地址:
|