网盘链接: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的交流信号。