A pocket oscilloscope composed of STC12C5A50S2 and NOKIA1100 LCD screen

Publisher:VolareLatest update time:2015-06-16 Source: 51heiKeywords:STC12C5A50S2  NOKIA1100 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
     This pocket oscilloscope is composed of STC12C5A50S2 and NOKIA1100 LCD screen. Function: It can measure dual-channel waveforms, the sampling rate ranges from 75KHz to 15Hz, and the input voltage should be able to reach 50V (I have not tested higher voltages).

 


 

 

        Main components: powered by mobile phone battery, PT1301 boosts voltage to 5V, 2.5V output by TL431 is used as the signal ground of the probe, TL082 op amp is used for signal amplification, MCP41010 digital potentiometer is used for gain adjustment, NOKIA1100 LCD screen is used as display, 96*65 pixels, the 3.3V voltage required for its operation is obtained by connecting 5V voltage in series with LED. STC12C5A50S2 is used as core control, according to the information, its ADC sampling speed can reach 250KHz, two ADCs collect waveform data, one ADC collects 2.5V voltage, one ADC collects battery voltage, and two PWMs control the offset of the conditioning circuit after low-pass filtering. The probe interface uses a dual-channel headphone interface, which saves space, but there will be interference between channels. There are 9 buttons, CH: channel selection; Vp/Hp: main menu selection: POWER: power on; Vs/Hs: (not used in this program) INC: +, STOP: power off SET: enter pop-up menu DEC: - ESC: exit/pause
        Program introduction:
        In order to facilitate graphic operations in the program, a memory buffer is established for the LCD screen. The drawing operation is performed in the microcontroller memory and then copied to the LCD screen as a whole. Since the memory is not sufficient, the block method is adopted to exchange time for space:
#define LCD_WIDTH 96
#define LCD_HEIGHT 8
//Number of LCD partitions
#define LCD_PART 2
//U8 lcd_x=0;
//U8 lcd_y=0;
xdata U8 lcd_buf[LCD_HEIGHT/LCD_PART][LCD_WIDTH]; //lcd display cache (1/LCD_PART screen)
xdata S16 lcd_bufx0=0,lcd_bufy0=0,lcd_bufx1=0,lcd_bufy1=0;//The four corners of the buffer correspond to the coordinates (remove the right border)
//x0 <= x < x1;y0 <= y < y1;
//-------------------------------------------------------
//Select LCD screen area
//s=0~LCD_PART-1
//-------------------------------------------------------
void lcd_buf_sel(U8 s)
{
        if(s>=LCD_PART)return;
        lcd_bufx0=0;
        lcd_bufx1=LCD_WIDTH;
        lcd_bufy0=LCD_HEIGHT*s/LCD_PART;        
        lcd_bufy1=LCD_HEIGHT*(s+1)/LCD_PART;
}

When drawing, it is necessary to traverse each display buffer block:
        for(p=0;p         {
                lcd_buf_sel(p);
                //LCD_DrawPic(0,0,160,123,0,gImage_t1);
                lcd_buf_fill(0x04);                
                GUI_SetFont6x8();
                GUI_dispnum(i,3,0,5,13,0);
                GUI_PutStr(5,5,"welcome...");
                GUI_SetFont8x16();
                GUI_PutStr(5,25,"welcome...");
                lcd_refresh();
        }

  The program collects waveform data in timer0 interrupt. The main code is as follows:
//--------------------------------------------------
//Query AD in timer
//--------------------------------------------------
void timer0(void) interrupt 1 using 3 //T0 interrupt, use register group 0
{
        //while(TF0==0);
        //TF0=0;
        U8 ad;
        //static U8 fp=0;//frequency divisionif        
        (T0EXC==0)
        {
                //mmm++;
                TH0=TH0RLD; //Reload initial value
                TL0=TL0RLD;
                T0EXC=T0EXH;
                //dosamp();
                while(ADC_CONTR&BIT(3)); //Wait for channel 0 conversion to complete
                //while(!(ADC_CONTR&BIT(4)));
                ad=ADC_RES; //Read channel 0
                if(TrigCh==0) //Channel 1 triggers
                {
                        if(ChEnable & BIT(1))//Channel 2 is enabled
                                ADC_CONTR=(0xE8|ADCH2);//Select channel 2
                        else //Otherwise select channel 1
                                ADC_CONTR=(0xE8|ADCH1);//Select channel 1
                        ADCBuf[0][BUF_Wps]=ad;//Loop storage data
                }
                else
                {
                        if(ChEnable & BIT(0))//Channel 1 is enabled
                                ADC_CONTR=(0xE8|ADCH1);//Select channel 1
                        else //Otherwise select channel 1
                                ADC_CONTR=(0xE8|ADCH2);//Select channel 2
                        ADCBuf[1][BUF_Wps]=ad;//Loop storage data                
                }
                [page]
                
                //if(BUF_Wps>=ADCBUFSIZE)BUF_Wps=0;
                if(SampState==0)//Pre-acquire data
                {
                        //if(ADC_Cnt                         ADC_Cnt++; //Increase the number of data by 1
                        BUF_Cnt++;
                        if(ADC_Cnt>=TrigPs)//trigger position
                        {
                                if(TrigEdge==0)//rising edge
                                        triggerSampState=1;
                                else //falling edge
                                        triggerSampState=2;
                        }
                }
                //------------------------rising edge state is 1-2-3, falling edge state is 2-1-3
                else if(SampState==1)
                {                        
                        if(ad<=TrigLevel)//lower than trigger level
                        {
                                if(TrigEdge==0)//rising edge
                                        triggerSampState=2;
                                else //falling edge
                                        triggerSampState=3;
                                //if(ADC_Cnt                                 ADC_Cnt++;//data number plus 1
                                BUF_Cnt++;
                        }
                        else//otherwise read queue, ADC_Cnt, BUF_Cnt will not be added
                        {
                                BUF_Rps++;
                                if(BUF_Rps>=ADCBUFSIZE)BUF_Rps=0;
                        }
                }
                else if(SampState==2)
                {
                        if(ad>TrigLevel)//higher than the trigger level
                        {
                                if(TrigEdge==0)//rising edge trigger
                                        SampState=3;
                                else //falling edge trigger
                                        SampState=1;
                                //if(ADC_Cnt                                 ADC_Cnt++;//data number plus 1
                                BUF_Cnt++;
                        }
                        else//otherwise read queue, ADC_Cnt, BUF_Cnt will not be added
                        {
                                BUF_Rps++;
                                if(BUF_Rps>=ADCBUFSIZE)BUF_Rps=0;
                        }
                }
                else if(SampState==3)//triggered
                {
                        ADC_Cnt++; //data number plus 1
                        BUF_Cnt++;
                        if(ADC_Cnt>=ADCBUFSIZE)//enough data collected
                        {
                                SampState=4;
                                TR0=0;
                        }
                }
                if((TrigMode==0)&&(SampState<3))//automatic trigger processing
                {                
                        if(TrigWait==0)//wait time low
                        {
                                if(TrigWaitH)//Wait time high
                                {
                                        TrigWaitH--;
                                }
                                else
                                {
                                        SampState=3;
                                }
                        }
                        TrigWait--;
                }
                if(TrigCh==0)//Channel 1 trigger
                {
                        if(ChEnable & BIT(1))//Channel 2 enable        
                        {
                                while(ADC_CONTR&BIT(3));//Wait for channel 1 conversion to complete
                                //while(!(ADC_CONTR&BIT(4)));
                                ad=ADC_RES;//Read channel 1
                                ADC_CONTR=(0xE8|ADCH1);//Select channel 1
                                ADCBuf[1][BUF_Wps]=ad;//Loop to store data
                        }
                }
                else
                {
                        if(ChEnable & BIT(0))//Channel 1 enable        
                        {
                                while(ADC_CONTR&BIT(3));//Wait for channel 1 conversion to complete
                                //while(!(ADC_CONTR&BIT(4)));
                                ad=ADC_RES;//Read channel 1
                                ADC_CONTR=(0xE8|ADCH2);//Select channel 2
                                ADCBuf[0][BUF_Wps]=ad;//Loop to store data
                        }                
                }
                //Move the write pointer down
                BUF_Wps++;
                if(BUF_Wps>=ADCBUFSIZE)BUF_Wps=0;
        }
        else
        {
                T0EXC--;
        }
}
Keywords:STC12C5A50S2  NOKIA1100 Reference address:A pocket oscilloscope composed of STC12C5A50S2 and NOKIA1100 LCD screen

Previous article:An improved 4*4 matrix keyboard scanning
Next article:Eight-way direct control keyboard controls digital display

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号