OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5314|回复: 7

有人能帮我看一下代码吗? STM32F407基于485接口的MODBUS协议通讯的数据获取

[复制链接]

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2019-11-23
在线时间
12 小时
发表于 2020-4-6 00:21:43 | 显示全部楼层 |阅读模式
10金钱
每次按一下复位按钮才会获取新数据,不然就是一直循环打印第一次获取的数据
  1. main.c
  2. =====================================================================
  3. #include "stm32f4xx.h"
  4. #include "usart.h"
  5. #include "delay.h"
  6. #include "MODBUS_Master.h"

  7. extern u16 Master_ReadReg[1000];          //主机接收缓冲区
  8. extern u8 RS485_TX_BUFF[2048];
  9. extern u8 RS485_RX_BUFF[2048];
  10. volatile u16 wx;
  11. int main(void)
  12. {
  13.         u8 i;       
  14.         SystemInit();
  15.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  16.         delay_init(168);                        //延时函数初始化          
  17.         uart_init(57600);                //串口初始化为115200
  18.                
  19.         Modbus_RegMap();
  20.         Master_USART2_Init();
  21.         Timer4_enable(5000);        //500ms        通讯节拍          
  22.         while(1)
  23.         {
  24.                 /*   RS485_RX_BUFF[4]  是风向数据 ,但无法实时读取*/
  25.                 for(i=0;i<8;i++)
  26.                         {
  27.                                 printf("%x \r",RS485_TX_BUFF[i]);
  28.                         }
  29.                                 printf("\n");
  30.                 for(i=0;i<8;i++)
  31.                         {
  32.                                 printf("%x \r",RS485_RX_BUFF[i]);
  33.                         }       
  34.                         printf("\n");
  35.                         printf("%x\r",RS485_RX_BUFF[4]);
  36.                         printf("%x\r",wx);                       
  37.                 printf("\n");
  38.                 delay_ms(1000);

  39.         }
  40.          
  41.                                                                          
  42. }
复制代码
  1. modbus.c
  2. =====================================================================
  3. #include "MODBUS_Master.h"
  4. #include "crc16.h"
  5. u32 Master_Baudrate=4800;                //通讯波特率
  6. u8         Master_Parity=0;                                        //0无校验;1奇校验;2偶校验
  7. u16 RS485_Frame_Distance=4;        //数据帧最小间隔(ms),超过此时间则认为是下一帧

  8. u8 RS485_RX_BUFF[2048];                        //接收缓冲区2048字节
  9. u16 RS485_RX_CNT=0;//接收计数器
  10. u8 RS485_RxFlag=0;//接收一帧结束标记

  11. u8 RS485_TX_BUFF[2048];//发送缓冲区
  12. u16 RS485_TX_CNT=0;//发送计数器
  13. u8 RS485_TxFlag=0;//发送一帧结束标记

  14. extern volatile u16 wx;
  15. ////////////////////////////////////////////////////////////////////////////////////////////////////////////

  16. //主机命令区
  17. u8   SlaverAddr = 0x01;             //从机地址
  18. u8   Fuction = 0x03;                //功能码
  19. u16  StartAddr = 0x0000;      //起始地址
  20. u16  ValueOrLenth = 0x0002;   //数据or长度
  21. ////////////////////////////////////////////////////////////////////////////////////////////////////////////

  22. u8 TX_RX_SET=0; //发送,接受命令切换。 0 发送模式 1接受模式
  23. u8 ComErr=8;                 //0代表通讯正常
  24.                                         //1代表CRC错误
  25.                                         //2代表功能码错误
  26.                        
  27. ////////////////////////////////////////////////////////////////////////////////////////////////////////////

  28. //Master寄存器和单片机寄存器的映射关系
  29. u16   Master_InputIO[100];  //输入开关量寄存器(这里使用的是位带操作)           注意: 这里储存从机返回的数据。    开关量的数据只能是0,1 例如 Master_InputIO[5]=0;Master_InputIO[8]=1;
  30. u16   Master_OutputIO[100]; //输出(给从机)开关量寄存器(这里使用的是位带操作)           功能码 05 15

  31. u16                Master_ReadReg[1000]; //只读寄存器----存储从机返回的数据                功能码 03
  32. u16          Master_WriteReg[1000];//写(写从机)寄存器-------将寄存器中的数据送给从机         功能码 06 16

  33. //u32         testData1=1201,testData2=1002,testData3=2303,testData4=8204;

  34. void Modbus_RegMap(void)
  35. {
  36.         Master_WriteReg[0]=1;
  37.         Master_WriteReg[1]=8;
  38.         Master_WriteReg[2]=9;
  39.         Master_WriteReg[3]=235;
  40.         Master_WriteReg[4]=8690;
  41.         Master_WriteReg[5]=23578;
  42.         Master_WriteReg[6]=125;
  43.        
  44.         Master_OutputIO[20]=1;
  45.         Master_OutputIO[21]=0;
  46.         Master_OutputIO[22]=1;
  47.         Master_OutputIO[23]=1;
  48.         Master_OutputIO[24]=0;
  49.         Master_OutputIO[25]=0;
  50.         Master_OutputIO[26]=1;
  51.         Master_OutputIO[27]=1;
  52.        
  53.         Master_OutputIO[28]=1;
  54.         Master_OutputIO[29]=0;               
  55. }

  56. ///////////////////////////////////////////////////////////////////////////////////////////////////
  57. void Master_USART2_Init(void)
  58. {
  59.         GPIO_InitTypeDef GPIO_InitStructure;
  60.         NVIC_InitTypeDef NVIC_InitStructure;
  61.         USART_InitTypeDef USART_InitStructure;
  62.        
  63.         /*使能使用的外设时钟*/
  64.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);                //GPIOA、GPIOG时钟使能
  65.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);                //串口2时钟使能

  66.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
  67.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);

  68.         /*GPIOA_Pin_2----USART2_Tx发送端*/
  69.         /*GPIOA_Pin_3----USART2_Rx接收端*/
  70.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
  71.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                                                //复用输出
  72.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                                        //推挽复用
  73.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  74.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  75.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  76.                
  77.         //PC23端口配置,控制485是处于发送状态还是接收状态
  78.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
  79.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                                                //普通输出
  80.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                                        //推挽输出
  81.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  82.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  83.         GPIO_Init(GPIOC, &GPIO_InitStructure);
  84.        
  85.         USART_DeInit(USART2);  //复位串口2
  86.        
  87.         //USART2通信配置
  88.         USART_InitStructure.USART_BaudRate = Master_Baudrate;//波特率
  89.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据位
  90.         USART_InitStructure.USART_StopBits = USART_StopBits_1;//1位停止位
  91.         switch (Master_Parity)   //0无校验;1奇校验;2偶校验
  92.         {
  93.                         case 0:
  94.                                         USART_InitStructure.USART_Parity = USART_Parity_No;     //无奇偶校验
  95.                                         break;
  96.                         case 1:
  97.                                         USART_InitStructure.USART_Parity = USART_Parity_Odd;    //奇模式            
  98.                                         break;
  99.                         case 2:
  100.                                         USART_InitStructure.USART_Parity = USART_Parity_Even;   //偶模式
  101.                                         break;
  102.                         default:
  103.                                         break;
  104. }       
  105.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流控制
  106.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送与接收模式
  107.         USART_Init(USART2, &USART_InitStructure);//初始化串口2
  108.        
  109.         USART_ClearITPendingBit(USART2,USART_IT_RXNE);  //清除串口2的中断标志位 RXNE:读数据寄存器非空(后续将数据读入RX_BUFF)
  110.         USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);    //使能串口2接收中断
  111.        
  112.         //Usart2的NVIC配置
  113.         NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  114.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;        //抢占优先级2
  115.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;                                //响应优先级2
  116.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                //IRQ通道使能
  117.         NVIC_Init(&NVIC_InitStructure);                                        //根据指定的参数初始化NVIC寄存器
  118.        
  119.         USART_Cmd(USART2, ENABLE);                //使能串口2
  120.         RS485_TX_EN = 0;                                                        //默认为接收状态
  121.         RS485_RX_EN = 0;
  122.         Timer7_Init();                                                                //定时器7初始化,用于监视空闲时间
  123. }

  124. //定时器4初始化
  125. //定时1s进行通讯,分2步:前500ms进行发送功能,后500ms处理从机返回的数据
  126. void Timer4_enable(u16 arr)                   //TIM4使能
  127. {
  128.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  129.         NVIC_InitTypeDef NVIC_InitStructure;

  130.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能
  131.        
  132.         TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
  133.         TIM_TimeBaseStructure.TIM_Prescaler = 7199; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
  134.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  135.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  136.         TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

  137.         TIM_ITConfig(  //使能或者失能指定的TIM中断
  138.                 TIM4, //TIM2
  139.                 TIM_IT_Update  |  //TIM 中断源
  140.                 TIM_IT_Trigger,   //TIM 触发中断源
  141.                 ENABLE  //使能
  142.                 );

  143.         NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
  144.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占优先级0级
  145.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //响应优先级3级
  146.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  147.         NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

  148.         TIM_Cmd(TIM4, ENABLE);  //使能TIM4外设                                                         
  149. }

  150. ///////////////////////////////////////////////////////////////////////////////////////////////
  151. //定时器7初始化---功能:判断从机返回的数据是否接受完成
  152. void Timer7_Init(void)
  153. {
  154.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  155.         NVIC_InitTypeDef NVIC_InitStructure;

  156.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); //TIM7时钟使能

  157.         //TIM7初始化设置
  158.         TIM_TimeBaseStructure.TIM_Period = RS485_Frame_Distance*10; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值     =4;        //数据帧最小间隔(40=4ms),超过此时间则认为是下一帧
  159.         TIM_TimeBaseStructure.TIM_Prescaler =7199; //设置用来作为TIMx时钟频率除数的预分频值 设置计数频率为10kHz
  160.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  161.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  162.         TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

  163.         TIM_ITConfig( TIM7, TIM_IT_Update, ENABLE );//TIM7 允许更新中断

  164.         //TIM7中断分组配置
  165.         NVIC_InitStructure.NVIC_IRQChannel =TIM7_IRQn;  //TIM7中断
  166.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //抢占优先级2级
  167.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //响应优先级3级
  168.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  169.         NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器                                                                  
  170. }

  171. /////////////////////////////////////////////////////////////////////////////////////
  172. void USART2_IRQHandler(void)//串口2中断服务程序
  173. {   
  174.         u8 res;
  175.         u8 err;
  176.         if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
  177.         {
  178.                 //清除中断标志位
  179.                 //USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  180.                 USART2->SR &= ~(0x1<<5);               
  181.                 if(USART_GetFlagStatus(USART2,USART_FLAG_NE|USART_FLAG_FE|USART_FLAG_PE))
  182.                         err=1;//检测到噪音、帧错误或校验错误
  183.                 else
  184.                         err=0;
  185.                
  186.                         res=USART_ReceiveData(USART2); //读接收到的字节,同时相关标志自动清除
  187.                 if((RS485_RX_CNT<2047)&&(err==0))
  188.                 {
  189.                         RS485_RX_BUFF[RS485_RX_CNT]=res;
  190.                         RS485_RX_CNT++;
  191.                        
  192.                         TIM_ClearITPendingBit(TIM7,TIM_IT_Update);//清除定时器溢出中断
  193.                         TIM_SetCounter(TIM7,0);//当接收到一个新的字节,将定时器7复位为0,重新计时(相当于喂狗)
  194.                         TIM_Cmd(TIM7,ENABLE);//开始计时
  195.                 }
  196.         }
  197. }
  198. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  199. void TIM4_IRQHandler(void)   //TIM4中断
  200. {
  201.         if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET) //检查指定的TIM中断发生与否:TIM 中断源
  202.         {
  203.                 TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除TIMx的中断待处理位:TIM 中断源 ;
  204.                 modbus_rtu();       
  205.         }
  206. }

  207. ///////////////////////////////////////////////////////////////////////////////////////
  208. //用定时器7判断接收空闲时间,当空闲时间大于指定时间,认为一帧结束
  209. //定时器7中断服务程序         
  210. void TIM7_IRQHandler(void)
  211. {        
  212.         if(TIM_GetITStatus(TIM7,TIM_IT_Update)!=RESET)
  213.         {
  214.                 TIM_ClearITPendingBit(TIM7,TIM_IT_Update);//清除中断标志
  215.                 TIM_Cmd(TIM7,DISABLE);//停止定时器
  216.        
  217.                 RS485_TX_EN = 1;//停止接收,切换为发送状态
  218.                 RS485_RX_EN = 1;
  219.                 RS485_RxFlag=1;//置位帧结束标记
  220.         }
  221. }

  222. //////////////////////////////////////////////////////////////////////////////
  223. //发送n个字节数据
  224. //buff:发送区首地址
  225. //len:发送的字节数
  226. void RS485_SendData(u8 *buff,u8 len)
  227. {
  228.         RS485_TX_EN = 1;//切换为发送状态
  229.         RS485_RX_EN = 1;       
  230.         while(len--)
  231.         {
  232.                 while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);//等待发送区为空
  233.                 USART_SendData(USART2,*(buff++));
  234.         }
  235.         while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);//等待发送完成
  236.         TX_RX_SET=1; //发送命令完成,定时器T4处理接收到的数据
  237.         RS485_TX_EN = 0;//接收状态
  238.         RS485_RX_EN = 0;
  239. }


  240. /////////////////////////////////////////////////////////////////////////////////////
  241. void modbus_rtu(void)
  242. {       
  243.         static u8 i=0;
  244.         static u8 j=0;
  245.         switch(i)
  246.         {
  247.                 case 0:
  248.                         RS485_TX_Service();
  249.                         if(TX_RX_SET) i=1;
  250.                         break;
  251.                 case 1:
  252.                         RS485_RX_Service();
  253.                         if(TX_RX_SET == 0) i=0;
  254.                         if(ComErr==0) //数据正确
  255.                         {
  256.                                 i=0;//完成命令更换功能码!
  257.                         }
  258.                         else
  259.                         {
  260.                                 i=1;//
  261.                                 j++;//一个命令发送3次没有应答切换下一个命令
  262.                                 if(j>=2)
  263.                                 {
  264.                                         j=0;
  265.                                         i=0;
  266.                                         ComErr=7;  //通讯超时
  267.                                 }
  268.                                
  269.                         }
  270.                         break;
  271. /*        case 2: //从机地址++
  272.                         //SlaverAddr++;
  273.                         break;
  274.         case 3://功能码
  275.                         break;                               
  276. */               
  277.         }
  278. }

  279. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  280. ///////////////////////////////////////////主机发送指令(起点)////////////////////////////////////////////////////////
  281. //Modbus功能码03处理程序///////////////////////////////////////////////////////////////////////////////////////
  282. //读保持寄存器
  283. void Master_03_Slove( u8 board_adr,u16 start_address,u16 lenth )
  284. {
  285.         u16 calCRC;
  286.     RS485_TX_BUFF[0] = board_adr;   //0x01
  287.     RS485_TX_BUFF[1] = READ_HLD_REG;    //modbus 指令码0x03
  288.     RS485_TX_BUFF[2] = HI(start_address);  //0x00
  289.     RS485_TX_BUFF[3] = LOW(start_address); //0x00
  290.     RS485_TX_BUFF[4] = HI(lenth);                   //0x00       
  291.     RS485_TX_BUFF[5] = LOW(lenth);         //0x02
  292.     calCRC=CRC_Compute(RS485_TX_BUFF,6);
  293.     RS485_TX_BUFF[6]=(calCRC>>8)&0xFF;
  294.     RS485_TX_BUFF[7]=(calCRC)&0xFF;
  295.         RS485_SendData(RS485_TX_BUFF,8);

  296. }
  297. ///////////////////////////////////////////主机发送指令////////////////////////////////////////////////////////
  298. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  299. void RS485_TX_Service(void)
  300. {
  301.         Master_03_Slove(SlaverAddr,StartAddr,ValueOrLenth);       
  302. }
  303. /////////////////////////////////////////////////////////////////////////////////////
  304. //RS485服务程序,用于处理接收到的数据(请在主函数中循环调用)
  305. void RS485_RX_Service(void)
  306. {
  307.         u16 calCRC;
  308.         u16 recCRC;
  309.         if(RS485_RxFlag==1)
  310.         {
  311.                 if(RS485_RX_BUFF[0]==SlaverAddr)//地址正确
  312.                 {
  313.                         if(RS485_RX_BUFF[1] == 0x03)//功能码正确
  314.                         {
  315.                                 calCRC=CRC_Compute(RS485_RX_BUFF,RS485_RX_CNT-2);//计算所接收数据的CRC
  316.                                 recCRC=RS485_RX_BUFF[RS485_RX_CNT-1]|(((u16)RS485_RX_BUFF[RS485_RX_CNT-2])<<8);//接收到的CRC(低字节在前,高字节在后)
  317.                                 if(calCRC==recCRC)//CRC校验正确
  318.                                 {
  319.                                         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  320.                                         if(RS485_RX_BUFF[1] == 0x03)//0x03功能码进行处理
  321.                                         {                                                                                                                                                                               
  322.                                                 Modbus_03_Solve();                                       
  323.                                         }
  324.                                 }
  325.                                 else//CRC校验错误
  326.                                 {
  327.                                         ComErr=14;
  328.                                        
  329.                                         return ;
  330.                                 }                                                                                       
  331.                         }
  332.                         else//功能码错误
  333.                         {
  334.                         /*        if((RS485_RX_BUFF[1]==0x81)||(RS485_RX_BUFF[1]==0x82)||(RS485_RX_BUFF[1]==0x83)||(RS485_RX_BUFF[1]==0x85)||(RS485_RX_BUFF[1]==0x86)||(RS485_RX_BUFF[1]==0x8F)||(RS485_RX_BUFF[1]==0x90))
  335.                                 {
  336.                                         switch(RS485_RX_BUFF[2])
  337.                                         {
  338.                                                 case 0x01:
  339.                                                                 ComErr=11;break;
  340.                                                 case 0x02:
  341.                                                                 ComErr=12;break;
  342.                                                 case 0x03:
  343.                                                                 ComErr=13;break;
  344.                                                 case 0x04:
  345.                                                                 ComErr=14;break;
  346.                                         }
  347.                                         TX_RX_SET=0; //命令完成       
  348.                                 }
  349.                         */
  350.                                 TX_RX_SET=0; //命令完成       
  351.                                 return ;
  352.                         }
  353.           }                                                       
  354.         RS485_RxFlag=0;//复位帧结束标志
  355.         RS485_RX_CNT=0;//接收计数器清零
  356.         RS485_TX_EN = 1;//开启发送模式        
  357.         RS485_RX_EN = 1;

  358.         TX_RX_SET=0; //命令完成
  359.         }               
  360. }

  361. //Modbus功能码03处理程序///////////////////////////////////////////////////////////////////////////////////////已验证程序OK
  362. //读保持寄存器
  363. void Modbus_03_Solve(void)
  364. {
  365.         u8 i;
  366.         u8 RegNum;
  367.         RegNum= RS485_RX_BUFF[2]/2;//获取字节数 4/2=2
  368.         if((StartAddr+RegNum)<1000)//寄存器地址+数量在范围内
  369.         {
  370.                 for(i=0;i<RegNum;i++)
  371.                 {
  372.                    Master_ReadReg[StartAddr+i]= RS485_RX_BUFF[3+i*2];           /////////高8位
  373.                    Master_ReadReg[StartAddr+i]= RS485_RX_BUFF[4+i*2]+(Master_ReadReg[StartAddr+i]<<8);// 低8位+高8位 0x0? +0x00= 0x0?
  374.                
  375.                 }
  376.                 wx = *Master_ReadReg;
  377.                 ComErr=0;
  378.                 //LED1 = 0;//////验证程序,验证主机是否接收到从机响应报文
  379.         }
  380.         else
  381.         {
  382.                 ComErr=3;
  383.         }
  384.         TX_RX_SET=0; //命令完成
  385. }
复制代码


最佳答案

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2019-11-23
在线时间
12 小时
 楼主| 发表于 2020-4-6 00:21:44 | 显示全部楼层
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2019-11-23
在线时间
12 小时
 楼主| 发表于 2020-4-9 11:18:48 | 显示全部楼层
已解决
回复

使用道具 举报

5

主题

179

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
8195
金钱
8195
注册时间
2016-9-7
在线时间
1113 小时
发表于 2020-4-9 21:32:54 | 显示全部楼层
楼主,是哪里问题
回复

使用道具 举报

1

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-2-13
在线时间
22 小时
发表于 2020-7-10 20:12:05 | 显示全部楼层
请问楼主师兄是怎么解决的?感谢
回复

使用道具 举报

2

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2020-7-17
在线时间
16 小时
发表于 2020-7-17 11:06:59 | 显示全部楼层
师兄你好!我导师最近要我学这个 STM32F407基于485接口的MODBUS协议通讯,我没什么基础,师兄能不能给些建议呀?
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-7-17 14:40:54 | 显示全部楼层
JIM积木 发表于 2020-7-17 11:06
师兄你好!我导师最近要我学这个 STM32F407基于485接口的MODBUS协议通讯,我没什么基础,师兄能不能给些建 ...

freemodbus  xtinymodbus
回复

使用道具 举报

1

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2020-9-29
在线时间
36 小时
发表于 2021-1-11 15:24:02 | 显示全部楼层
你好,请问可以发一下源码吗?1019296329@qq.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-3-1 02:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表