STM32
直播中

刘洋

10年用户 1130经验值
擅长:可编程逻辑 嵌入式技术
私信 关注
[问答]

STM32F107开发板外设有哪些

STM32F107开发板外设有哪些?

有哪些应用呢?

回帖(1)

洪欣意

2021-11-3 15:35:01
     在STM32F107环境下实现如下功能:
  -以太网接口用作串口使用(区别于C / S模型);
  -以太网接口接收全部的网内数据;
  -对网内数据过滤,仅接收本相关数据包及包广播;
  工具:
  anysend.exe:Anysend是基于Winpcap自组开发的数据包,实现接口发送任意数据包的工具,各位请自行寻找下载;
  wirehark.exe:网络抓捕工具
  如果你是一个嵌入式开发人员,
  MDK:嵌入式集成开发环境;
  开发板:载stm32f107处理器+的开发板;
  简要说下开发板外设:
  开发外设
  
  接口:使用SMI(MDC、MDIO)接口物理接口,参见下图的指引:
  
  DMA发送占用(占用资源略):
  
  相关接口的配置,主要关注MAC和DMA接口:
  
  可能到的、DMA相关
  
  接口如下:MAC地址如下:
  
  部分资源:
  接收数据处理程序:
  /**
  * @brief Called when a frame is received
  * @param None
  * @retval None
  */
  void ETH_RxPkt_Handle(void)
  {
  u8 *buffer;
  u16 len;
  FrameTypeDef frame;
  frame = ETH_RxPkt_ChainMode();
  /* Obtain the size of the packet and put it into the “len”
  variable. */
  len = frame.length;
  buffer= (u8*)frame.buffer;
  memcpy(buff_rx,(u8*)&buffer[0], len);
  /* Set Own bit of the Rx descriptor Status: gives the buffer back to ETHERNET DMA
  设置Rx描述符Status的 OWN位*/
  frame.descriptor-》Status = ETH_DMARxDesc_OWN;
  /* When Rx Buffer unavailable flag is set: clear it and resume reception
  Rx缓冲区不可用时,清除ETH_DMASR_RBUS并且恢复接收*/
  if ((ETH-》DMASR & ETH_DMASR_RBUS) != (u32)RESET)
  {
  /* Clear RBUS ETHERNET DMA flag */
  ETH-》DMASR = ETH_DMASR_RBUS;
  /* Resume DMA reception */
  ETH-》DMARPDR = 0;
  }
  //ETH_DMA_test();
  }
  获取接收到的数据信息(DMA描述符)
  /*******************************************************************************
  * Function Name : ETH_RxPkt_ChainMode
  * Description : 获取接收到的数据信息(DMA描述符)
  * Input : None
  * Output : None
  * Return : frame: farme size and location
  *******************************************************************************/
  FrameTypeDef ETH_RxPkt_ChainMode(void)
  {
  u32 framelength = 0;
  FrameTypeDef frame = {0,0};
  /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset)
  检查这个描述符在被谁占用,DMA? CPU?*/
  if((DMARxDescToGet-》Status & ETH_DMARxDesc_OWN) != (u32)RESET)
  { //不等于0,表示DMA正在使用描述符对应的缓冲区, 0==CPU占有,1==DMA占有,
  frame.length = ETH_ERROR;
  if ((ETH-》DMASR & ETH_DMASR_RBUS) != (u32)RESET)
  {
  /* Clear RBUS ETHERNET DMA flag */
  ETH-》DMASR = ETH_DMASR_RBUS;
  /* Resume DMA reception */
  ETH-》DMARPDR = 0;
  }
  /* Return error: OWN bit set */
  return frame;
  }
  if(((DMARxDescToGet-》Status & ETH_DMARxDesc_ES) == (u32)RESET) && //无相关错误
  ((DMARxDescToGet-》Status & ETH_DMARxDesc_LS) != (u32)RESET) && //这个描述符指向的缓冲区是帧的最后一个缓冲区
  ((DMARxDescToGet-》Status & ETH_DMARxDesc_FS) != (u32)RESET)) //这个描述符包含帧的第一个缓冲区
  {
  /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC
  获取接收数据包的长度,需要减掉4字节的CRC*/
  framelength = ((DMARxDescToGet-》Status & ETH_DMARxDesc_FL) 》》 ETH_DMARxDesc_FrameLengthShift) - 4;
  /* Get the addrees of the actual buffer */
  frame.buffer = DMARxDescToGet-》Buffer1Addr;
  }
  else
  {
  /* Return ERROR */
  framelength = ETH_ERROR;
  }
  frame.length = framelength;
  frame.descriptor = DMARxDescToGet;
  /* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor
  更新DMA全局Rx描述符成为下一个Rx描述符*/
  /* Chained Mode ==链表模式*/
  /* Selects the next DMA Rx descriptor list for next buffer to read
  选择下一个DMA Rx描述符链表为下一个缓冲区去读*/
  DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet-》Buffer2NextDescAddr);
  /* Return Frame */
  return (frame);
  }
  发送数据包的处理程序:
  err_t ETH_TxPkt_Handle(u8* buff,u16 len)
  {
  int l = 0;
  u8 *buffer = (u8 *)ETH_GetCurrentTxBuffer();//获取当前的发送缓冲区地址
  memcpy((u8*)&buffer[l], buff, len);
  while(ETH_ERROR== ETH_TxPkt_ChainMode(len));
  return 0;
  }
  更新DMA发送长度:
  /*******************************************************************************
  * Function Name : ETH_TxPkt_ChainMode
  * Description : Transmits a packet, from application buffer, pointed by ppkt.
  * Input : - FrameLength: Tx Packet size.
  * Output : None
  * Return : ETH_ERROR: in case of Tx desc owned by DMA
  * ETH_SUCCESS: for correct transmission
  *******************************************************************************/
  u32 ETH_TxPkt_ChainMode(u16 FrameLength)
  {
  /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
  if((DMATxDescToSet-》Status & ETH_DMATxDesc_OWN) != (u32)RESET)
  { //被DMA占用
  /* Return ERROR: OWN bit set */
  return ETH_ERROR;
  }
  /* Setting the Frame Length: bits[12:0]
  设置帧长*/
  DMATxDescToSet-》ControlBufferSize = (FrameLength & ETH_DMATxDesc_TBS1);
  /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
  DMATxDescToSet-》Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
  /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
  DMATxDescToSet-》Status |= ETH_DMATxDesc_OWN;
  /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
  if ((ETH-》DMASR & ETH_DMASR_TBUS) != (u32)RESET)
  {
  /* Clear TBUS ETHERNET DMA flag */
  ETH-》DMASR = ETH_DMASR_TBUS;
  /* Resume DMA transmission*/
  ETH-》DMATPDR = 0;
  }
  /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */
  /* Chained Mode */
  /* Selects the next DMA Tx descriptor list for next buffer to send */
  DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet-》Buffer2NextDescAddr);
  /* Return SUCCESS */
  return ETH_SUCCESS;
  }
  应用:
  接口接口接口使用(于C接口/S模型):
  在MAC帧过滤过滤接口上文章:
  ETH_InitStruc.ETH_ReceiveAll = ETH_ReceiveAll_Enable;//
  关于发送数据接口,可以发送以太网II协议,不能检测发送IEEE802.3帧,问题寻找中;
  接收接口接收全部的网内数据:
  同上…
  对网内数据包过滤,仅接收本机相关数据包及广播包;
  ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;//关闭接收所有的帧,来实现过滤掉 非本机为目的地址的数据
  ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;//允许接收所有广播帧
  ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable; //关闭混合模式的地址过滤
  ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;//对于组播地址使用完美地址过滤
  ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;//对单播地址使用完美地址过滤
举报

更多回帖

发帖
×
20
完善资料,
赚取积分