【GD32E503 Review】 Summary of Simple Oscilloscope Experiment Project
[Copy link]
First of all, I would like to thank GigaDevice and EEWORLD Forum for providing this evaluation opportunity. My evaluation plan is to display the ADC converted data dynamically in a graphical manner on the TFT screen to complete a simple oscilloscope experiment. This evaluation took nearly two months, focusing on the simple oscilloscope experiment. Through repeated exploration and experiments, I basically completed the project goal and realized the dynamic display of ADC converted data in a graphical manner.
1. Operation of TFT screen display
Understanding and mastering the operation of the TFT display is the first step in dynamic graphics display. Through the analysis of the sample code, I initially understood that the characters displayed on the screen are written point by point, which laid the foundation for the subsequent dynamic graphics display of ADC conversion results. During the test, it was found that although the efficiency of point-by-point writing was very low, there was no display hysteresis in the test because the microcontroller had few other processing tasks. The character display function provided by the example is to display a single character. On this basis, I rewrote a function that can display a string, and also added a Chinese character set to achieve a mixed display of Chinese characters and ASCII code characters. Later, a function to display data in decimal format was added to facilitate the display of ADC conversion results. The following figure shows the effect of the TFT screen display:
Here is the function code that displays the string:
/*!
\brief 从根据指定位置开始在液晶屏上显示字符串(8*16ASCII和16*16汉字字符集)
\param[in] x: the start position of row-coordinate X坐标
\param[in] y: the start position of column-coordinate Y坐标
\param[in] text: the char 要显示的字符串
\param[in] char_color: the color of char 字符颜色
\param[in] c_format: the structure of char format 字体(字库)
font: CHAR_FONT_8_16 or CHAR_FONT_16_24
direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
char_color: the color of char
bk_color: the color of background
\param[out] none
\retval none
*/
void lcd_strue_display(uint16_t x,uint16_t y,uint8_t *str,char_format_struct c_format)
{
uint8_t i,j,k,temp_char;
uint16_t X,Y;
X = x;
Y = y;
while(*str){
if(((uint8_t)(*str)) < 128){ //显示单字节ASCII(8*16)
if(*str > 31){
if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){//水平显示
for (i = 0; i < 16; i++) { //显示16行的点阵
temp_char = ascii_8x16[((*str - 0x20) * 16) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
lcd_point_set(X - i, Y + j, c_format.char_color);
} else {
lcd_point_set(X - i, Y + j, c_format.bk_color);
}
}
}
Y += 8;
}else{
for (i = 0; i < 16; i++) { //显示16行的点阵
temp_char = ascii_8x16[((*str - 0x20) * 16) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X + j, Y + i, c_format.char_color);
else
lcd_point_set(X + j, Y + i, c_format.bk_color);
}
}
X += 8;
}
}
str++;
}
else{ //显示双字节汉字(16*16)
for(k=0; k<200; k++){ //在汉字字符集中查找小于200次
if((GB_16ID[k][0] == *(str)) && (GB_16ID[k][1] == *(str + 1))){
if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){ //水平显示
for( i=0; i<16; i++){//显示16行的点阵(左半边)
temp_char = GB_16[(k * 32) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X - i, Y + j, c_format.char_color);
else
lcd_point_set(X - i, Y + j, c_format.bk_color);
}
}
for( i=0; i<16; i++){//显示16行的点阵(右半边)
temp_char = GB_16[(k * 32) + i + 16];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X - i, Y + j + 8, c_format.char_color);
else
lcd_point_set(X - i, Y + j + 8, c_format.bk_color);
}
}
Y += 16;
} else {
for( i=0; i<16; i++){//显示16行的点阵(左半边)
temp_char = GB_16[(k * 32) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X + j, Y + i, c_format.char_color);
else
lcd_point_set(X + j, Y + i, c_format.bk_color);
}
}
for( i=0; i<16; i++){//显示16行的点阵(右半边)
temp_char = GB_16[(k * 32) + i + 16];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X + j + 8, Y + i, c_format.char_color);
else
lcd_point_set(X + j + 8, Y + i, c_format.bk_color);
}
}
X += 16;
}
}
}
str += 2;
}
}
}
Here is the function code that displays the variables:
/*!
\brief 从指定位置开始在液晶屏上显示变量(8*16ASCII十进制数字)
\param[in] x: the start position of row-coordinate X坐标
\param[in] y: the start position of column-coordinate Y坐标
\param[in] len: 显示的长度(位数,<8位)
\param[in] pont: 小数位数
\param[in] text: the char 要显示的字符串
\param[in] char_color: the color of char 字符颜色
\param[in] c_format: the structure of char format 字体(字库)
font: CHAR_FONT_8_16 or CHAR_FONT_16_24
direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
char_color: the color of char
bk_color: the color of background
\param[out] none
\retval none
*/
void lcd_value_display(uint16_t x,uint16_t y,uint8_t len, uint8_t pont, uint32_t val,char_format_struct c_format)
{
uint8_t i,j,f = 32; //列循环、字循环、显示标志
uint8_t cha[] = "0000000000"; //10位
uint32_t t,cid; //当前余数、当前数字
uint32_t n; //当前倍数
t = val;
n = 1;
i = 0;
for (j = 0; j < len; j++)
n = n * 10;
for (j = len; j > 0; j--) //字符循环开始
{
n = j < 2 ? 1: n / 10; //计算当前的倍数
cid = t / n; //当前位数字
t = t - (cid * n);
if((cid>0) | (j-1==pont)) //有效数据后的零显示
f = 48;
cha[i++] = cid + f;
if(pont > 0 & pont == (j - 1)){
cha[i++] = 46; //加小数点
}
}
cha[i] = 0;
lcd_strue_display( x, y, cha, c_format);
}
2. The process of simple oscilloscope experiment
First, we tested the ADC conversion. We used ADC1 (PA1) and ADC2 (PA2) on the board. ADC1 on the development board has been connected to a multi-turn potentiometer, and PA2 is connected to an external signal source through JP4. I made a potentiometer expansion board as the signal source for ADC2, and also used a linear power converter to lead out a low-voltage AC power supply, which was used as a signal source for testing dynamic waveforms after half-wave rectification by a diode. The following figure shows ADC2 connected to the potentiometer expansion board:
This is ADC2 connected to a homemade low-voltage AC (half-wave rectifier) signal source:
On the basis of testing ADC conversion, I continued to experiment with a simple oscilloscope. I set about 2/3 of the screen as the graphic display area, with two display modes, independent and combined, which can be switched by pressing KEY_CET. The following figure is the independent mode, that is, the two ADC conversion results are displayed in two areas respectively, ADC1 is displayed in the upper area with red lines, and ADC2 is displayed in the lower area with blue lines.
The display effect of the merge mode is as follows, that is, the two sets of transformation results are displayed in the same coordinate system, which makes it easier to compare:
I set three parameters for adjustment in the simple oscilloscope experiment, namely sampling rate, refresh rate and zoom rate. When adjusting the parameters, first use the KEY_A button to switch the parameter to be adjusted, and then press the KEY_B or KEY_D button to adjust the size of the parameter.
First is the sampling rate parameter. At first, I planned to use a timer to trigger sampling, but after many attempts, the timer was not set successfully. I had no choice but to set a variable to count this variable in the main loop. When the set value is reached, the sampling is triggered. By changing the set value, the sampling rate is changed. As shown in the figure below, in this experiment, this parameter is from 50 to 1500 with an interval of 50. After testing, when the parameter is 50, the sampling rate is about 11,000 times per second; when the parameter is 1500, the sampling rate is about 400 times per second.
The second adjustable parameter is the refresh rate, which ranges from 5 to 200 with an interval of 5. When the parameter is 5, about 83 columns are displayed per second, and it takes about 3 seconds to refresh a screen; when the parameter is 200, about 15 columns are displayed per second, and it takes about 16 seconds to refresh a screen.
The third adjustable parameter is the scaling factor. We know that the maximum conversion data of 12-bit ADC is 4096. In this experiment, the column direction is 100 dots when displayed independently and 200 dots when displayed together. This data needs to be reduced so that it can be displayed on the screen. This parameter can be adjusted from 15 to 40 (see the figure below):
3. Results of the Simple Oscilloscope Experiment
At the beginning of the experiment, I synchronized the ADC sampling and the graphic display, that is, the display was displayed as the sampling progressed. During the test, when the potentiometer was rotated, the displayed line would move up and down, and a relatively good effect was achieved. However, when I used low-voltage AC power after half-wave rectification as the signal source, I could not see the expected half sine wave, but only a waveform that was approximately a straight line with periodic changes (see the figure below), which seemed to be the effect of refreshing too quickly:
On this basis, when I try to reduce the refresh rate to about 15 columns per second, I can see a staircase-like approximate half sine wave, as shown in the following figure:
We know that the frequency of the AC power is 50Hz, which means one cycle is 20 milliseconds. In my experiment, it took more than ten seconds to display half of the waveform, which means at least 200 cycles have passed. Therefore, the waveform above is not a real sine wave, but a "harmonic" graph that happens to be consistent with the AC power cycle.
In the improved experiment, I separated the ADC conversion from the graphic display. The result of the ADC conversion was placed in an array, and the data was taken from this array when it was displayed. Since the display speed is relatively slow and only 238 sets of data are needed to display one screen, I paused after the ADC converted 300 sets of data, waited for the full screen to be displayed, and then read 300 sets of data to continue displaying. In order to display half of the sine wave of the alternating current, I imagined sampling about 2000 times per second and 50 times per cycle, which should be able to display half of the waveform, but the reality was contrary to my expectations, and what I saw was still a periodically changing horizontal line.
After further analysis, I thought that the gap between triggering the ADC conversion and reading the data might be too short, causing the data to be incorrect. So I inserted a delay after triggering the ADC conversion and then read the data. However, the experiment was still unsuccessful. I gradually adjusted the delay from tens of microseconds to a few milliseconds, but only the amplitude of the horizontal line changed, and even the step-like waveform did not appear.
After nearly 20 days of testing, the effort to view the AC sine wave graphics of the mains power supply was ultimately unsuccessful. The reason may be the speed of ADC conversion. Of course, the bottleneck of the display screen is also an important reason. It seems that the idea of using a single-chip microcomputer to make an oscilloscope is still unrealistic. The sampling part should use a dedicated chip, and the display part cannot use the display screen evaluated in this test. Although the experiment of this simple oscilloscope was not completely successful, the evaluation of the GD32E503V-EVAL development board was still quite rewarding. This was my first contact with a touch screen and the first time I realized the dynamic display of graphics on a TFT screen.
|