0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

看电子技术的老软件工程师写代码说明

电子森林 来源:硬禾学堂 作者:硬禾学堂 2020-12-30 15:50 次阅读

ZY是一名热爱电子技术的老软件工程师,观望了两期Funpack活动后,在这一期上了车,功能实现得好,代码和说明还写得清楚明了,很值得学习。 以下,enjoy。

自我介绍

本人叫ZY,是一名软件工程师,从事软件开发工作十多年了,本身的工作是与互联网相关的应用系统设计开发工作,业余很喜欢电子技术,所以业余有空的时候会玩一些小的电子制作和开发的东西,之前有做过一些函数波形发生器、迷你示波器,探针等小东西。

实现功能

本次也是由于拿到板子太晚,也就仅仅基于作业要求,实现了简单的电阻测量功能,后续会继续挖掘更好玩的功能,目前考虑会做一个简单的示波器,可以通过蓝牙Wi-Fi把数据与Thingsboard结合实现,作业中使用了16bit的ADC,通过分压测试法实现了电阻测量功能。软件部分则是基于瑞萨提供的e2studio工具以及FSP2.1.0软件包,基于HAL库调用了ADC部分的函数实现的。软件部分采用了共计12次采样,抛弃前两次采样数据,再去掉最大最小值之后,求平均值的方式实现,同时计算采样数据的标准差用于评估测试结果的精准程度,这样可以在仅使用一只10K电阻分压的条件下,更好的提升测试精度。连接示意图如下:

e7925db4-4a28-11eb-8b86-12bb97331649.png

测试方法,按上图将开发版与面包板以及其他器件连接好,将开发板(已下载好程序)的DEBUG USB口与PC端的USB口相连,PC端启动J-Link RTT Viewer,通过RTT Terminal连接开发版,见下图

RTT Terminal连接成功后会打印出操作指引,见下图

下一步将待测电阻插入面包板对应的孔位中,在RTT Terminal中输入测试指令1,等待约1秒,RTT Terminal中会输出电阻测试结果(单位欧姆),以及测试结果所对应的采样平均值与样本集的标准差。见下图

代码说明

hal_entry.c 该文件是程序入口,hal_entry函数中打印了欢迎信息,而后阻塞等待用户来自RTT Terminal的输入,用户输入后调用adc_ep.c文件中的read_process_input_from_RTT(void) 函数进行命令处理。 adc_ep.c 该文件是主要的程序文件,以下进行简要的介绍: staticfloat std_dv(uint16_t samples[], uint8_t count)该函数是计算adc样本向量的标准差,用以评估样本向量的采样置信度; staticint32_t f2i(float ft)该函数是将浮点数转换为整数型,因为RTT Print无法输出浮点数,因此用此函数将浮点数的整数部分与小数部分分别转换后输出; staticvoid print_menus(void)该函数用于输出菜单项; fsp_err_tread_process_input_from_RTT(void)该函数用于读取用户来自RTT Terminal的输入,调用点在hal_entry.c的hal_entry()函数中; staticvoid resistor_estimation(void)该函数是用于基于adc_ch0的值来估算当前待测电阻的阻值,以下结合代码说明;

static void resistor_estimation(void){float r = 0;// adc的参考值非常接近于16bit ADC的测量范围的最大值(32767),因此为了不在除法计算中丢失精度,因此使用乘法计算这类数值。 if (adc_ch0 > 32750) { r = 0.32767 * (32767 - adc_ch0);}// 除法计算对精度影响不大的情况使用除法计算。 else { float adcv = adc_ch0; r = (32767 - adcv) / adc_ch0 * 10000; } int32_t int_v = f2i (r); int32_t deci_v = f2i ((r - int_v) * 1000); APP_PRINT("Estimation of resistor at channel 0 is: %d.%d (Ohm) ", int_v, deci_v);}uint16_tuint16_t_cmp(const void *a, const void *b)该函数用于qsort排序函数; staticfsp_err_t re_sample(void)该函数用于连续读取12次adc的采样值,丢弃前2次的采样值,并对后10次采样值排序,去掉最大与最小的两个值,而后对另外的8次采样值求平均值,以及计算这8次采样值向量的标准差,以下结合代码说明;

static fsp_err_t re_sample(void){ fsp_err_t err = FSP_SUCCESS; // Error status uint16_t single_read = 0;//读取并丢弃第一次ADC采样的数据 err = R_ADC_Read (&g_adc_ctrl, ADC_CHANNEL_0, &single_read); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** R_ADC_Read API on channel 0 failed ** "); return err; }R_BSP_SoftwareDelay (sample_delay, BSP_DELAY_UNITS_MILLISECONDS);//读取并丢弃第二次ADC采样的数据 err = R_ADC_Read (&g_adc_ctrl, ADC_CHANNEL_0, &single_read); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** R_ADC_Read API on channel 0 failed ** "); return err; } R_BSP_SoftwareDelay (sample_delay, BSP_DELAY_UNITS_MILLISECONDS); uint16_t samples[10] = { 0x00 };uint32_t sum_of_adc_reads = 0;//连续读取10次ADC采样数据 for (uint8_t i = 0; i < 10; i++) { single_read = 0; err = R_ADC_Read (&g_adc_ctrl, ADC_CHANNEL_0, &single_read); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** R_ADC_Read API on channel 0 failed ** "); return err; } if (1 > single_read || 32767 < single_read) { APP_ERR_PRINT("Read bad data on ADC channel 0, operation abort "); return FSP_ERR_ABORTED; } samples[i] = single_read; single_read = 0; R_BSP_SoftwareDelay (sample_delay, BSP_DELAY_UNITS_MILLISECONDS);}//对10次 ADC采样的数据排序 qsort (samples, 10, sizeof(uint16_t), uint16_t_cmp); uint16_t valid_samples[8] ={ 0x00 };//去除10次采样数据中的最大与最小值,并累加求和 for (uint8_t j = 0; j < 8; j++) { valid_samples[j] = samples[j + 1]; sum_of_adc_reads += samples[j + 1];}//计算过滤后的8次采样数据的标准差std_deviation = std_dv (valid_samples, 8);//计算过滤后的8次采样数据的平均值并赋值到adc_ch0变量 adc_ch0 = (uint16_t) (sum_of_adc_reads >> 3); return err;}

staticfsp_err_t adc_ch0_read(void)该函数用于启动并校准16bits ADC,而后调用re_sample函数读取的通道0的数据,以下结合代码说明;

static fsp_err_t adc_ch0_read(void){fsp_err_t err = FSP_SUCCESS; // Error status//判断ADC是否处于被占用的状态 if (false == adc_busy){ //开启16 bits ADC模块 /* Open/Initialize ADC module */ err = R_ADC_Open (&g_adc_ctrl, &g_adc_cfg); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** R_ADC_Open API failed ** "); return err; } // Delay for waiting for ADC be stable R_BSP_SoftwareDelay (5, BSP_DELAY_UNITS_MILLISECONDS); #ifdef BOARD_RA2A1_EK /* Set Reference Voltage Circuit Control register */ R_ADC0->VREFAMPCNT |= ((VREFADCG_VALUE << SHIFT_BY_ONE) | (VREFADCG_ENABLE << SHIFT_BY_THREE)); //根据芯片手册中的建议,16bits ADC使用前需要进行校准,这里调用函数校准ADC。 /* Calibrate the ADC */ err = adc_start_calibration (); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** adc_start_calibration function failed ** "); return err; }#endif //调用HAL库中的函数,配置ADC,这里配置为连续读取模式 /* Configures the ADC scan parameters */ err = R_ADC_ScanCfg (&g_adc_ctrl, &g_adc_channel_cfg); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** R_ADC_ScanCfg API failed ** "); return err; } //启动ADC采样 /* Start the ADC scan*/ err = R_ADC_ScanStart (&g_adc_ctrl); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** R_ADC_ScanStart API failed ** "); return err; } adc_busy = true; //调用函数re_sample()函数进行ADC数据采样,前文有详细说明该函数。 err = re_sample (); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** Sampling on ADC channel 0 failed ** "); return err; } uint8_t counter = 0; //基于调试结果分析,低阻值的电阻需要依赖采样的数据的一致性来保证测量精度,因此这里判断如果为低阻值数据,且采样数据标准差大于1.5则进行重新采样处理,共重试最多8次,直至采样数据符合要求,如果超过8次采样数据仍旧未能符合标准,则打印测量失败的通知到RTT Terminal提示用户。

if (32755 < adc_ch0 && 1.5f < std_deviation) { APP_PRINT( "Lower resistance value [1(Ohm) ~ 5(Ohm)] found and sampling quality too low, auto perform re-sampling... "); while (1.5f < std_deviation && 10 > counter) { err = re_sample (); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** Sampling on ADC channel 0 failed ** "); return err; } counter++; } } if (32755 < adc_ch0 && 1.5f < std_deviation) { APP_ERR_PRINT("Sampling quality too low, operation abort "); } else { //输出样本质量评估的标准差数据 int32_t int_stddv = f2i (std_deviation); int32_t deci_stddv = f2i ((std_deviation - int_stddv) * 1000); APP_PRINT("Standard deviation of samples is: %d.%d, samples quality is %s ", int_stddv, deci_stddv, std_deviation < 5 ? "GOOD" : "POOR"); //输出16 bits ADC采样的原始数据。 APP_PRINT("Sampling data at ADC channel 0 is: %d ", adc_ch0); //输出待测电阻的估算阻值。 resistor_estimation (); } //停止ADC连续采样 err = R_ADC_ScanStop (&g_adc_ctrl); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** R_ADC_ScanStop API failed ** "); return err; } adc_busy = false; //关闭ADC模块 err = R_ADC_Close (&g_adc_ctrl); if (FSP_SUCCESS != err) { APP_ERR_PRINT("** R_ADC_Close API failed ** "); return err; } } else { APP_PRINT("Resistor testing in progress "); } return err;}

staticfsp_err_t adc_start_calibration(void)该函数用于校准ADC。

活动体会

首先简单说一下瑞萨的这块板子,拿到手的比较晚,大概在12月10号左右拿到的,所以了解的也十分有限,因为要赶在20号前交作业,所以还来不及很充分的去看这个板子的内容。这块评估板不论做工还是设计都是十分不错的,该有的都有,需要配置和调整的地方也设计的比较灵活,概览了一下板子的手册,发现板子可玩性还是比较强的。 其次再说一下e2studio这款开发工具,对于我个人来说,这个开发工具真是太合我心意了。首先我使用eclipse应该快有20年了,从上学到工作中这些年一直也都在使用这个开发工具,十分的熟悉,应该说瑞萨选择以eclipse作为基础来打造开发环境,也就是因为eclipse在过去的20年中已经深入民心了,大部分的工程师尤其是软件工程师应该都有使用eclipse的经验;另外e2studio针对调试和配置两个部分做了很好的扩展,虽然界面没有stm32的那么华丽,但是功能简洁实用,软件的稳定程度也很高,在使用过程中还未遇到明显的错误。 最后说一下Funpark活动,这个活动确实很棒,建立交流群让共同的爱好者有一个共同的目标,一起讨论交流,这个是十分愉快也十分难得的;另外还会请来高水平老师给大家进行培训,帮助大家尽量解决问题,扫清了我们完成任务的障碍;最后是硬禾这个平台,在前段时间板子没到的时候,去过硬禾的网站和电子森林的站点,里边的确是包含了非常多的技术干货,着实是能帮助到电子爱好者甚至是专业从业人士的。 再次感谢硬禾与Digikey能够给大家提供这样一个好玩又能学知识的活动,实在是很棒。

原文标题:看老工程师写代码说明——Funpack第三期分享之二

文章出处:【微信公众号:FPGA入门到精通】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 电子
    +关注

    关注

    32

    文章

    1731

    浏览量

    88406
  • 代码
    +关注

    关注

    30

    文章

    4555

    浏览量

    66762

原文标题:看老工程师写代码说明——Funpack第三期分享之二

文章出处:【微信号:xiaojiaoyafpga,微信公众号:电子森林】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Cognition发布首款AI软件工程师Devin

    据报道,Cognition公司今日公布了其首款人工智能软件工程师——Devin,掀起了打造软件模式变革的序幕。该产品在SWE-bench代码测验中展现出卓越表现,甚至超过了部分顶级人类工程师
    的头像 发表于 03-13 10:57 380次阅读

    企业工程师和高校老师有啥区别

    电子工程师硬件
    电子发烧友网官方
    发布于 :2024年02月28日 17:50:00

    如何构建linux开发环境和编译软件工程、应用程序

    前文介绍了如何使用官方提供的镜像文件启动开发板,本文将说明如何构建linux开发环境和编译软件工程、应用程序。
    的头像 发表于 01-03 12:31 465次阅读
    如何构建linux开发环境和编译<b class='flag-5'>软件工程</b>、应用程序

    嵌入式软件工程师常用的

    最近我换工作了,看见不同嵌入式软件工程师用的平台都不一样,所以我整理了一下。PlatformIO:多平台支持:PlatformIO支持多种嵌入式平台,包括Arduino、ESP8266、ESP32
    的头像 发表于 12-24 08:00 235次阅读
    嵌入式<b class='flag-5'>软件工程师</b>常用的

    电子工程师第一天上班就暴揍师傅。。。#科普 #示波器 #电子工程师 #打工日记

    电子工程师示波器
    安泰小课堂
    发布于 :2023年12月18日 17:36:12

    嵌入式硬件和软件哪个好?

    这类技术都是经验的,经验越高,那他的身价也相应变高。据统计,65%的电子产品开发企业中,嵌入式软件开发工程师团队,往往只占全公司人数的5%
    发表于 12-05 15:17

    【热招】苏州,单片机工程师

    【单片机工程师】 3年及以上经验,要求有智能产品经验。 岗位职责: 1、根据MRD,与产品部等部门的需求,负责对新开发的产品进行可行性分析,主要负责分析产品的软件可实现性; 2、根据产品需求,完成
    发表于 11-28 14:02

    FPGA工程师需要具备哪些技能?

    工程师需要能够产生正确的测试数据集,以确保设计的准确性和性能。 在综合方面,FPGA工程师需要使用工具将HDL语言转化为更低级别的代码。这样,他们就能够顺利地将代码映射到可编程
    发表于 11-09 11:03

    电子工程师必备——九大系统电路识图宝典》+附录5学习方法

    jf_39110170 网名“还没吃饭”阅读《电子工程师必备 九大系统电路识图宝典第2版》附录5的读后感:探索科学学习方法 作为一名对电子技术学科充满热情的嵌入式工程师,你是否曾因学习
    发表于 10-06 23:25

    嵌入式软件好还是硬件好?

    电路、功放电路、高速信号传输线的匹配电路等;故障定位、解决问题的能力;设计文档的组织编写技能! 那对于嵌入式软件工程师来说: 嵌入式软件工程师领域较新,他的发展也是很快的,像这类技术都是
    发表于 09-18 15:31

    热门推荐:硬件工程师必备工具

    硬件开发的工作流程一般可分为:原理图设计、PCB Layout设计、采购电子BOM、PCB板生产、PCBA组装、功能调试及测试、小批量试产、大批量生产正式投放市场等步骤。 作为一名优秀的硬件工程师
    发表于 06-21 10:15

    电子工程师必看书籍推荐#知识分享 #知识科普 #交流#硬声创作季

    电子工程师
    也许吧
    发布于 :2023年05月24日 10:47:34