STM32/STM8技术william hill官网
直播中

尹家军

10年用户 405经验值
擅长:MEMS/传感技术 测量仪表 嵌入式技术 接口/总线/驱动 控制/MCU
私信 关注
[经验]

【STM32L476 Nucleo试用体验】串行通讯实验


在我们的项目需求中,有两个串口应用需求,一个是与炭氢传感器的通讯,另一个是与显示屏的通讯。鉴于此,我们需要实验串行通讯。

1、硬件设计

串行通讯一个采用RS232接口,另一个直接采用TTL方式。我们在STM32L476RG开发板中,发现USART1USART3的输入输出端口已经引出来,所以我们使用这两个串口。

USART1_TX           PA9              CN5-1

USART1_RX          PA10     CN9-3

USART3_TX           PC4              CN10-34

USART3_RX          PC5              CN10-6

如下图红色方框中所示:

3-1.jpg

对于RS232接口我们采用了周立功RSM232模块来做实验,其推荐的连接方式如下图:

3-2.png

在实验过程中我们不需要这些保护措施,根据以上的分析我们可以对串口通讯做如下设计。RS232接口原理图如下:

3-3.png

对于单总线TTL通讯,我们采用如下原理图来实现:

3-4.png

2、软件设计

完成硬件连接后我们可以开始软件开发了,首先我们在STM32CubeMX中对硬件部分进行配置。其中USART1USART3的配置如下图所示:

3-5.png

而后对串口部分做参数配置,波特率等按要求配置好,很简单在此不多说了。接下来编写测试代码。

static void Test_UART_Configuration(void)

{

  huart1.Instance = USART1;

  huart1.Init.BaudRate = 115200;

  huart1.Init.WordLength =UART_WORDLENGTH_8B;

  huart1.Init.StopBits =UART_STOPBITS_1;

  huart1.Init.Parity =UART_PARITY_NONE;

  huart1.Init.Mode =UART_MODE_TX_RX;

  huart1.Init.HwFlowCtl =UART_HWCONTROL_NONE;

  huart1.Init.OverSampling =UART_OVERSAMPLING_16;

  if (HAL_UART_Init(&huart1) !=HAL_OK)

  {

    Error_Handler();

  }

定义一个简单的类Modbus通讯协议,采用中断方式来实现数据接收。中断处理函数如下:

voidUSART1_ReceiveDataHandle(void)

{

if(ozonatorRxLength>=RETURNING_DATA_LENGTH)

  {

    ozonatorRxLength=0;

  }

  /*接收寄存器为空,等待字节被对应的串口完全接收*/

if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)!=RESET)

  {

    uint8_t rData;

    /*获取接收到的字节*/

   HAL_UART_Receive(&huart1,&rData,1,1000);

    TestRxBuffer[ozonatorRxLength++] = rData;

  }

}

对接收到的信息进行解析,并根据请求命令完成放回信息的编码并回传。

/*解析接收到的信息,并返回合成的回复信息和信息的字节长度,通过回调函数*/

uint16_t ParsingMasterAccessCommand(uint8_t *receivedMessage,uint8_t*respondBytes,uint16_t rxLength)

{

  uint16_t respondLength=0;

  /*判断是否是本站,如不是不处理*/

  uint8_tslaveAddress=*receivedMessage;

  if(slaveAddress!=StationAddress)

  {

    return 0;

  }

  

  /*判断功能码是否有误*/

  FunctionCodefc=(FunctionCode)(*(receivedMessage+1));

  if(CheckFunctionCode(fc)!=MB_OK)

  {

    return 0;

  }

  

  /*信息校验,如不正确则为错误信息不用处理*/

  uint16_t dataLength=8;

if((fc==WriteMultipleCoil)||(fc==WriteMultipleRegister))

  {

   dataLength=(uint16_t)(*(receivedMessage+6))+9;

    if(rxLength尚未接收完整

    {

      return 65535;

    }

  }

  boolchechMessageNoError=CheckRTUMessageIntegrity(receivedMessage,dataLength);

  if(!chechMessageNoError)

  {

    return 0;

  }


  uint16_tstartAddress=(uint16_t)(*(receivedMessage+2));

startAddress=(startAddress<<8)+(uint16_t)(*(receivedMessage+3));

  uint16_tquantity=(uint16_t)(*(receivedMessage+4));

quantity=(quantity<<8)+(uint16_t)(*(receivedMessage+5));

  

  uint8_tindex=(fc>0x08)?(fc-0x09):(fc-0x01);

  

respondLength=HandleMasterCommand[index](startAddress,quantity,receivedMessage,respondBytes);


  return respondLength;

}

3、测试结果

通过USBRS232接口的模块接入电脑通过AccessPort和串口出手来对通讯进行测试。下图是在AccessPort中监控到的数据收发状态:

3-6.png

下图是在串口助手中发送命令及接收反馈的截图:

3-7.png

串口通讯方式测试完成,完全能符合我们的要求。

更多回帖

×
20
完善资料,
赚取积分