大神们有没有关于ModBus在STM32上移植的心脏有没有期限书籍?求推荐

查看: 22803|回复: 66
FreeModbus在STM32上移植。
FreeModbus在STM32上移植...1.5的,调试使用的是modscan32,可以响应命令,但是没做返回数据。
使用串口1和TIM2
参考前辈的一些移植范烈,没多少解释,编译通过,但是不能正常接受命令。
我仔细分析了下,FreeModbus使用的定时器和协议上的时序要求不是一样的,区别:
RTU模式:协议上是字符间空闲时间大于1.5个字符时间,则认为该帧不完整;帧之间间隔必须大于3.5个字符时间。
FreeModbus在第一次接收到字符时启动定时器,并从空闲状态转入接收状态,每接收一次字符,判断接收字符的长度大于等于4或3(RTU/ASCII模式最小帧长度)&& CRC校验,如接收到完整的帧,则转入执行模式...其中定时器的作用是在一定时间内,若未接收到完整的帧,超时后转入空闲模式,缓存指针指向0位置;该时间长度为 大于最大帧在指定波特率传输一帧所需要的时间,即为定时器溢出中断时间。定时器不涉及RTU传输协议的时间处理(我之前误解了)。
修改定时器时间后,现在可以接收到modscan32发送的标准指令了,不过没有写返回。
里面可能还有一些错误,需要的参考参考,一起讨论学习吧。。。
点击此处下载
(原文件名:STM32_MODBUS.rar)
麻烦楼主再介绍一下FreeModbus。百度一下没有什么太详细的介绍。这个的使用环境是什么?哪里用的多一些?
搜了一下modbus,知道了。
资料不多...刚开始学。
MODBUS协议可以参考《从MODBUS到透明协议就绪》这本书,比看英文的容易理解吧,MODBUS常用于工业网络通信,有好几个类型。
FreeModbus 是一个可移植的Modbus软件协议,目前感觉结构还很不错,UC/MODBUS 网上也有,好像源码还不全。
先mark下,留着备用
FreeModbus 第一次听说.
第一次听说。mark
第一次听说。mark
需要用到,mark一下。
留记号,后续研究
系统有2个串口,一个做主,一个做从,freemodbus表示鸭梨很大。
freemodbus 只有从. 且只能做一个从.
回复【11楼】lvhaian 安哥
-----------------------------------------------------------------------
安哥,前辈啊,我才刚开始接触...
我现在就是打算用FreeModbus做从机实现一个RTU。
如果要实现主机和一机多从,一般都是自己实现的么?
UC/MODDBUS貌似可以,不过找不到完整的。。
安哥,指点下如何做好MODBUS的开发。。
回复【10楼】waterx3
-----------------------------------------------------------------------
不知,关于MODBUS开发有什么心得...全民教育下...刚开始接触,有点找不着北。
回复【11楼】lvhaian&&安哥
-----------------------------------------------------------------------
主、从都可以,但是只能有1个。
其实RTThread移植了freemodbus的master,不过有问题还需要自己改改。
最近正在弄这东西。
这个不错,还可以支持Modbus TCP
回复【3楼】xiaowei061
资料不多...刚开始学。
modbus协议可以参考《从modbus到透明协议就绪》这本书,比看英文的容易理解吧,modbus常用于工业网络通信,有好几个类型。
freemodbus 是一个可移植的modbus软件协议,目前感觉结构还很不错,uc/modbus 网上也有,好像源码还不全。
-----------------------------------------------------------------------
请问这本书哪里有?
freemodbus 官方网站:
http://www.freemodbus.org/index.php?lang=cn
官方公布移植freemodbus的芯片与系统:
- Ports ASCII/RTU
&&- FreeRTOS/STR71X
&&- AVR ATMega8/16/32/128/168/169
&&- Freescale MCF5235
&&- TI MSP430
&&- LPC214X
&&- Z8 Encore!/Z8F6422
&&- Linux/Cygwin
&&- FreeRTOS/AT91SAM7X
- Ports TCP
&&- lwIP/MCF5235
&&- lwIP/STR71X
(原文件名:ArchInternalDependencies-DirectoryStructure.jpg)
文件夹结构图
标记一下,以后会用到的,谢谢
回复【23楼】phil
-----------------------------------------------------------------------
这篇帖子有错误,定时器时间处理那段。。。别看了。。。
回复【24楼】xiaowei061
回复【23楼】phil&&
-----------------------------------------------------------------------
这篇帖子有错误,定时器时间处理那段。。。别看了。。。
-----------------------------------------------------------------------
啥错误哦?能指明下吗?
回复【25楼】niba
-----------------------------------------------------------------------
modbus 通讯接收的3.5字符接收时间,FreeModbus底层接口的定时器配置,我理解错了...够明了了吧。。。一般看一下就知道我说的错在哪里,之前对FreeMOdbus的理解是正确的。
谢谢,准备做MODBus,还不知道如何下手
一直想研究一下这个协议的
很好,很好的资料!
modbus&&记号
刚开始搞MODBUS, 试了UCMODBUS,发现文件不太完整。freemodbus还不错,自由软件!
MARK,收藏了!
mark下 正在做pic rtu这块
lvhaian 发表于
freemodbus 只有从. 且只能做一个从.
只能做一个从。
也有主,不过不Free
支持,最近要开始做变频器的Modbus 了,看起来还是有点麻烦的
此贴不能沉的
来自:amoBBS 阿莫电子论坛 Windows Phone 7 客户端
留记号,后续研究。
谢谢分享&&开始做这方面东西
flyunlimit 发表于
麻烦楼主再介绍一下FreeModbus。百度一下没有什么太详细的介绍。这个的使用环境是什么?哪里用的多一些? ...
带有RS485通信接口的设备上基本都是用modbus-rtu,freemodbus是一个modbus协议的协议栈,
让开发者可以在很短的时间内就可以实现modbus,而且稳定可靠。
楼主可以介绍下Freemodbus的工作工程么?移植了个例程,也通讯成功了,总感觉云里雾里的,还望多多指点啊
freemodbus 很实用还没有lz理解的那么深
标记,FreeModbus在STM32上移植
FreeModbus的思路还是不错的,项目上仿照FreeModbus写过,Modbus的主机程序还是要跑个OS好用点
非常感谢,参考学习了
最近需要移植
用起来简单
但是把所有执行步骤理清楚
还是需要花一些时间的
这个应该不错
看看freemodbus
非常感谢分享
mark下 谢谢分享
非常好,感谢LZ
可以参考,但介绍的不详细
谢谢楼主分享
FreeModbus移植只要修改好PORT文件就好了,主要是定时器和串口操作,不过FreeModbus是基于事件触发来处理的,带OS移植就非常方便,不带的可以在LOOP里面处理。
MODBUS工业总线,很常用,关注学习
我前几天也移植成功了,stm32F103上。接下来想移植到stc15里面去
最近也在看MODBUS,不知FreeModbus支持主机否?
阿莫电子论坛, 原"中国电子开发网"
, 原www.ourdev.cn, 原www.ouravr.com21ic官方微信-->
ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU
请完成以下验证码
freemodbus 在STM32上的移植
实习生, 积分 45, 距离下一级还需 5 积分
实习生, 积分 45, 距离下一级还需 5 积分
实习生, 积分 45, 距离下一级还需 5 积分
实习生, 积分 45, 距离下一级还需 5 积分
本帖最后由 固桐 于
22:27 编辑
这几天,研究了freemodbus通信协议,然后在stm32上移植。关于freemodbus通信原理,以及通信过程(状态机转换),这里就不说了。& && & freemodbus使用的库是最新版本freemodbus-v1.5.0,把相应的库文件加载在STM32工程中。移植时,需要用户改写的文件有两个,一个是porttimer.c文件,一个是portserial.c文件。porttimer.c文件主要用于超时判断,本例使用的是定时器2,portserial.c主要使用串口通信的实现,本例使用的是RS485.porttimer.c修改如下
/* ----------------------- Platform includes --------------------------------*/
#include &port.h&
/* ----------------------- Modbus includes ----------------------------------*/
#include &mb.h&
#include &mbport.h&
#include &..\..\include\nvic.h&
#include &..\..\include\stm32f10x_reg.h&
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us ) //配置50us时钟
{
& && &&&uint16_t PrescalerValue = 0;
& && &&&
& && &&&/* TIM2 clock enable */
& && &&&
& && &&&RCC-&CFGR.B.PPRE1 = 4;&&//APB1预分频系数
& && && && && && && && &&&//100:HCLK 2分频
& && && && && && && && && && &&&//APB1 不超过36MHz
& && &&&RCC-&APB1ENR.B.TIM2EN = 1;
& && &&&/* Compute the prescaler value */
& && &&&PrescalerValue = (uint16_t) ( / 20000) - 1; // 1/20000=50us
& && &&&/* Time base configuration */
& && &&&TIM2-&ARR=(uint16_t) usTim1Timerout50
& && &&&TIM2-&PSC= PrescalerV
& && &&&TIM2-&CR1.B.URS = 1;
& &MY_NVIC_Init(3,3,28,2);& && && &
& && && && && &
& && &&&/* TIM IT DISABLE */
& && &&&TIM2-&SR.B.UIF = 0;
& && &&&TIM2-&DIER.B.UIE = 0;
& && &&&TIM2-&CR1.B.CEN = 0;
& && &&&/* TIM2 DISABLE counter */
& && &&&return TRUE;;
}
void vMBPortTimersEnable(&&) //打开时钟
{
& && && &TIM2-&SR.B.UIF = 0;
& && &&&TIM2-&DIER.B.UIE = 1;
& && &&&TIM2-&CNT= 0;
& && &&&TIM2-&CR1.B.CEN = 1;
& && &&&
}
void vMBPortTimersDisable(&&) //关闭时钟
{
& && &&&TIM2-&CR1.B.CEN = 0;
& && &&&TIM2-&CNT= 0;
& && &&&TIM2-&DIER.B.TIE = 0;
& && &&&TIM2-&DIER.B.UIE = 0;
& && &&&}
/* Create an ISR which is called whenever the timer has expired. This function
* must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
* the timer has expired.
*/
void prvvTIMERExpiredISR( void ) //在时钟中断内调用
{
& & ( void )pxMBPortCBTimerExpired(&&);
}
void TIM2_IRQHandler(void)
{
& & /* Clear TIM4 Capture Compare1 interrupt pending bit*/
& &
& && &&&TIM2-&SR.B.UIF = 0;
& && &&&TIM2-&SR.B.TIF = 0;
& && &&&prvvTIMERExpiredISR( );
}
复制代码portserial.c文件修改如下
#include &port.h&
/* ----------------------- Modbus includes ----------------------------------*/
#include &mb.h&
#include &mbport.h&
#include &..\..\include\nvic.h&
#include &..\..\include\stm32f10x_reg.h&
#include &mb.h&
#include &mbport.h&
#include &stdio.h&
#include &stdlib.h&
#include &string.h&
#include &ctype.h&
#include &math.h&
#include &stdarg.h&
#define& && &&&RS485_T& & GPIOA-&BSRR.B.SETIO4=1
#define RS485_R& &GPIOA-&BSRR.B.CLRIO4=1
/* ----------------------- Start implementation -----------------------------*/
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) //控制串口的收发中断
{
& && &&&if(TRUE==xRxEnable)
& && &&&{
& && && && && & USART2-&CR1.B.RXNEIE = 1;
& && && && && && && && && && && && && &
& && &&&}
& && &&&else
& && &&&{
& && && && && & USART2-&CR1.B.RXNEIE = 0;
& && && && && &
& && &&&if(TRUE==xTxEnable)
& && &&&{
& && && && && &
& && && && && & USART2-&CR1.B.TXEIE = 1;
& && && && && &
& && &&&}
& && &&&else
& && &&&{
& && && &&&
& && && && && & USART2-&CR1.B.TXEIE = 0;
& && && && && && &
& && &&&}
}
* 配置串口 目前除了波特率其他参数无效
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
& && &&&
&&float temp2;& && &&&
&&AFIO-&MAPR.B.USART2_REMAP=0; //无重映像
&&RCC-&APB1ENR.B.USART2EN = 1; //USART2时钟开启
& && &&&GPIOA-&CRL.B.MODE2 = 3;& && &&&// Configure USART2 Tx (PA.2) as alternate function push-pull
& && &&&GPIOA-&CRL.B.CNF2 = 2;
& && &&&GPIOA-&CRL.B.MODE3 = 0;& && &&&// Configure USART2 Rx (PA.3) as input floating
& && &&&GPIOA-&CRL.B.CNF3 = 1;
& && && && && && && && && &
& && &&&
& && &&&temp= (/2)/(16*ulBaudRate);
& && &&&temp2=floor(temp);
& && &&&temp=temp-temp2;
& && &&&temp*=16;
& && && && && && && && && && && && && && && && && && && && && &
& && &&&USART2-&BRR.B.DIV_Fraction=//DIV_Fraction[3:0]:USARTDIV的小数部分
& && && && && && && && && && && && && && && && && && && && && && && && &//这4位定义了USART分频器除法因子(USARTDIV)的小数部分。
& && && && && && && && && && && && && && && && && && && && && && && && &// 6 9600
& && &&&USART2-&BRR.B.DIV_Mantissa=temp2;
& && &&&//DIV_Mantissa[11:0]:USARTDIV的整数部分
& && &&&//这12位定义了USART分频器除法因子(USARTDIV)的整数部分。
& && &&&//234 9600
& && &&&
& && &&&
& && &&&USART2-&CR1.B.PCE = 0;& & //0:校验控制被禁止;
& && &&&USART2-&CR1.B.M = 0;& && &//0:一个起始位,8个数据位,n个停止位;
& && &&&USART2-&CR1.B.RE = 1;& &&&//1:接受被使能。
& && &&&USART2-&CR1.B.TE = 1;& &&&//1:发送被使能。
& && &&&USART2-&CR1.B.RXNEIE = 1; //1:当USART_SR中的ORE或者RXNE为1时,产生USART中断。
& && &&&USART2-&CR1.B.PEIE = 1;& &//1:当USART_SR中的PE为1时,产生USART中断。
& && &&&USART2-&CR1.B.UE = 1;& &&&//1:USART模块使能。
& && &&&
& && &&&USART2-&CR2.B.LBCL = 0;& &//0:最后一位数据的时钟脉冲不从SCLK输出;
& && &&&USART2-&CR2.B.CPOL = 0;& &//0:总线空闲时SCLK引脚上保持低电平;
& && &&&USART2-&CR2.B.CLKEN = 0;&&//0:SCLK引脚被禁止。
& && &&&USART2-&CR2.B.STOP = 0;& &//00:1个停止位;
& && &&&USART2-&CR2.B.CPHA = 1;& &//1:时钟二个第边沿进行数据捕获。
& && &&&USART2-&CR3.B.RTSE = 0;& &//0:RTS硬件流控制被禁止;
& && &&&USART2-&CR3.B.CTSE = 0;& &//0:CTS硬件流控制被禁止;
& && &&&
& &MY_NVIC_Init(3,3,38,2);//组2,最低优先级
& && && &GPIOA-&CRL.B.MODE4 = 3;
& && &&&GPIOA-&CRL.B.CNF4 = 0;
& &
& && &&&RS485_R;
& &
& && &&&return TRUE;
}
// 串口发
BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
& && &&&
& && &&&RS485_T;
& && &&&
& & for(i=0;i&1000;i++);
& && && & USART2-&DR.W= ucB
& && && & while (!(USART2-&SR.B.TC == 1)) ;
& && &&&
& && && & RS485_R;
& & return TRUE;
}
// 串口收
BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
& & *pucByte = USART2-&DR.W;
& & return TRUE;
}
/* Create an interrupt handler for the transmit buffer empty interrupt
* (or an equivalent) for your target processor. This function should then
* call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
* a new character can be sent. The protocol stack will then call
* xMBPortSerialPutByte( ) to send the character.
void prvvUARTTxReadyISR( void )
{
& & pxMBFrameCBTransmitterEmpty(&&);
}
/* Create an interrupt handler for the receive interrupt for your target
* processor. This function should then call pxMBFrameCBByteReceived( ). The
* protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
* character.
*/
void prvvUARTRxISR( void )
{
& &&&pxMBFrameCBByteReceived(&&);
}
void USART2_IRQHandler(void)
{
& && &&&if(USART2-&CR1.B.RXNEIE==1)
& && &&&{
& && && && && & prvvUARTRxISR();//接收完成中断
& && && && && & USART2-&SR.B.RXNE=0;
& &&&
& && &&&}
& && &&&if(USART2-&CR1.B.TXEIE==1)
& && &&&{
& && && && && & prvvUARTTxReadyISR();//发送完成中断
& && && && && & USART2-&SR.B.TC=0;
& && && && && &
& && &&&
& && &&&
}
复制代码另外在主函数中,加入测试函数如下
#include &mb.h&
#include &..\..\include\adc.h&
#include &..\..\include\lm75.h&
#include &..\..\include\timer.h&
#include &..\..\include\simulate.h&
#include &..\..\include\encode.h&
#include &..\..\include\hardware.h&
#include &..\..\include\systick.h&
unsigned short int&&usRegInputBuf[10]={0x0000,0xfe02,0x4,0x6,0x8,0x1809};
unsigned short int *usRegHoldingBuf=usRegInputB& && &&&//一个测试用的 寄存器数组 地址0-7
unsigned char REG_INPUT_START=0,REG_HOLDING_START=0;
unsigned char REG_INPUT_NREGS=8,REG_HOLDING_NREGS=8;
unsigned char usRegInputStart=0,usRegHoldingStart=0;
//读数字寄存器 功能码0x04
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
& && &&&eMBErrorCode& & eStatus = MB_ENOERR;
& && &&&int& && && && & iRegI
& & if( ( usAddress &= REG_INPUT_START )&& ( usAddress + usNRegs &= REG_INPUT_START + REG_INPUT_NREGS ) )
& & {
& && &&&iRegIndex = ( int )( usAddress - usRegInputStart );
& && &&&while( usNRegs & 0 )
& && &&&{
& && && && &*pucRegBuffer++ =
& && && && && & ( unsigned char )( usRegInputBuf[iRegIndex] && 8 );
& && && && &*pucRegBuffer++ =
& && && && && & ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
& && && && &iRegIndex++;
& && && && &usNRegs--;
& && &&&}
& & }
& & else
& & {
& && &&&eStatus = MB_ENOREG;
& & }
& & return eS
}
// 寄存器的读写函数 支持的命令为读 0x03 和写0x06
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{
& & eMBErrorCode& & eStatus = MB_ENOERR;
& & int& && && && & iRegI
& & if( ( usAddress &= REG_HOLDING_START ) && ( usAddress + usNRegs &= REG_HOLDING_START + REG_HOLDING_NREGS ) )
& & {
& && &&&iRegIndex = ( int )( usAddress - usRegHoldingStart );
& && &&&switch ( eMode )
& && &&&{
& && && && && && && && && && && && && &
& && &&&case MB_REG_READ:
& && &&&if(usAddress==1)
& && && && && && && && && & {
& && && && && && && && && && && && &*pucRegBuffer++ = ( unsigned char )( adc.read(1) && 8 );
& && && && &
& && && && && && && && && && && && &*pucRegBuffer++ = ( unsigned char )( adc.read(1) & 0xFF );
& && && && && && && && && && && & }
& && && && && && && && && && &&&if(usAddress==2)
& && && && && && && && && && && & {
& && && && && && && && && && && && &*pucRegBuffer++ = ( unsigned char )( adc.read(0) && 8 );
& && && && &
& && && && && && && && && && && && &*pucRegBuffer++ = ( unsigned char )( adc.read(0) & 0xFF );
& && && && && && && && && && && & }
& && && && && && && && && && && && && & if(usAddress==3)
& && && && && && && && && && && & {
& && && && && && && && && && && && &*pucRegBuffer++ = ( unsigned char )( adc.read(7) && 8 );
& && && && &
& && && && && && && && && && && && &*pucRegBuffer++ = ( unsigned char )( adc.read(7) & 0xFF );
& && && && && && && && && && && & }
& && && && && && && && && && && && && & if(usAddress==4)
& && && && && && && && && && && & {
& && && && && && && && && && && && &*pucRegBuffer++ = ( unsigned char )( lm75.read() && 8 );
& && && && &
& && && && && && && && && && && && &*pucRegBuffer++ = ( unsigned char )( lm75.read() & 0xFF );
& && && && && && && && && && && & }
& && &&&
& && && &if(usAddress==5)
& && && && && && && && && && && & {
& && && && && && && && && && && && && && && && && && && && && &
& && && && && && && && && && &&&timer.refresh();
& && && && && && && && && && &&&*pucRegBuffer++ = ( unsigned char )( tim_parameter.Position_relative && 8 );
& && && && && & *pucRegBuffer++ = ( unsigned char )( tim_parameter.Position_relative &0xFF );
& && && && && && && && && && && && && && && && &
& && && && && &
& && &&&}
& && && && && & if(usAddress==6)
& && && && && && && && && && && & {
& && && && && && && && && && && && && && && && && && && && && &
& && && && && && && && && && &&&timer.refresh();
& && && && && && && && && && &&&*pucRegBuffer++ = ( unsigned char )(&&TIM1-&CCR2&& 8 );
& && && && && & *pucRegBuffer++ = ( unsigned char )(&&TIM1-&CCR2&0xFF );
& && && && && && && && && && && && && && && && &
& && && && && &
& && &&&}
& && && && && && && && && && && &
& && && && &
& && &&&case MB_REG_WRITE:
& && && && &while( usNRegs & 0 )
& && && && &{
& && && &
& && && && && && && && && && &&&usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ && 8;
& && && && & usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
& && && && & iRegIndex++;
& && && && && & usNRegs--;
& && && && &}
& && &&&}
& & }
& & else
& & {
& && &&&eStatus = MB_ENOREG;
& & }
& & return eS
}
//读/写开关寄存器&&0x01&&x05
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
& & ( void )pucRegB
& & ( void )usA
& & ( void )usNC
& & ( void )eM
& & return MB_ENOREG;
}
//读开关寄存器 0x02
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
& & ( void )pucRegB
& & ( void )usA
& & ( void )usND
& & return MB_ENOREG;
}
复制代码
经过,测试,本次移植可以读取节点的温度,AD转换值,等参数,实现了预期的效果。
资深工程师, 积分 16475, 距离下一级还需 3525 积分
资深工程师, 积分 16475, 距离下一级还需 3525 积分
资深工程师, 积分 16475, 距离下一级还需 3525 积分
资深工程师, 积分 16475, 距离下一级还需 3525 积分
我记得freemodbus包里自带了stm32 demo吧。
实习生, 积分 45, 距离下一级还需 5 积分
实习生, 积分 45, 距离下一级还需 5 积分
实习生, 积分 45, 距离下一级还需 5 积分
实习生, 积分 45, 距离下一级还需 5 积分
dong_abc 发表于
我记得freemodbus包里自带了stm32 demo吧。
在demo目录下&&bare文件中,修改 porttimer.c和portserial.c即可
实习生, 积分 26, 距离下一级还需 24 积分
实习生, 积分 26, 距离下一级还需 24 积分
实习生, 积分 26, 距离下一级还需 24 积分
实习生, 积分 26, 距离下一级还需 24 积分
好东西,写成文件,就更好了。
资深技术员, 积分 483, 距离下一级还需 17 积分
资深技术员, 积分 483, 距离下一级还需 17 积分
资深技术员, 积分 483, 距离下一级还需 17 积分
资深技术员, 积分 483, 距离下一级还需 17 积分
看看 怎么样&&学习
高级工程师, 积分 6988, 距离下一级还需 1012 积分
高级工程师, 积分 6988, 距离下一级还需 1012 积分
高级工程师, 积分 6988, 距离下一级还需 1012 积分
高级工程师, 积分 6988, 距离下一级还需 1012 积分
楼主介绍的步骤很详细,借鉴一下楼主的经验,项。
实习生, 积分 33, 距离下一级还需 17 积分
实习生, 积分 33, 距离下一级还需 17 积分
实习生, 积分 33, 距离下一级还需 17 积分
实习生, 积分 33, 距离下一级还需 17 积分
不错。。。
实习生, 积分 21, 距离下一级还需 29 积分
实习生, 积分 21, 距离下一级还需 29 积分
实习生, 积分 21, 距离下一级还需 29 积分
实习生, 积分 21, 距离下一级还需 29 积分
LZ您好!最近在做STM32的项目,也是刚接触不久,一直使用寄存器版本编写代码,没有使用STM32库函数。
现在由于也要用到485与上位机通讯,希望移植freemodbus,不知道这个协议可不可以用在寄存器开发版本的STM32工程里?谢谢!
中级技术员, 积分 190, 距离下一级还需 110 积分
中级技术员, 积分 190, 距离下一级还需 110 积分
中级技术员, 积分 190, 距离下一级还需 110 积分
中级技术员, 积分 190, 距离下一级还需 110 积分
使用过ModBus,简易版的,自己写的...
助理工程师, 积分 1085, 距离下一级还需 915 积分
助理工程师, 积分 1085, 距离下一级还需 915 积分
助理工程师, 积分 1085, 距离下一级还需 915 积分
助理工程师, 积分 1085, 距离下一级还需 915 积分
先MARK 以后学时看 顶下
初级工程师, 积分 2176, 距离下一级还需 824 积分
初级工程师, 积分 2176, 距离下一级还需 824 积分
初级工程师, 积分 2176, 距离下一级还需 824 积分
初级工程师, 积分 2176, 距离下一级还需 824 积分
Mrzhen009 发表于
LZ您好!最近在做STM32的项目,也是刚接触不久,一直使用寄存器版本编写代码,没有使用STM32库函数。
随便你怎么用都行。
实习生, 积分 21, 距离下一级还需 29 积分
实习生, 积分 21, 距离下一级还需 29 积分
实习生, 积分 21, 距离下一级还需 29 积分
实习生, 积分 21, 距离下一级还需 29 积分
dbayj 发表于
随便你怎么用都行。
谢谢!也就是说,这个freemodbus只是提供一些API,只要把源码放入工程,直接可以用它提供的函数接口实现modbus协议?这样理解对吗?
初级工程师, 积分 2176, 距离下一级还需 824 积分
初级工程师, 积分 2176, 距离下一级还需 824 积分
初级工程师, 积分 2176, 距离下一级还需 824 积分
初级工程师, 积分 2176, 距离下一级还需 824 积分
首先,你得把它要的驱动接口做好,然后你才可以用它提供给你的接口。至于你是用库的方式写驱动,还是用寄存器方式写驱动,都是一样的。
助理工程师, 积分 1758, 距离下一级还需 242 积分
助理工程师, 积分 1758, 距离下一级还需 242 积分
助理工程师, 积分 1758, 距离下一级还需 242 积分
助理工程师, 积分 1758, 距离下一级还需 242 积分
楼主好,请教一个问题,上位机在读输入寄存器(读数字寄存器 功能码0x04)的时候是怎么跳转到回调函数
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
的,多谢了!
助理工程师, 积分 1758, 距离下一级还需 242 积分
助理工程师, 积分 1758, 距离下一级还需 242 积分
助理工程师, 积分 1758, 距离下一级还需 242 积分
助理工程师, 积分 1758, 距离下一级还需 242 积分
这种数组寄存器处理方法和从Flash地址取值有何优点?
若非上述操作,如何实现取从机地址的0x4000的数据呢?
中级技术员, 积分 100, 距离下一级还需 200 积分
中级技术员, 积分 100, 距离下一级还需 200 积分
中级技术员, 积分 100, 距离下一级还需 200 积分
中级技术员, 积分 100, 距离下一级还需 200 积分
中级技术员, 积分 248, 距离下一级还需 52 积分
中级技术员, 积分 248, 距离下一级还需 52 积分
中级技术员, 积分 248, 距离下一级还需 52 积分
中级技术员, 积分 248, 距离下一级还需 52 积分
高级技术员, 积分 913, 距离下一级还需 87 积分
高级技术员, 积分 913, 距离下一级还需 87 积分
高级技术员, 积分 913, 距离下一级还需 87 积分
高级技术员, 积分 913, 距离下一级还需 87 积分
谢谢!学习了。
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
亲,这是主机还是从机程序
扫描二维码,随时随地手机跟帖
核心会员奖章
等级类勋章
坚毅之洋流
发帖类勋章
时间类勋章
技术导师奖章
人才类勋章
技术高手奖章
人才类勋章
涓涓之细流
发帖类勋章
时间类勋章
无冕之王奖章
等级类勋章
奔腾之江水
发帖类勋章
技术奇才奖章
人才类勋章
时间类勋章
技术新星奖章
人才类勋章
时间类勋章
欢快之小溪
发帖类勋章
社区建设奖章
等级类勋章
精华达人奖章
等级类勋章
湍急之河流
发帖类勋章
时间类勋章
您需要登录后才可以回帖

我要回帖

更多关于 ucos在stm32上的移植 的文章

 

随机推荐