踏浪而行,偶尔回首,虽不见印记,却也能望见远处的海岸。
从15年毕业,恍然已八年。
硬件工作了八年。也是爱的深沉。
还记得大学的时候在学生会认识的朋友,他有一天突然跟我推荐单片机开发板,那时候大二,打听过,单片机应该是下学期开始的课程。当时我觉得是一种命运的安排,就斥巨资购买了郭天祥的单片机开发板。鬼使神差的,竟然在大学那松散的时光里,我可以学习到深夜一两点!也是因为一块开发板,我考了两次的计算机二级(虽然后来知道没啥用),就很自然的过了。以前不是很理解的硬件知识,也通畅了。后来参加了学校组织的以及国家级的多次比赛,硬件开始让我爱不释手。在当时我也成为了我们班的专业代表,然而毕业始终给人猝不及防。
后来,经过一番忙碌,进入了现在的企业。
还记得简历上不敢写面试硬件工程师,最终写了个PCB工程师。或许也比较怀疑自己的硬件设计能力吧。
刚入职,大多是熟悉产品,于是我维修了公司的陈年旧板,看原理图,查资料,大部分还是需要自主去弄的。然后PCB的设计,学习cadence软件,设计第一块接口板。
恍惚一年多,五六层板也很轻松了。记得有一次评估PCB尺寸和接口位置,对应产品外观。逼不得已学习了最简单的SolidWorks操作。也算是初涉结构设计,后来我们结构设计工程师离职,我就揽下了这个工作。自古硬件结构不分家。PCB与结构的搭配产生了完美的产品。
就这样一晃就是四年,作为干硬件的竟然连原理图都没弄过,挺遗憾的,正当要得过且过的时候,也不知为啥我的领导开始疯狂输出各种原理图设计给我,并且算得上的手把手教学了,但是时间只给了我一个月,因为他要离职了,并且让我接替。有种悲喜交加的感觉。喜的是升职加薪,悲的是刚好两个项目来了。原理图、PCB、结构...
就从原理图认真开始吧,反正也只能这样。于是参考着参考设计,本想着删删减减就大功告成的,然而就在删电容的时候就卡住了,脑海中全是疑问:这个电容为什么选这个容量的?为什么耐压值是这个?这里没标注电容的材料啊?哎?为啥这个地方要这么多种类的电容啊?算了还是删电阻吧,然后又是疑问:多大电阻?多少精度?多大封装?后来还有电感...
最终的结果是全部保留原样的,反正能用,就不改了。最终导致了bom成本,板卡做的很大等问题。
第一次可以这样做,第二次也可以,但是等产品出来了,市面上同类产品,我们的定价颇高,于是老板请我去他办公室喝茶了。意思很简单,降bom成本。
路漫漫修远以下是面包板社区“瑞萨RA6M4 MCU 评估板”评测活动的评测连载,分享于此,希望对你有所参考。
(1)开发环境搭建
(2)快速傅里叶变换(FFT)测试
(3)定时器实现SPWM
(4)基于RS232 接口的 Modbus-RTU 从机实现
1、modbus 协议是工业运用比较成熟的通信协议,本例基于瑞萨RA6M4单片机进行modbus协议的实现,开源的modbus 协议较多,本例以移植Xtiny-Modbus为展示:
(1)第一步:搭建硬件环境
由于开发板没有带串口,需要外接一个串口收发模块
(2)第二步:下载开源的源码,下载地址:Xtiny-Modbus移植示例 https://gitee.com/zhang_en/xtiny_-modbus_test.git
(3)第三步:建立工程,配置时钟
由于外部高速晶振24MHz没有焊接,需要配置为内部晶振16MHz,然后再2分频
(4)第四步:配置串口
设置波特率、回调函数、中断优先级
(5)第五步:配置定时器
设置定时器计时的周期,回调函数、中断优先级
(6)第六步:编写串口驱动函数
#include"usart3.h"#include"Sys_Config.h"#if MD_USD_SALVE#include"MDS_RTU_Serial.h"#else#include"MDM_RTU_Serial.h"#include"MD_RTU_SysInterface.h"#include"MDM_RTU_Fun.h"#endif
volatileuint8_t flag=false;
voidRS485RWConvInit(void){//收发引脚配置// R_IOPORT_Open(&g_ioport_ctrl,g_ioport.p_cfg);// R_IOPORT_PinWrite(&g_ioport_ctrl,BSP_IO_PORT_05_PIN_03,BSP_IO_LEVEL_LOW); }
//串口1配置voidinit_usart3(void){ R_SCI_UART_Open(&g_uart0_ctrl,g_uart0.p_cfg); RS485RWConvInit(); }voidusart3_send_byte(uint8_t byte){ R_SCI_UART_Write(&g_uart0_ctrl,(uint8_t*)(&(byte)),1);while(flag!=true); flag=false; }voidusart3_send_bytes(uint8_t *bytes,int len){int i;for(i=0;i<len;i++){ usart3_send_byte(bytes); } }voidusart3_send_string(char *string){while(*string) { usart3_send_byte(*string++); } }
voiduart_callback(uart_callback_args_t *arg){uint8_t data_r;switch(arg->event) {case UART_EVENT_RX_CHAR:// R_SCI_UART_Read(&g_uart0_ctrl,(u8*)(&(data_r)),1); data_r=(uint8_t)(arg->data);#if !MD_RTU_USED_OS#if MD_USD_SALVE MDSSerialRecvByte(data_r);#else#if MDM_USD_USART3 MDMSerialRecvByte(data);#endif#endif#elseextern Modbus_RTU modbus_RTU; MD_RTU_MsgPut((PModbusBase)(&modbus_RTU), MD_RTU_MSG_HANDLE_ARG(&modbus_RTU),(void*)(data),0);#endifbreak;case UART_EVENT_TX_COMPLETE: flag=true;break;default:break; }
}
(7)第7步编写定时器驱动程序:
#include"tim3.h"#include"Sys_Config.h"#if MD_USD_SALVE#include"MDS_RTU_Serial.h"//#include "MDS_RTU_Serial_1.h"#else#include"MDM_RTU_Serial.h"#endif
volatileuint32_t sys_tick_100us=0;
voidTIM3_Int_Init(void){ R_AGT_Open(&g_timer0_ctrl,g_timer0.p_cfg); R_AGT_Start(&g_timer0_ctrl);}
voidtimer_callback(timer_callback_args_t *arg){if(arg->event==TIMER_EVENT_CYCLE_END)// if (timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP) != RESET) { sys_tick_100us++;#if !MD_RTU_USED_OS#if MD_USD_SALVE MDSTimeHandler100US(sys_tick_100us);#else MDMTimeHandler100US(sys_tick_100us);#endif#endif }}
(8)第八步:编写应用程序
staticvoidMDS_RTU_UserUpdate(void){ uint16 temp=0xff; uint16 temp1[]={1,2,3,4,5}; MDS_RTU_WriteCoils(&modbusS_RTU,1,5,&temp); MDS_RTU_WriteHoldReg(&modbusS_RTU,11, temp); MDS_RTU_WriteHoldRegs(&modbusS_RTU,5,5,temp1); }
(9)第九步:编写处理程序
#include"hal_data.h"
#include"tim3.h"#include"Sys_Config.h"#if MD_USD_SALVE#include"MDS_RTU_APP.h"#else#include"MDM_RTU_APP.h"#include"MDM_RTU_Fun.h"#include"MDM_RTU_User_Fun.h"#endif
FSP_CPP_HEADERvoidR_BSP_WarmStart(bsp_warm_start_event_t event); FSP_CPP_FOOTER
/*******************************************************************************************************************//** * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function * is called by main() when no RTOS is used. **********************************************************************************************************************/voidhal_entry(void){/* TODO: add your own code here */#if MD_RTU_USED_OS OSInit(); #endif//delay_init();
#if MD_USD_SALVE MDS_RTU_APPInit();#else MDM_RTU_APPInit();#endif TIM3_Int_Init();#if MD_RTU_USED_OS task1=OSCreateTask(mdTestTask0,NULL,6,256); task2=OSCreateTask(mdTestTask1,NULL,6,256); SysTick_Config(SystemCoreClock / OS_T IC KS_PER_SEC); OSStart();#endifwhile(1){#if !MD_RTU_USED_OS#if MD_USD_SALVE MDS_RTU_Loop();#else MDM_RTU_Loop(); MDM_RW_CtrlLoop();#endif#endif }#if BSP_TZ_SECURE_BUILD/* Enter non-secure code */ R_BSP_NonSecureEnter();#endif }
(10)第十步:连接Modbus 主机,查看结果
END
点击阅读原文,免费申请 |