产品选型

crc 单片机 AOVX资产监测设备之华大单片机Boot软件升级

小编 2024-10-09 产品选型 23 0

AOVX资产监测设备之华大单片机Boot软件升级

近期笔者在研究如何从软件方面提升资产监测设备的性能,从而提升用户的使用体验感。

资产监测设备的主要作用是帮助用户监测设备的实时位置、实时状态避免运动中的货物出现丢失等情况。AOVX环境监测设备在智慧物流方面发挥了重要的作用,例如在运输贵重货物过程中,只需要将该设备安装在货物中,用户即可远程了解货物的位置、货物是否出现暴力扔件、以及避免货物在运输过程中的丢失。

资产监测设备中的华大单片机,对该设备的工作发挥了重要的作用。笔者的软件团队对单片机进行了软件升级。

具体流程如下:

具体流程如下:/**

** \brief 上位机数据帧解析及处理**** \param [in] None**** \retval Ok APP程序升级完成,并接受到跳转至APP命令** \retval OperationInProgress 数据处理中** \retval Error 通讯错误********************************************************************************/en_result_t Modem_Process(void){uint8_t u8Cmd, u8FlashAddrValid, u8Cnt, u8Ret;uint16_t u16DataLength, u16PageNum, u16Ret;uint32_t u32FlashAddr, u32FlashLength, u32Temp;

if (enFrameRecvStatus == FRAME_RECV_PROC_STATUS) //有数据帧待处理, enFrameRecvStatus值在串口中断中调整

{

u8Cmd = u8FrameData[PACKET_CMD_INDEX]; //获取帧指令码

if (PACKET_CMD_TYPE_DATA == u8FrameData[PACKET_TYPE_INDEX]) //如果是数据指令

{

u8FlashAddrValid = 0u;

u32FlashAddr = u8FrameData[PACKET_ADDRESS_INDEX] + //读取地址值

(u8FrameData[PACKET_ADDRESS_INDEX + 1] << 8) +

(u8FrameData[PACKET_ADDRESS_INDEX + 2] << 16) +

(u8FrameData[PACKET_ADDRESS_INDEX + 3] << 24);

if ((u32FlashAddr >= (FLASH_BASE + BOOT_SIZE)) && (u32FlashAddr < (FLASH_BASE + FLASH_SIZE))) //如果地址值在有效范围内

{

u8FlashAddrValid = 1u; //标记地址有效

}

}

switch (u8Cmd) //根据指令码跳转执行

{

case PACKET_CMD_HANDSHAKE : //握手帧 指令码

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //返回状态为:正确

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧给上位机

break;

case PACKET_CMD_ERASE_FLASH : //擦除flash 指令码

if ((u32FlashAddr % FLASH_SECTOR_SIZE) != 0) //如果擦除地址不是页首地址

{

u8FlashAddrValid = 0u; //标记地址无效

}

if (1u == u8FlashAddrValid) //如果地址有效

{

u32Temp = u8FrameData[PACKET_DATA_INDEX] + //获取待擦除flash尺寸

(u8FrameData[PACKET_DATA_INDEX + 1] << 8) +

(u8FrameData[PACKET_DATA_INDEX + 2] << 16) +

(u8FrameData[PACKET_DATA_INDEX + 3] << 24);

u16PageNum = FLASH_PageNumber(u32Temp); //计算需擦除多少页

for (u8Cnt=0; u8Cnt<u16PageNum; u8Cnt++) //根据需要擦除指定数量的扇区

{

u8Ret = Flash_EraseSector(u32FlashAddr + (u8Cnt * FLASH_SECTOR_SIZE));

if (Ok != u8Ret) //如果擦除失败,反馈上位机错误代码

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ERROR;

break;

}

}

if (Ok == u8Ret) //如果全部擦除成功,反馈上位机成功

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;

}else //如果擦除失败,反馈上位机错误超时标志

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_TIMEOUT;

}

}

else //地址无效,反馈上位机地址错误

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR;

}

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

break;

case PACKET_CMD_APP_DOWNLOAD : //数据下载 指令码

if (1u == u8FlashAddrValid) //如果地址有效

{

u16DataLength = u8FrameData[FRAME_LENGTH_INDEX] + (u8FrameData[FRAME_LENGTH_INDEX + 1] << 8)

- PACKET_INSTRUCT_SEGMENT_SIZE; //获取数据包中的数据长度(不包含指令码指令类型等等)

if (u16DataLength > PACKET_DATA_SEGMENT_SIZE) //如果数据长度大于最大长度

{

u16DataLength = PACKET_DATA_SEGMENT_SIZE; //设置数据最大值

}

u8Ret = Flash_WriteBytes(u32FlashAddr, (uint8_t *)&u8FrameData[PACKET_DATA_INDEX], u16DataLength); //把所有数据写入flash

if (Ok != u8Ret) //如果写数据失败

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ERROR; //反馈上位机错误 标志

}

else //如果写数据成功

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功 标志

}

}

else //如果地址无效

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR; //反馈上位机地址错误

}

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

break;

case PACKET_CMD_CRC_FLASH : //查询flash校验值 指令码

if (1u == u8FlashAddrValid) //如果地址有效

{

u32FlashLength = u8FrameData[PACKET_DATA_INDEX] +

(u8FrameData[PACKET_DATA_INDEX + 1] << 8) +

(u8FrameData[PACKET_DATA_INDEX + 2] << 16) +

(u8FrameData[PACKET_DATA_INDEX + 3] << 24); //获取待校验flash大小

if ((u32FlashLength + u32FlashAddr) > (FLASH_BASE + FLASH_SIZE)) //如果flash长度超出有效范围

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_FLASH_SIZE_ERROR; //反馈上位机flash尺寸错误

}else

{

u16Ret = Cal_CRC16(((unsigned char *)u32FlashAddr), u32FlashLength);//读取flash指定区域的值并计算crc值

u8FrameData[PACKET_FLASH_CRC_INDEX] = (uint8_t)u16Ret; //把crc值存储到应答帧

u8FrameData[PACKET_FLASH_CRC_INDEX+1] = (uint8_t)(u16Ret>>8);

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功 标志

}

}

else //如果地址无效

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR; //反馈上位机地址错误

}

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE+2); //发送应答帧到上位机

break;

case PACKET_CMD_JUMP_TO_APP : //跳转至APP 指令码

Flash_EraseSector(BOOT_PARA_ADDRESS); //擦除BOOT parameter 扇区

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

return Ok; //APP更新完成,返回OK,接下来执行跳转函数,跳转至APP

case PACKET_CMD_APP_UPLOAD : //数据上传

if (1u == u8FlashAddrValid) //如果地址有效

{

u32Temp = u8FrameData[PACKET_DATA_INDEX] +

(u8FrameData[PACKET_DATA_INDEX + 1] << 8) +

(u8FrameData[PACKET_DATA_INDEX + 2] << 16) +

(u8FrameData[PACKET_DATA_INDEX + 3] << 24); //读取上传数据长度

if (u32Temp > PACKET_DATA_SEGMENT_SIZE) //如果数据长度大于最大值

{

u32Temp = PACKET_DATA_SEGMENT_SIZE; //设置数据长度为最大值

}

Flash_ReadBytes(u32FlashAddr, (uint8_t *)&u8FrameData[PACKET_DATA_INDEX], u32Temp); //读flash数据

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功 标志

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE + u32Temp);//发送应答帧到上位机

}

else //如果地址无效

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR; //反馈上位机地址错误 标志

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

}

break;

case PACKET_CMD_START_UPDATE : //启动APP更新(此指令正常在APP程序中调用)

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功 标志

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

break;

}

enFrameRecvStatus = FRAME_RECV_IDLE_STATUS; //帧数据处理完成,帧接收状态恢复到空闲状态

}

return OperationInProgress; //返回,APP更新中。。。

}

同样从事软件工作相关的用户,对资产监测设备感兴趣的话可以参考该文档。

DIY,51单片机,SiC MOSFET,技术文章分享

做了一个小玩具 - 超声波喇叭

昨天发了个图,有好几个同好已经猜出来是超声波扬声器了,不过声音不是很大,所以我还是叫它超声波喇叭吧。(音质稀碎 ,有种80年代收音机的感觉,指向性发声 ,还是很好玩的)

b站上的是接音频线版本的,我觉得比较麻烦,所以买了个蓝牙音频模块(杰理 的芯片),很便宜很好用,5块多 一个,搜MH-18可以购买,还是挺好的一个小模块,喜欢的同好也可以买来做小音箱 。这个模块也是支持一个ADC按键调声音之类的,非常不错。

然后这个BLE_IN就是这个蓝牙模块的输出信号了,我把左右声道接到一起了,没有分开处理。然后BLE_IN这个音频信号经过电容耦合后接到NE555的CONT管脚,这个我也不太熟悉NE555,是根据网上的图照着接的。

大概就是让NE555输出一个40Khz的方波为载波,然后将音频信号加到载波上面 。音频播放的时候,555定时器输出的方波会发生变化。(开了余晖显示,大概是这样在不停的变化,如果在音频播放时)

因为需要一个互补的PWM给超声波的驱动芯片,所以555输出后也给到了一个反相器,作为输出一对互补输出的PWM ,然后给到驱动芯片……

查看原文:https://www.dianyuan.com/eestar/article-7927.html

五块五包邮的肌电按摩的方案是怎么样的?

最近在拼多多看到了一个比较好玩的产品,于是买回来分析一下电路结构,与各位同好一起分析一下电路。8个模式19个档位,可以说是相当的卷了 ……5.7元包邮。

使用感受就不说了,有点麻麻的,没仔细实验,直接分析电路吧。买之前我甚至想是不是数码管,拆开后发现就是普通的白光LED,加结构实现的数码管哈哈,不得不说这消费电子的花活挺多。挺让人意外的,还预留了红外接收器没贴 。正面元器件还是很简单的,22个LED加上几个电阻和金属按键 。(金属按键两个是低电平检测,一个高电平检测),这么多LED灯估计是矩阵的形式控制的。

然后是背面,背面一个锂电池,甚至还有一颗锂电池充电芯片4054 (右下角那个小芯片)。不过没有电池过冲过放的保护(这价位还要啥自行车)

然后拆掉电池,看到完整的PCB背面,主控的丝印被磨掉了,是1个14脚的主控芯片 ,可能是个OTP的单片机。然后2个NPN (丝印G1),1个PNP (丝印2L),1个1mH的电感 (丝印102),便是全部的电子元件了。然后看一下如何实现电刺激的。

关于电极这块的电路我抄出来如下,当IO1为高电平 时,三极管Q8导通 (电容C6为加速电容),电池通过红色电流路径给电感充能 ,类似boost拓扑;当IO2为高电平 时,Q6导通 ,电池的电压和电感产生的反生电动势叠加一起通过蓝色路径放电 (人体皮肤接到电极正和电极负之间)……

查看原文:https://www.dianyuan.com/eestar/article-7928.html

会使用51单片机的前提下,如何自学stm32?

我大一的时候在实验室的环境下开始学习 51 单片机,虽说学长不怎么管我们这些小白吧,但起码有个环境,有不懂的问题都可以向学长提问,这就是环境的好处了。但是如果说周围只有你一个人在学单片机,那这条路走得就会比较艰难了!为什么?因为单片机学习不仅涉及到软件,还涉及到硬件,这就是为什么说嵌入式门槛高的原因了,出了问题你不知道是硬件问题还是软件问题,还是都有问题,需要你根据经验一一排查才可以。

说回自学 STM32 问题,STM32 单片机远比 51 单片机复杂,寄存器数量是它的好几倍,各种外设模块,DA、CRC、SPI、CAN、SD、CAN 、TIM等等,而每一个模块可能都有单独的时钟,在使用这些模块时都要提前将时钟配置好,否则根本不能工作;而配置这些外设时钟之前你还要先配置系统时钟才行,而系统时钟又涉及到了分频、倍频的问题,也是繁杂。正因为这些东西实在是太多了,所以出现了库函数开发!

库函数开发的好处就是你不用管如何去操作寄存器,你只要了解什么时候该调用哪一个函数即可,相当方便,所以库函数开发的思路就是,记住各个函数的功能、调用条件(不需要死记硬背)就可以轻松进行开发了。但也正因为如此,所以在学STM32 的时候第一个拦路虎就是如何建立一个 STM32 工程,因为库函数开发需要的文件数量远比单纯的寄存器开发多的多,而这些文件之间还有关联性,很容易编译出错,所以可能在 51 单片机很简单的建工程到了 STM32 里面就会变得复杂了。但这些问题通过网上搜索还是很快能解决的,但是解决归解决,你是否明白为什么就这样解决了呢?所以你在开始学 STM32 的时候心里会很没底,因为你连最基本的工程都不知道该怎么才能建好。

然后第二个拦路就是时钟了,前面说过,STM32的时钟也是相当的复杂,所以很多教程上来就是教你如何配置时钟,这本没有错,但是你可能只是想尽快的点你第一个 LED 灯罢了,却要学这种感觉和点灯无关的时钟问题,所以心里也是挺着急的。事实上,点第一个 LED 灯是很简单的事情,只要你把对应的引脚配置好了就可以点灯。可能你会问,不要配置时钟吗?当然要,只是你点个灯对时钟的要求根本不高,所以时钟频率到底是多少可以不管,因此你直接用用默认的时钟配置就行了,因为在进入main函数之前启动文件(唯一的那个汇编文件)其实已经对时钟进行了配置(默认一般按最大的时钟频率进行配置),根本不需要额外的时钟代码的。所以这一点可以省去初学者不少功夫,当你比较熟练的掌握了库函数的时候,再回过头来去理解时钟的配置可能效果会更好。

关于 STM32 入门视频,你可以找刘凯老师的视频教程(有清晰版的),讲的还是不错的,因为我就是通过他学习 STM32 的,一集没落下的全部看完了。

最后再说一点,STM32 学习不比 51,51 单片机的调试功能不比STM32,所以在寻找 BUG 上还是比较麻烦的,而 STM32 因为有在线调试功能,可以实时观察数据、指令跟踪,所以在学习过程中一定要好好利用(当初我学习的时候根本不知道,还傻傻的用 51 那一套调试),而开发平台我觉得 MDK 最好,因为它把常用的寄存器都进行了集成,还有各种调试机制,非常人性化……

查看原文:https://www.dianyuan.com/eestar/article-7892.html

SiC MOSFET栅极电阻的影响分析

众所周知,由于没有IGBT所具有的拖尾电流,SiC MOSFET可以比IGBT实现更高频化,同时关断损耗又不至于太高,有助于提高系统功率密度。

值得注意的是,开关速度在一定程度上取决于栅极电阻,包含芯片内部和外部串联栅极电阻,针对合适的系统级考虑选择合适的外部栅极电阻。

芯片的内部栅极电阻取决于材料的物理特性和芯片尺寸,芯片尺寸越小,则其栅极电阻越大,SiC MOSFET首先比Si MOSFET的尺寸小,所以一般来说,栅极电阻会变大一些,在芯片内部栅极电阻确定的情况下,尽可能的选择适当外部栅极电阻,以抑制开关尖峰电压的基础上,尽可能减小开关损耗。

以1200V的MSC025SMA120B分立器件为例,我们可知其典型的栅极电阻为0.88ohm,相对较小,侧面也印证出其内部芯片尺寸较大……

查看原文:https://www.dianyuan.com/eestar/article-7943.html

SiC功率器件的H3TRB测试规范解析

在SiC功率器件或者模块的可靠性测试中有一项H3TRB测试比较典型,今天我们来简要讨论一下。

图1 典型功率模块的IDSS漏电流指标

在一般的规格书电气特性中,我们可以看到会标识功率模块的漏电流参数值,以MSCSM120AM16CT1AG这个1200V 12.5mohm典型阻抗的功率半桥模块来说,其漏电流为如图1所示,这个1200V可以看出IDSS这个漏电流参数,在1200V漏极电压反偏下,门级电压为0V,典型值为20uA,最大值200uA。

H3TRB, 具体含义是High Voltage High Humidity High Temperature Reverse Bias,即高压高温高湿反偏测试,这项测试是测试功率器件在此恶略严酷环境下的使用的可靠性,对于功率模块而言,在其内部会使用硅胶作为绝缘材料,硅胶在潮湿环境下容易吸湿,在无法做到完全密封的模块条件下,随着时间的推移,这将导致功率模块的绝缘性能受损,继而在电路运行中发生故障。

图2 H3TRB测试典型规范

测试SiC MOSFET的H3HTRB测试和Si MOSFET测试区别主要是施加的漏极电压或者反向电压不同,一般测试Si 器件的反向电压较低……

查看原文:https://www.dianyuan.com/eestar/article-7944.html

更多精彩内容,尽在电子星球 APP(https://www.eestar.com/)

六篇技术文章,让你秒懂电容的脾气秉性

七篇DIY技术文章献给你,让你脑洞全开

五篇文章帮你开启DSP的学习思路

汇总篇:关于PID知识,重点在此

相关问答

pic 单片机 怎么实现modbus协议?

与用什么单片机无关,关键的是你找个CRC校验C语言子程序拿来引用,然后再看看MODBUS常用的读写功能的数据格式,按格式一个数据一个数据的接收判断或者发送就行...

单片机 配置写入和数据校验是什么意思? (烧录程序的时候)-ZO...

你用的啥类型的单片机?单片机配置写入是你对这片芯片下次再写或程序上电启动时的要求,数据校验是你这片芯片写完后是否还要校验一次(这提高了可靠性可要多花时...

单片机 、光耦

1系统总体结构原理粮食在储藏期间,由于受环境、气候和通风条件等因素的变化,粮仓内温度或湿度会发生异常,这极易造成粮食的霉烂、或发生虫害。那么...

盆友们!有谁知道在线等 东莞实惠的智能硬件设计哪家有名,...

[回答]第1章51单片机开发的基础知识1.151单片机的硬件结构1.1.1功能模块1.1.2CPU1.1.3并行I/O端口1.1.4存储嚣结构1.1.5定时/计数器1.1.6串行口1.1.7中断...

51 单片机 c语言看门狗程序肿么写-ZOL问答

看门狗在51单片机电路里的作用是防止程序“跑飞”、“死机”后,系统不动作,而采取复位的办法“唤醒”系统。89S51、89S52系列单片机自带有看门狗功能,片内数据...

求关于随机争用仲裁系统设计和开发的论文有么

[回答]MCS51系列的单片机没有那么强大的功能(主要是可扩展的存储器有限),如果真要使用的话,可能要用好几片.2:现在的电梯都是PLC(可编程逻辑控制器)控制...

usart和uart优缺点?

USART(通用同步/异步收发器)和UART(通用异步收发器)都是用于实现串行通信的协议。下面是USART和UART的一些优缺点:USART优点:1.支持同步和异步的串行通信...

nrf24r01配置步骤?

nRF24L01是一款常用的无线通信模块,下面是nRF24L01的配置步骤:1.硬件连接:将nRF24L01模块与单片机或其他主控设备进行连接。连接包括以下几个要点:VCC和GND...

CAN 如何连成总线

[回答]spanname=whlmid=whlm摘要:控制器局域网(CAN)WBR是一种有效支持分布式控制或实时控制的现场总线,WBR具有高性能和高可靠性的特点;随着现代汽车技...

麻烦各位资深人士!我想了解 重庆什么是通信光模块,通信光...

[回答](11)与51系列单片机P0口连接时候,需要加10K的上拉电阻,与其余口连接不需要。(12)其他系列的单片机,如果是5V的,请参考该系列单片机IO口输出电流大小...

猜你喜欢