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

    文章

    2003

    浏览量

    93028
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73135

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    工程师变身AI“指挥者”,吉利与阿里云的软件开发变革实验

    1975年,IBM工程师Fred Brooks在《人月神话》中提出软件工程的核心难题:随着系统规模和团队规模增长,复杂度会呈指数级上升。他的结论是, 软件工程“没有银弹”,没有单一技术
    的头像 发表于 11-13 10:43 201次阅读
    <b class='flag-5'>工程师</b>变身AI“指挥者”,吉利与阿里云的<b class='flag-5'>软件</b>开发变革实验

    从电路板到创新领袖:电子技术人才的进阶之路

    电子技术人才的潜力。案例3:女性工程师的突破之路张工,某半导体公司工艺工程师,在男性主导的领域取得突出成就:创新\"晶圆级封装工艺\",良品率提升15个百分点开发\"智能检测
    发表于 08-22 15:18

    电子发烧友工程师电子领域评职称,技术之路更扎实

    电子发烧友的各位工程师、硬件开发者们,咱们每天在平台查芯片手册、讨论电路设计难题、分享嵌入式项目经验,从调试 PCB 板到开发 AIoT 系统,靠的都是过硬的技术实力 —— 而电子领域
    发表于 08-20 13:53

    硬件工程师的 “鄙视链” 新动向:代码的,凭啥瞧不起画图的?

    “  在海外硬件工程师的世界里,一场关于设计灵魂归属的“圣战”已悄然打响。一边是信奉“所见即所得”、手握鼠标精雕细琢的“画图派”;另一边,则是高举“代码即真理”、用键盘召唤电路的“码派”。这不
    的头像 发表于 08-06 11:21 3210次阅读
    硬件<b class='flag-5'>工程师</b>的 “鄙视链” 新动向:<b class='flag-5'>写</b><b class='flag-5'>代码</b>的,凭啥瞧不起画图的?

    做了电子工程师之后,最好拍的视频出现了#硬件设计 #电子DIY #电子工程师

    电子工程师
    安泰小课堂
    发布于 :2025年06月24日 17:45:57

    电子工程师自学速成——入门篇

    本文共3册,由于资料内存过大,分开上传,有需要的朋友可以去主页搜索下载哦~ 电子工程师自学速成分为:入门篇、提高篇和设计篇,本文为入门篇,内容包括电子技术入门基础、电子元器件(电阻器
    发表于 05-15 15:50

    (仰天长啸)为什么受伤的总是硬件工程师...#MDD#MDD辰达半导体 #电子工程师

    电子工程师
    MDD辰达半导体
    发布于 :2025年04月27日 18:21:47

    工程师经验分享:社区之星 赵云 沉着稳定才能做好技术

    控制算法理论和实践有过推导和大量的研发调试经验。   工作经历: 华为技术有限公司---芯片验证工程师 上海问问网络科技有限公司---电机驱动软件工程师       社区访谈: 社区小助手:可以分享一下您的学习、工作经历吗,您是
    的头像 发表于 04-15 15:58 988次阅读
    <b class='flag-5'>工程师</b>经验分享:社区之星  赵云 沉着稳定才能做好<b class='flag-5'>技术</b>

    如何成为一名嵌入式软件工程师

    软件工程师保持持续学习的态度,紧跟技术发展趋势;同时,注重实践经验的积累,积极参与实际项目的开发和调试工作。 此外,还应不断提升自己的沟通能力和团队协作能力,以适应日益复杂的工作环境。 嵌入式
    发表于 04-15 14:37

    工程师手册:常用电子物料封装及参数介绍

    汇总了工程师常见的电子物料的封装及参数介绍,虽然是资料,不过手册查看方便 纯分享贴,有需要可以直接下载附件获取资料! (如果内容有帮助可以关注、点赞、评论支持一下哦~)
    发表于 03-28 16:48

    一招拿捏电子工程师#被AI拿捏了 #电子工程师 #电子电工

    电子工程师
    安泰小课堂
    发布于 :2025年03月25日 17:30:51

    嵌入式软件工程师就业好不好?

    嵌入式软件工程师就业好不好?会不会越越吃香?今天一起来看看。 首先看下市场需求。 随着物联网、人工智能、5G等前沿技术的快速发展,嵌入式系统的应用领域不断扩大,从智能家居、汽车电子
    发表于 02-20 10:19