stm32f103与2.4寸TFT可触液晶屏实现的数字示波器

网盘链接:https://pan.baidu.com/s/1WvDpZaFYJQbCZfkTKYdd6w
提取码:2333

一、移植文件

将 queue.c 、 queue.h两个文件添加到过程文件夹下

1.1 queue.c

#include "queue.h"
#include "key.h"
#include "delay.h"


#define xpos 254
#define ch1_on 1//定义通道1打开 
#define ch2_on 1//定义通道2打开 

float queue1[MAXSIZE];
float queue2[MAXSIZE];

int lowfflag=0;	
int key_par=2;

float Getmax(float *queue)
{
	int max = 0;
	int i;
	for (i = 1; i < MAXSIZE; i++)
	{
		if (queue[i] > queue[max])
		{
			max = i;
		}
	}
	return queue[max];
}

float Getmin(float *queue)
{
	int min = 0;
	int i;
	for (i = 1; i < MAXSIZE; i++)
	{
		if (queue[i] < queue[min])
		{
			min = i;
		}
	}
  return queue[min];
}

void draw_grid()//画网格
{
	int m_wid = 1;
	int i;
	GUI_SetColor(GUI_YELLOW);
	for (i = 0; i <= 10; i++)
	{
		if (i <= 8)
			GUI_DrawLine(0 + m_wid, i * 29 + m_wid, 251, i * 29 + m_wid);
		GUI_DrawLine(i * 25 + m_wid, 0 + m_wid, i * 25 + m_wid, 233);
	}
}

void Clear(int num, int step, int x)
{
	GUI_SetBkColor(GUI_BLACK);
	if (num == 0)//第一列矩形
		GUI_ClearRect(x, 0, x + step, 240);	

	else if (num == 1)//第二列矩形
		GUI_ClearRect(x, 0, x + step, 240);	

	else if (num == 2)//第二列矩形
		GUI_ClearRect(250, 0, 280, 240);

	draw_grid();//画网格
}

int countnum(float *queue, float max, float min)
{
	float tempuse; 
	int i;
	int pos = 1;
	int sum = 0;
  float avg = (max + min) / 2;   
  
	if (queue[0] > 0)
		tempuse = 1;
	else
		tempuse = -1;

	for (i = 1; i < MAXSIZE; i++)
	{
		if (tempuse * (queue[i] -avg) < 0) //记下第一个异号的数据下标 并退出循环
		{
			pos = i;
			break;
		}
	}

  if(i == MAXSIZE)//如果到最后一个数据前都未找到第一个异号的数据  则直接返回
    return -1;
      
	for (; pos < MAXSIZE; pos++)
	{
		if (tempuse * (queue[pos] -avg) < 0)//从第一个异号的数据  后续的异号数据均计数 
		{
			sum++;
		}
		else//从第一个异号的数据后找到第一个同号的数据 则计数结束
		{
			return sum;
		}
	}
  
  return -1;//程序不会到这里 去掉warning
}


void show_f(float max1,float min1,float max2,float min2)
{
  int ypos;
	GUI_SetFont(&GUI_Font20_ASCII);
	GUI_SetColor(GUI_YELLOW);

//显示f1频率
#ifdef ch1_on 
  //float f1 = (50 / (countnum(queue1, max1, min1) * 2 * 0.0225096))*16.31 - 2.6832;
  float f1 = (50 / (countnum(queue1, max1, min1) * 2 * 0.0225096))*14.5031 - 2.6832;
	ypos = 80;
	GUI_DispStringAt("f1:", xpos, ypos);

	ypos += 20;
	GUI_GotoXY(xpos, ypos);					//移动光标 显示频率
	if (lowfflag==1||lowfflag==3) f1 /= 14;
	if (f1 > 2000 || f1< 0)
    GUI_DispStringAt("******   ", xpos, ypos);
  else
		GUI_DispFloat(f1, 6);
#endif

//显示f2频率
#ifdef ch2_on
  //float f2 = (50 / (countnum(queue2, max2, min2) * 2 * 0.0225096))*16.31 - 2.6832;
  float f2 = (50 / (countnum(queue2, max2, min2) * 2 * 0.0225096))*14.5031 - 2.6832;
	ypos = 200;
	GUI_DispStringAt("f2:", xpos, ypos);

	ypos += 20;
	GUI_GotoXY(xpos, ypos);					//移动光标 显示频率
	if (lowfflag==2||lowfflag==3) f2 /= 14;
	if (f2 > 2000 || f2 < 0)
    GUI_DispStringAt("******   ", xpos, ypos);
  else
		GUI_DispFloat(f2, 6);
#endif 
}

void show_maxmin(float max, float min, int adorder)
{
	int ypos = 0;
	GUI_SetFont(&GUI_Font20_ASCII);
	GUI_SetColor(GUI_YELLOW);
  if (adorder == 1)
  {
      ypos = 0;
      GUI_DispStringAt("min1:", xpos, ypos);
  }
  else
  {
      ypos = 120;
      GUI_DispStringAt("min2:", xpos, ypos);
  }
  
	ypos += 20;
	GUI_GotoXY(xpos, ypos);					//移动光标 显示最小值
	if (min < 0)
		GUI_DispFloat((min), 6);
	else
		GUI_DispFloat((min), 5);

	ypos += 20; 
  if (adorder == 1)
    GUI_DispStringAt("max1:", xpos, ypos);
  else
    GUI_DispStringAt("max2:", xpos, ypos);
  
	ypos += 20;
	GUI_GotoXY(xpos, ypos);					//移动光标 显示最大值
	if (max < 0)
		GUI_DispFloat((max), 6);
	else
		GUI_DispFloat((max), 5);
}

float getWID(float max, float min, int key_par)
{
	float WID;//获取垂直分辨率
	float avg;

	if (key_par == 1)
	{
		WID = 0.1;
	}
	else if (key_par == 2)
	{
		WID = 1.0;
	}
	else if (key_par == 0)
	{
		avg = (max + min) / 2;
		max -= avg;
		min -= avg;
		if (max > -min)
			WID = max / 4;
		else
			WID = -min / 4;
	}
	return WID;
}

void key_fun()//按键实现锁存、改变采样频率、改变图像纵向每格电压大小
{
    vu8 key = KEY_Scan(0);	//得到键值
		if (key == KEY1_PRES)//改变采样速率
      lowfflag = (1 + lowfflag)%4;//0(初始采样速率) 1(降低一通道采样速率) 2(降低二通道采样速率) 3(降低一、二通道采样速率) 循环    
    else if (key == WKUP_PRES)//设置电压档位
      key_par = (key_par + 1) % 3;//0(auto) 1(0.1V) 2(1V)循环    
    else if (key == KEY0_PRES)//实现图像静止
      	while (1)
				{
          delay_ms(10);//消抖
					key = KEY_Scan(0);	//得到键值
					if (key==KEY0_PRES)
					{
						  break;	 
					}
		   	}
}

void plot()
{
	int i = 0;//循环遍历时 开始的位置 队头
	int x = 0;//开始作图的起始横坐标
	int step = 250 / (int)MAXSIZE;  //相邻两个采样点X坐标差距
	float WID;//获取垂直分辨率
  float min1, max1, min2, max2;
//显示通道1极值
#ifdef ch1_on
  float ybef1, ynow1;//相邻两个要连线的点的纵坐标
  max1 = Getmax(queue1);//数组1中最大值
	min1 = Getmin(queue1);//数组1中最小值
  show_maxmin(max1, min1, 1);
#endif 
//显示通道2极值  
#ifdef ch2_on
  float ybef2, ynow2;//相邻两个要连线的点的纵坐标
  max2 = Getmax(queue2);//数组2中最大值
	min2 = Getmin(queue2);//数组2中最小值
  show_maxmin(max2, min2, 2);
#endif
   
  show_f(max1, min1, max2, min2);//显示频率
  
	Clear(0, step, x);//第一个黑色矩形的绘制
	for (i = 0; i < MAXSIZE - 1; i++)
	{
		Clear(1, step, x + step);//第二个黑色矩形的绘制
 
//通道1显示
#ifdef ch1_on
		WID = getWID(max1, min1, key_par);
		if (key_par == 0)//如果是autoset档位则使其尽量铺满屏幕
		{
			ybef1 = 117 - (queue1[i] - (max1 + min1) / 2) / WID * 29;
			ynow1 = 117 - (queue1[i + 1] - (max1 + min1) / 2) / WID * 29;
		}
		else
		{
			ybef1 = 117 - queue1[i] / WID * 29;
			ynow1 = 117 - queue1[i + 1] / WID * 29;
		}
		if (ybef1 <= 2) ybef1 = 2;//修改坐标 使其显示在屏幕网格范围内
		if (ynow1 <= 2) ynow1 = 2;
		if (ybef1 >= 233) ybef1 = 233;
		if (ynow1 >= 233) ynow1 = 233;

    GUI_SetColor(GUI_WHITE);	//ch1画白线
		GUI_DrawLine(x, ybef1, (x + step), ynow1);
#endif   
//通道2显示
#ifdef ch2_on
		WID = getWID(max2, min2, key_par);
		if (key_par == 0)//如果是autoset档位则使其尽量铺满屏幕
		{
			ybef2 = 117 - (queue2[i] - (max2 + min2) / 2) / WID * 29;
			ynow2 = 117 - (queue2[i + 1] - (max2 + min2) / 2) / WID * 29;
		}
		else
		{
			ybef2 = 117 - queue2[i] / WID * 29;
			ynow2 = 117 - queue2[i + 1] / WID * 29;
		}
		if (ybef2 <= 2) ybef2 = 2;//修改坐标 使其显示在屏幕网格范围内
		if (ynow2 <= 2) ynow2 = 2;
		if (ybef2 >= 233) ybef2 = 233;
		if (ynow2 >= 233) ynow2 = 233;

		GUI_SetColor(GUI_BLUE);		//ch2画蓝线
		GUI_DrawLine(x, ybef2, (x + step), ynow2);
#endif

    key_fun();//按键实现锁存、改变采样频率、改变图像纵向每格电压大小
    x += step;  
  }
}


1.2 queue.h

#include "2ddisplay.h"

#define MAXSIZE 250


float Getmax(float *queue);//获取数组最小值的下标
float Getmax(float *queue);//获取数组最大值的下标
void draw_grid(void);//画网格
void Clear(int num,int step,int x);//画黑色矩形实现部分区域的清屏 以达到扫描效果
int countnum(float *queue, float max, float min);//统计半个周期采样次数 用来求周期
void show_f(float max1,float min1,float max2,float min2);//显示频率
void show_maxmin(float max,float min,int adorder);//显示极值
float getWID(float max,float min,int key_par);//获取垂直分辨率
void key_fun(void);//按键实现锁存、改变采样频率、改变图像纵向每格电压大小
void plot(void);//做出图像

二、程序调用

2.1 main.c中添加变量
int lowfflag=0;	
int key_par=0;
#define k1  (7.4923)
#define b1  (-14.1525)
#define k2  (6.3584)
#define b2  (-10.4536)
extern float queue1[MAXSIZE];
extern float queue2[MAXSIZE];
2.1修改EMWINDEMO任务
//EMWINDEMO任务
void emwindemo_task(void *p_arg)
{
	int i;
	int adcx1,adcx2;
	float v_res1,v_res2;
	GUI_SetBkColor(GUI_BLACK);		//设置背景颜色
  GUI_Clear();
	uart_init(115200);	 	//串口初始化为115200
 	Adc1_Init();		  		//板载ADC1初始化
	Adc2_Init();		  		//板载ADC2初始化
	KEY_Init();         	//初始化与按键连接的硬件接口
	
	 while(1)
	 {		 	
			for (i = 0; i < MAXSIZE; i++)
			{			
				adcx1 =	Get_Adc1(ADC_Channel_1);//PA1   ad1读出的数值 0-4095 
			  v_res1=(float)adcx1*(3.3/4096);	
				//v_res1=v_res1*k1+b1;  	if(v_res1<0) v_res1+=0.07;//pa1线性校正
				queue1[i]=v_res1;
				
				if(lowfflag==1||lowfflag==3) delay_us(400);
			}	
			
			for (i = 0; i < MAXSIZE; i++)
			{					
				adcx2 =	Get_Adc2(ADC_Channel_4);//PA4    ad读出的数值 0-4095
				v_res2=(float)adcx2*(3.3/4096);	
				//v_res2=v_res2*k2+b2;//pa2线性校正
				queue2[i]=v_res2;

				if(lowfflag==2||lowfflag==3) delay_us(400);
			}	
			draw();//做出曲线图像			
		}
}

三、硬件电路设计

板载ADC前硬件设计如下。可采集VPP为20V,频率为10-2kHz的交流信号。

  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值