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).
Keywords:STC12C5A50S2 NOKIA1100
Reference address:A pocket oscilloscope composed of STC12C5A50S2 and NOKIA1100 LCD screen
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--;
}
}
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
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
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
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--;
}
}
Previous article:An improved 4*4 matrix keyboard scanning
Next article:Eight-way direct control keyboard controls digital display
- Popular Resources
- Popular amplifiers
- MCU Principles and Interface Technology C51 Programming (Edited by Zhang Yigang)
- Learn programming from scratch Learn 51 single chip microcomputer from scratch (He Liang)
- MCU Principles and Interface Technology Fifth Edition (Li Chaoqing)
- Learn programming from scratch Learn 51 single chip microcomputer from scratch
Recommended Content
Latest Microcontroller Articles
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
MoreDaily News
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
Guess you like
- DC motor drive solution using TC118S domestic chip
- Inline instructions in TI DSP TMS320C66x study notes (c6x.h Chinese comments)
- [Zero-knowledge ESP8266 tutorial] Quick Start 19 Using NTP server to get network time
- [GD32E503 Review] How to Play with GD32E503-Environment Construction
- [National Technology M4 core hot-selling N32G45XVL evaluation] The fifth low-power performance evaluation
- STM32G timer setting problem
- dsp DM642 uses timer to light up LED source program
- [2022 Digi-Key Innovation Design Competition] I am just an image porter
- Nengdian Electronics Capacitive Liquid Level Sensor D1CS-D54 Review
- [Zhongke Bluexun AB32VG1 RISC-V board "meets" RTT] GPIO simulation realizes full-color LED lights