将 queue.c 、 queue.h两个文件添加到过程文件夹下
#include "queue.h"
#include "key.h"
float queue1[MAXSIZE];
float queue2[MAXSIZE];
extern int lowfflag;
extern int key_par;
int Getmaxi(float *queue)
{
int max = 0;
int i;
for (i = 1; i < MAXSIZE; i++)
{
if (queue[i] > queue[max])
{
max = i;
}
}
return max;
}
int Getmini(float *queue)
{
int min = 0;
int i;
for (i = 1; i < MAXSIZE; i++)
{
if (queue[i] < queue[min])
{
min = i;
}
}
return min;
}
int countnum(float *queue)
{
float tempuse;
int i;
int pos;
int sum = 0;
if (queue[0] > 0)
tempuse = 1;
else
tempuse = -1;
for (i = 1; i < MAXSIZE; i++)
{
if (tempuse*queue[i] < 0) //记下第一个异号的数据下标 并退出循环
{
pos = i;
sum++;
break;
}
}
for (; pos < MAXSIZE; pos++)
{
if (tempuse*queue[pos] < 0)
{
sum++;
}
else
{
return sum;
}
}
return -1;
}
void show_f(void)
{
#define xpos 254
int ypos;
float f1 = f1 = (50 / (countnum(queue1) * 2 * 0.0225096))*14.5031 - 2.6832;
float f2 = f2 = (50 / (countnum(queue2) * 2 * 0.0225096))*14.5031 - 2.6832;
GUI_SetFont(&GUI_Font20_ASCII);
GUI_SetColor(GUI_YELLOW);
ypos = 80;
GUI_DispStringAt("f1:", xpos, ypos);
ypos += 20;
GUI_GotoXY(xpos, ypos); //移动光标 显示频率
if (lowfflag==1||lowfflag==3) f1 /= 14;
if (f1 > 0)
GUI_DispFloat(f1, 6);
ypos = 200;
GUI_DispStringAt("f2:", xpos, ypos);
ypos += 20;
GUI_GotoXY(xpos, ypos); //移动光标 显示频率
if (lowfflag==2||lowfflag==3) f2 /= 14;
if (f2 > 0)
GUI_DispFloat(f2, 6);
}
void show_maxmin(float max, float min, int adorder)
{
#define xpos 254
int ypos = 0;
GUI_SetFont(&GUI_Font20_ASCII);
GUI_SetColor(GUI_YELLOW);
if (adorder == 1)
{
ypos = 0;
GUI_DispStringAt("min1:", xpos, ypos);
ypos += 20;
GUI_GotoXY(xpos, ypos); //移动光标 显示最小值
if (min < 0)
GUI_DispFloat((min), 6);
else
GUI_DispFloat((min), 5);
ypos += 20;
GUI_DispStringAt("max1:", xpos, ypos);
ypos += 20;
GUI_GotoXY(xpos, ypos); //移动光标 显示最大值
if (max < 0)
GUI_DispFloat((max), 6);
else
GUI_DispFloat((max), 5);
}
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;
GUI_DispStringAt("max2:", xpos, ypos);
ypos += 20;
GUI_GotoXY(xpos, ypos); //移动光标 显示最大值
if (max < 0)
GUI_DispFloat((max), 6);
else
GUI_DispFloat((max), 5);
}
}
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);
}
}
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 mod1queue1(float max1, float min1)
{
float avg1 = (max1 + min1) / 2;
int i;
for (i = 0; i < MAXSIZE; i++)
{
queue1[i] -= avg1;
}
}
void mod1queue2(float max2, float min2)
{
float avg2 = (max2 + min2) / 2;
int i;
for (i = 0; i < MAXSIZE; i++)
{
queue2[i] -= avg2;
}
}
void mod2queue1(float max1, float min1)
{
float avg1 = (max1 + min1) / 2;
int i;
for (i = 0; i < MAXSIZE; i++)
{
queue1[i] += avg1;
}
}
void mod2queue2(float max2, float min2)
{
float avg2 = (max2 + min2) / 2;
int i;
for (i = 0; i < MAXSIZE; i++)
{
queue2[i] += avg2;
}
}
void shouparam(float max1, float min1, float max2, float min2)
{
show_maxmin(max1, min1, 1);
show_maxmin(max2, min2, 2);
if (max1 >= 0 && min1 >= 0)
mod1queue1(max1, min1);
if (max2 >= 0 && min2 >= 0)
mod1queue2(max2, min2);
show_f();
if (max1 >= 0 && min1 >= 0)
mod2queue1(max1, min1);
if (max2 >= 0 && min2 >= 0)
mod2queue2(max2, min2);
}
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();//画网格
}
void draw()
{
float ybef1, ynow1;//相邻两个要连线的点的纵坐标
float ybef2, ynow2;//相邻两个要连线的点的纵坐标
int i = 0;//循环遍历时 开始的位置 队头
int x = 0;//开始作图的起始横坐标
int step = 250 / (int)MAXSIZE; //相邻两个采样点X坐标差距
vu8 key = 0;//作为按键输入的返回值
float WID;//获取垂直分辨率
float max1 = queue1[Getmaxi(queue1)];//数组1中最大值
float min1 = queue1[Getmini(queue1)];//数组1中最小值
float max2 = queue2[Getmaxi(queue2)];//数组2中最大值
float min2 = queue2[Getmini(queue2)];//数组2中最小值
shouparam(max1, min1, max2, min2);//显示频率和极值
Clear(0, step, x);//第一个黑色矩形的绘制
for (i = 0; i < MAXSIZE - 1;)
{
Clear(1, step, x + step);//第二个黑色矩形的绘制
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;
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_WHITE); //ch1画白线
GUI_DrawLine(x, ybef1, (x + step), ynow1);
GUI_SetColor(GUI_BLUE); //ch2画蓝线向下移动一个像素 加以区分
GUI_DrawLine(x, ybef2 + 1, (x + step), ynow2 + 1);
x += step;
//按键实现锁存、改变采样频率、改变图像纵向每格电压大小
key = KEY_Scan(0); //得到键值
if (key)
{
switch (key)
{
case KEY1_PRES://改变采样速率
lowfflag = (1 + lowfflag)%4;//0(初始采样速率) 1(只降低一通道采样速率) 2(只降低二通道采样速率) 3(降低一、二通道采样速率)循环
break;
case WKUP_PRES://设置电压档位
key_par = (key_par + 1) % 3;//0(auto) 1(0.1V) 2(1V)循环
break;
case KEY0_PRES://实现图像静止
while (1)
{
key = KEY_Scan(0); //得到键值
if (key)
{
switch (key)
{
case KEY0_PRES://再按一下KEY0_PRES则 跳出此while 进行i++和下一步作图
goto B;
}
}
}
break;
}
}
//实现结束
B: i++;
}
}
#include "2ddisplay.h"
int Getmini(float *queue);//获取数组最小值的下标
int Getmaxi(float *queue);//获取数组最大值的下标
int countnum(float *queue);//统计半个周期采样次数 用来求周期
void show_maxmin(float max,float min,int adorder);//显示极值
void show_f(void);//显示频率
void shouparam(float max1,float min1,float max2,float min2);//显示极值和频率
void mod1queue1(float max1,float min1);//一通道数据都为非负数时同时减去极值的平均值 以用来求取频率和显示
void mod1queue2(float max2,float min2);//二通道数据都为非负数时同时减去极值的平均值 以用来求取频率和显示
void mod2queue1(float max1,float min1);//一通道求取频率时同时减去极值的平均值后 再加上减去的值
void mod2queue2(float max2,float min2);//二通道求取频率时同时减去极值的平均值后 再加上减去的值
void draw_grid(void);//画网格
float getWID(float max,float min,int key_par);//获取垂直分辨率
void draw(void);//做出图像
void Clear(int num,int step,int x);//画黑色矩形实现部分区域的清屏 以达到扫描效果
#define MAXSIZE 250
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];
//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();//做出曲线图像
}
}