2019年全国大学生电子设计大学(D 题)简易电路特性测试仪(2)基础部分电路与代码
先看基础部分第一问,首先经过测试,我的共射放大电路的放大倍数是280左右(分立元件每个人都不一样),选择放大倍数越小的三极管越好做(1)中有作解释。
基础部分硬件
输入电阻
DDS输出的正弦波幅值为1.1v,经过分压后,串联一个电阻,根据公式计算即可得出。电路图如下:
上面那一路是分压十分之一,底下是百分之一,先说上面的作用,可以看到,上面是DDS接跟随后,经过隔直,再经过跟随后串联电阻,因为题目要求做的是输入电阻1K-50K,范围跨度比较大,所以在输入电阻比较大时串联大电阻,比较小时串联小电阻。
因为在实际过程中,AD对波形峰值判断不准(我也不懂为什么,我的学长也是同样的情况),加了算法以后效果不是特别理想,所以采用AD637峰值检波模块,这里介绍一下AD637,也算是记录一下这个芯片性能,以免忘掉。
AD637 是一款完整的高精度、单芯片均方根直流转换器,可计算任何复杂波形的真均方根值。它提供集成电路均方根直流转换器前所未有的性能,精度、带宽和动态范围与分立和模块式设计相当。AD637 提供波峰因数补偿方案,允许以最高为 10 的波峰因数测量信号,额外误差小于 1%。宽带宽允许测量 200 mV 均方根、频率最高达 600 kHz 的输入信号以及 1V 均方根以上、频率最高达 8 MHz 的输入信号。
中文资料网上都有,这里就不啰嗦了
原理图
当±5V供电时,输入有效值电压范围:0 ~ 3 V,当±15V供电时,输入有效值电压范围:0 ~ 6 V
所以直接将检出来的值接给AD,误差非常小并且非常稳定。
输出电阻与输入电阻非常类似,就不再详细展开说明了。
放大倍数
放大倍数是输入放大电路的Ui和带载的Uo,不可以直接拿DDS输出或者分压的输出算,必须是进入放大电路的Ui,直接用32AD两个通道采集峰值检波的值就一除就可以了。
幅频特性曲线
幅频特性曲线(1)中说过,要保证DDS在变频时,幅值变化不大,不然需要重新采集输入,会消耗时间,题目是有时间规定的,超时扣分。
(1)中提到过,可以用示波器或者扫频仪先测量出0.707倍时对应的频率,方便代码编写DDS输出频率
经测量我手头9850在100HZ-20M幅值都是1.1V,故不需要采集输入,因为输入端固定不变。测量后上下限频率分别是260HZ到十几MHZ,用DDS变一次频率就算一次放大倍数,最后将其显示在stm32lcd屏幕上。
需要注意的是:
一在放大倍数有变化的端可以多采集一些点,在中间放大倍数很固定的点可以少采集一点,这样曲线就会很平滑,不会像一次函数一样非常直。
二电阻分压噪声还是有些大,用运放会好一点。
基础部分硬件到这里就结束了,基础分是很好拿的,几乎没有难度很流畅。
代码
#include "adc.h"
#include "delay.h"
#include "stdio.h"
#include "math.h"
#include "lcd.h"
#include "led.h"
#include "ad9850.h"
u8 Res_select=0;
u32 large_Res=20000;
u32 little_Res=3000;
u32 ui1=55; //DDS_OUT直接用万用表测量解写入代码(单位:mv)
//DDS输出1.1v 经过分压后值是可知的不需要用ad或者峰值检波测量
//但为了误差小数据精确 用台式万用表测量写入代码
//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3
void Adc1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 3; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
//设置指定ADC的规则组通道,一个序列,采样时间
//ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
//ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 2, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
//ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 3, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
// ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc1(u8 ch)
{
// //设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
u16 Get_Adc_Average1(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc1(ch);
delay_ms(5);
}
return temp_val/times;
}
/*
//可以采用此函数计算波形峰值 但ad采不准 故我采用的方案为峰值检波
//用ad直接采集峰值检波口的波形幅值比较精确
#define N 50
u16 filter(u8 ch,u8 times)
{
char count,i,j;
u32 Value_buf[N];
u32 temp;
u32 sum=0;
for(count=0;count<N;count++)
Value_buf[count]= 0;
for(count=0;count<N;count++)
Value_buf[count]= Get_Adc1(ch);
for(j=0;j<(N-1);j++)
for(i=0;i<(N-j);i++)
if(Value_buf[i]>Value_buf[i+1])
{
temp = Value_buf[i];
Value_buf[i]= Value_buf[i+1];
Value_buf[i+1]=temp;
}
for(count =1;count<N-1;count++)
sum += Value_buf[count];
return (u16)(sum/(N-2));
}
void adc_ch_data(u8 Channel)
{
u32 adcx[128];
u16 i;
for(i=0;i<128;i++)
{
adcx[i] = Get_Adc_Average1(Channel,10); // 检测通道1的电压
printf("%d\r\n",adcx[i]);
}
}
*/
void get_resin(void)
{
float res_in=0;
float adc_ch10=0;
float adc_ch10_v=0;
jidianqi7=0;
delay_ms(200);
adc_ch10 = Get_Adc_Average1(ADC_Channel_10,10); //采集通道1 的adc数值
//Y1=0.6715X-1.2403
//adc_ch10_v=((((adc_ch10+1.2403)/0.6715)*2)/80);
adc_ch10_v=((((adc_ch10+1.2403)/0.6715)*2)/110);
//将其转换为电压
//将其反算回去以后乘2的目的是使用峰峰值
//除100的目的是 因为这个值比较小 实际测量中只有4mv
//所以我在4mv输出后加了一级放大倍数为80倍的同相比例放大
//故要在代码中除100 若不加放大则不需要除这100
//不加放大测量结果正确 但是因为幅值比较小 采集不稳定 值跳变的厉害 但有正确的结果
delay_ms(200);
if(Res_select==1)
{
res_in=(adc_ch10_v*large_Res)/(ui1-adc_ch10_v);
//输入电阻计算公式: (Ui2*R)/(Ui1-Ui2)
}
else
{
res_in=(adc_ch10_v*little_Res)/(ui1-adc_ch10_v);
}
printf("%f\r\n",res_in);
//res_in=res_in/1000;
LCD_ShowxNum(100,0, res_in,5,24,0);//显示ADC的值
LCD_ShowxNum(100,120, adc_ch10_v,5,24,0);//显示ADC的值
//printf("%f\r\n",res_in);
}
void get_resout(void)
{
float res_out=0;
float adc_ch11=0;
float adc_ch11_1=0;
float adc_ch11_v1=0;
float adc_ch11_v2=0;
jidianqi6=1; //空载
//Y1=0.6715X-1.2403
adc_ch11 = Get_Adc_Average1(ADC_Channel_12,10); //采集通道11 的adc数值
//adc_ch11_v1=(((adc_ch11+1.2403)/0.6715)*2)+1.1; //将其转换为电压
//adc_ch11_v1=adc_ch11*3.3/4096;
//jidianqi闭合 低电平
jidianqi6=0; //带载
LCD_ShowxNum(100,150, adc_ch11_v1,5,24,0);//显示ADC的值
delay_ms(500);
adc_ch11_1 = Get_Adc_Average1(ADC_Channel_12,10); //采集通道11 的adc数值
//adc_ch11_v2=adc_ch11_1*3.3/4096;
//adc_ch11_v2=(((adc_ch11_1+1.2403)/0.6715)*2);
//输出电阻测量 Ro=(Uo1-Uo2)*R/Uo2 R:带载阻值
LCD_ShowxNum(100,180, adc_ch11_v2,5,24,0);//显示ADC的值
//res_out=((adc_ch11_v1-adc_ch11_v2)*2000)/adc_ch11_v2;
res_out=((adc_ch11-adc_ch11_1)*2000)/adc_ch11_1;
//res_out=((adc_ch11-adc_ch11_1)*2000)/adc_ch11_1;
delay_ms(2);
//res_out=res_out/1000;
//printf("%f\r\n",res_out);
LCD_ShowxNum(100,30, res_out,5,24,0);//显示ADC的值
}
void get_Au(void)//增益
{
u16 Au=0;
float Uo=0;//经过放大电路以后并未通过继电器的波形峰值
//输出的波形峰值需要将直流量减掉 再进行峰值检波
float Ui_v=0;
float Uo_v=0;
float Ui=0;//输入放大电路的波形峰值
Ui= Get_Adc_Average1(ADC_Channel_10,10);
Ui_v=((((Ui+1.2403)/0.6715)*2)/100);
delay_ms(200);
Uo= Get_Adc_Average1(ADC_Channel_12,10);
Uo_v=(((Uo+0.12)*4)-6.35)*2;
//Uo_v=(((Uo+1.2403)/0.6715)*2);
delay_ms(10);
Au=Uo_v/Ui_v;
//printf("%d\r\n",Au);
LCD_ShowxNum(100,60, Au,5,24,0);//显示ADC的值
}
输入电阻、输出电阻、放大倍数都封装成了函数,在主函数中直接调就可以了。
幅频特性曲线坐标显示:
void zuobiao(void)
{
POINT_COLOR = RED;
LCD_Display_Dir(0);
LCD_ShowString(30,0,210,24,24,"Ri = ");
LCD_ShowString(30,30,210,24,24,"R0 = ");
// LCD_ShowString(30,60,210,24,24,"fL = ");
// LCD_ShowString(30,90,210,24,24,"fH = ");
LCD_ShowString(30,60,210,24,24,"Au = ");
LCD_DrawLine(0,305,240,305);
LCD_DrawLine(15,140,15,320); //x轴y轴
LCD_DrawLine(240,305,230,315);
LCD_DrawLine(240,305,230,295); //箭头
LCD_DrawLine(15,140,5,150);
LCD_DrawLine(15,140,25,150); //箭头
LCD_DrawLine(40,305,40,300);
LCD_DrawLine(65,305,65,300);
LCD_DrawLine(90,305,90,300);
LCD_DrawLine(115,305,115,300);
LCD_DrawLine(140,305,140,300);
LCD_DrawLine(165,305,165,300);
LCD_DrawLine(195,305,195,300);
LCD_DrawLine(15,275,20,275);
LCD_DrawLine(15,245,20,245);
LCD_DrawLine(15,215,20,215);
LCD_DrawLine(15,185,20,185);
LCD_ShowString(220,307,200,12,12,"Hz");
LCD_ShowString(20,307,200,12,12,"100");
LCD_ShowString(40,307,200,12,12,"200");
LCD_ShowString(60,307,200,12,12,"1K");
LCD_ShowString(80,307,200,12,12,"1.5K");
LCD_ShowString(100,307,200,12,12,"10K");
LCD_ShowString(120,307,200,12,12,"50K");
LCD_ShowString(140,307,200,12,12,"100K");
LCD_ShowString(160,307,200,12,12,"150K");
LCD_ShowString(180,307,200,12,12,"170K");
LCD_ShowString(2,270,200,12,12,"80");
LCD_ShowString(2,240,200,12,12,"10O");
LCD_ShowString(2,210,200,12,12,"12O");
LCD_ShowString(2,180,200,12,12,"14O");
LCD_ShowString(7,307,200,12,12,"O");
LCD_Display_Dir(1);
LCD_ShowString(145,0,200,12,12,"Gain");
LCD_Display_Dir(0);
}
幅频特性曲线的显示:
//因为我手头的AD9850在变频率的时候不会变幅值
//9854在变频率的时候会改变幅值
//测量幅频特性曲线的时候 需要测量增益 若是DDS输出不变则不需要每次变频率采输入幅值
//同理若是变频率扫频时 幅值会变 则每变一次频率就应该采集一次输入 代码工作量比较大
//幅频特性曲线显示
float signal[11]={100,200,500,1000,10000,50000,100000,150000,170000};//DDS输出频率
void boxin(void)
{
u32 Ui1=55; //DDS_OUT直接用万用表测量解写入代码(单位:mv)
//DDS输出1.1v 经过分压后值是可知的不需要用ad或者峰值检波测量
//但为了误差小数据精确 用台式万用表测量写入代码
u8 Au[9]={0,0,0,0,0,0,0,0,0};
u8 i;
float adc_ch11_1=0;
float adc_ch11_v2=0;
for(i=0;i<11;i++)
{
ad9850_wr_serial(0x00,(double)signal[i]);//DDS输出信号
adc_ch11_1 = Get_Adc_Average1(ADC_Channel_12,10); //采集通道11 的adc数值
adc_ch11_v2=(((adc_ch11_1+1.2403)/0.6715)*2)+1.1; //将其转换为电压
Au[i]=adc_ch11_v2/Ui1;
}
// for(i=0;i<8;i++)
// {
// au[i]=Au[i];
// }
// au[5]=au[4]-30;
// au[6]=au[4]-60;
// au[7]=au[4]-100;
LCD_DrawPoint(20,305-Au[0]/20*30);
LCD_DrawPoint(40,305-Au[1]/20*30);
LCD_DrawPoint(60,305-Au[2]/20*30);
LCD_DrawPoint(80,305-Au[3]/20*30);
LCD_DrawPoint(100,305-Au[4]/20*30);
LCD_DrawPoint(120,305-Au[5]/20*30);
LCD_DrawPoint(140,305-Au[6]/20*30);
LCD_DrawPoint(160,305-Au[7]/20*30);
LCD_DrawPoint(180,305-Au[8]/20*30);
LCD_DrawLine(20,305-Au[0]/20*30,40,305-Au[1]/20*30);
LCD_DrawLine(40,305-Au[1]/20*30,60,305-Au[2]/20*30);
LCD_DrawLine(60,305-Au[2]/20*30,80,305-Au[3]/20*30);
LCD_DrawLine(80,305-Au[3]/20*30,100,305-Au[4]/20*30);
LCD_DrawLine(100,305-Au[4]/20*30,120,305-Au[5]/20*30);
LCD_DrawLine(120,305-Au[5]/20*30,140,305-Au[6]/20*30);
LCD_DrawLine(140,305-Au[6]/20*30,160,305-Au[7]/20*30);
LCD_DrawLine(160,305-Au[7]/20*30,180,305-Au[8]/20*30);
// LCD_DrawLine(65,305-Au[1]*t,70,305-Au[1]*t+k2*5-4);
// LCD_DrawLine(70,305-Au[1]*t+k2*5-4,75,305-Au[1]*t+k2*10-5);
// LCD_DrawLine(75,305-Au[1]*t-5+k2*10,80,305-Au[1]*t+k2*15-4);
// LCD_DrawLine(80,305-Au[1]*t-4+k2*15,85,305-Au[1]*t+k2*20-3);
// LCD_DrawLine(85,305-Au[1]*t-3+k2*20,90,305-Au[2]*t);
// LCD_DrawLine(40,305-Au[0]*t,65,305-Au[1]*t);
// LCD_DrawLine(65,305-Au[1]*t,90,305-Au[2]*t);
// LCD_DrawLine(90,305-Au[2]*t,115,305-Au[3]*t);
// LCD_DrawLine(115,305-Au[3]*t,140,305-Au[4]*t);
// LCD_DrawLine(140,305-Au[4]*t,148,305-Au[5]*t);
// LCD_DrawLine(148,305-Au[5]*t,156,305-Au[6]*t);
// LCD_DrawLine(156,305-Au[6]*t,165,305-Au[7]*t);
// LCD_DrawLine(165,305-Au[7]*t,195,305-Au[8]*t);
}
上面就是基础部分的全部了,都是已经测试完毕了的,没有问题。
2019年全国大学生电子设计大学(D 题)简易电路特性测试仪(2)基础部分电路与代码相关推荐
- 2019年全国大学生电子设计大学(D 题)简易电路特性测试仪(1)整题思路方案分析
2019年全国大学生电子设计大学(D 题)简易电路特性测试仪,此题是特别经典的一道题,对于不选控制类题目的同学,这个题非要有必要训练一下,这个题综合性比起2021年E题收发器难度会差一些,但是还是很考 ...
- 2017全国大学生电子设计竞赛H题:远程幅频特性测试仪:主控STM32F407
2017年全国大学生电子设计竞赛 远程幅频特性测试仪(H题) [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9sPfFjy1-1618627176227)(media/ ...
- 线路负载及故障检测装置(2019全国大学生电子设计大赛C题:国家级一等奖)
这个东西是今年(2019年)全国大学生电子设计大赛C题,经过4天3夜得辛苦奋斗,完成得题目要求得指标,最后也取得了一个不错得成绩. 题目要求如下: 题目三个大的要求:测电容.电感.电阻值, ...
- 2019 年TI杯全国大学生电子设计竞赛H题模拟电磁曲射炮
2019 年TI杯全国大学生电子设计竞赛H题模拟电磁曲射炮 前言 首先要肯定电子设计竞赛的含金量,而也正是电子设计竞赛给了我本科阶段最好的体验.此文章介绍的作品是我所在团队于2019年参加电赛的参赛作 ...
- 【电子设计大赛】2019 年全国大学生电子设计竞赛 仪器设备和主要元器件清单
文章目录 2019 年全国大学生电子设计竞赛 仪器设备和主要元器件清单 本科组 1.仪器设备清单 2. 主要元器件清单 高职高专组 1. 仪器设备清单 2. 主要元器件清单 2019 年全国大学生电子 ...
- 2019 年全国大学生电子设计竞赛 仪器设备和主要元器件清单√☺♥
@[TOC](2019 年全国大学生电子设计竞赛 仪器设备和主要元器件清单)√☺♥ [本科组] 1. 仪器设备清单 数字示波器(500MHz,双通道) 带 Z 轴输入端子的示波器(100MHz) 函数 ...
- 2019年全国大学生电子设计竞赛综合测评题解析
2019年全国大学生电子设计竞赛综合测评题解析 题目如下,设计制作电路产生下列四路信号: 1.频率为19kHz ~ 21kHz连续可调的方波脉冲信号,幅度不小于3.2V: 2.与方波同频率的正弦波信号 ...
- 2019全国大学生电子设计大赛H题 模拟电磁炮系统全国一等奖
2019全国大学生电子设计大赛H题 模拟电磁炮系统全国一等奖 作者 xxx 队友 阿华 狗子 (想要比赛指导的可以xian鱼搜索 电子设计竞赛国一竞赛指导(发布人为晨星)) (想要源码和我比赛时候准备 ...
- 桂电全国计算机设计大赛获奖名单,广西教育厅网:桂电学子在2019年全国大学生电子设计竞赛中再创佳绩...
来源:广西教育厅网 近日,2019年全国大学生电子设计竞赛结果公布,桂林电子科技大学学子获得全国一等奖8项(本科组6项.高职高专组2项).二等奖9项(本科组8项.高职高专组1项),在参赛的1109所院 ...
最新文章
- OpenCV中图像以Mat类型保存时各通道数据在内存中的组织形式及python代码访问各通道数据的简要方式...
- 「珍藏」老司机为你推荐10个炫酷的开源库,看完的人都收藏了
- MyEclipse中删除对Struts、hibernate、spring的支持
- Eigen 学习笔记
- iphone11屏比例_华为P50Pro概念图:回归经典的直面屏
- Deep-Learning-with-Python] 文本序列中的深度学习
- HDU 4777 Rabbit Kingdom 树状数组
- java使用gridview,java反射,用于GridView
- Python装饰器之一
- Observer(观察者)模式
- jquery操作CSS样式全记录
- 【Android】 修复ijkPlayer进行m3u8 hls流播放时seek进度条拖动不准确的问题
- Spring boot Redis客户端 乱码
- Linux如何整数分区,硬盘整数分区怎么计算?NTFS整数分区数值表分享
- python装饰器详解
- 利用vlmcs客户端区分KMS服务器是KMS模拟器还是正版微软KMS服务器
- 【Java+MySQL】使用JDBC连接MySQL 8.0数据库
- Cesium 源码分析 Material
- Endnote下载的pdf文件合并到同一个文件夹
- 宝峰uv5r怎么设置信道_宝峰UV-5R对讲机怎么操作?
热门文章
- 单纯性搜索算法 matlab函数,matlab : Nelder mead simplex 单纯形直接搜索算法;
- 进程同步生产者-消费者问题C语言,经典进程同步问题 --- 生产者和消费者
- ET篇:ETBook笔记(1.2 为什么使用C# .net core做服务端?)
- 思维方式-《思维的发现》书中的精髓:两个天才心理学家经历的奇妙经济学之旅。
- 系统升级: PHP(5.1.6-5.4.7) CI(1.7.2-2.1.2)调查记录
- 已知补码如何求原码、真值
- windows搭建Git服务器之Bonobo Git Server
- Serverless 底座的持续创新
- 为什么会对电视剧上瘾?
- Group Lasso-Based Band Selection for Hyperspectral Image Classification