你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32串口直通

[复制链接]
anobodykey 发布时间:2017-9-8 22:06
所谓的串口直通是指MCU把从USART1接口收到的数据送往USART2接口处发送出去,由USART2->USART1情况类似。这个时候MCU只是当作一个调试模块,而不做任何操作,举个例子:比如蓝牙模块的接口是串口,我们想要使用MCU来对蓝牙模块进行读写控制,在调试时我们需要确定蓝牙模块是否良好,这个时候就可以使用串口直通模式来测试与蓝牙模块的通信是否良好,代码很简单只是开启了DMA即可,如下:
  1. #define USARTx                          USART1
  2. #define USARTx_GPIO_PORT                GPIOA
  3. #define USARTx_TX_PIN                   GPIO_Pin_9
  4. #define USARTx_TX_SOURCE                GPIO_PinSource9
  5. #define USARTx_TX_AF                    GPIO_AF_1
  6. #define USARTx_RX_PIN                   GPIO_Pin_10
  7. #define USARTx_RX_SOURCE                GPIO_PinSource10
  8. #define USARTx_RX_AF                    GPIO_AF_1
  9. #define USARTx_IRQn                     USART1_IRQn
  10. #define USARTx_IRQHandler               USART1_IRQHandler
  11. #define USARTx_CLK_ENABLE()             RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE)
  12. #define USARTx_DMA_CLK_ENABLE()         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE)
  13. #define USARTx_GPIO_CLK_ENABLE()        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE)

  14. #define USARTx_RDR_ADDRESS              (uint32_t)&USARTx->RDR
  15. #define USARTx_RX_DMA_CHANNEL           DMA1_Channel3
  16. #define USARTx_TDR_ADDRESS              (uint32_t)&USARTx->TDR
  17. #define USARTx_TX_DMA_CHANNEL           DMA1_Channel2


  18. #define ISP_USARTx                      USART2
  19. #define ISP_USARTx_GPIO_PORT            GPIOA
  20. #define ISP_USARTx_GPIO_CLK             RCC_AHBPeriph_GPIOA
  21. #define ISP_USARTx_TX_PIN               GPIO_Pin_2
  22. #define ISP_USARTx_TX_SOURCE            GPIO_PinSource2
  23. #define ISP_USARTx_TX_AF                GPIO_AF_1
  24. #define ISP_USARTx_RX_PIN               GPIO_Pin_3
  25. #define ISP_USARTx_RX_SOURCE            GPIO_PinSource3
  26. #define ISP_USARTx_RX_AF                GPIO_AF_1
  27. #define ISP_USARTx_IRQn                 USART2_IRQn
  28. #define ISP_USARTx_IRQHandler           USART2_IRQHandler
  29. #define ISP_USARTx_CLK_ENABLE()         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE)
  30. #define ISP_USARTx_DMA_CLK_ENABLE()     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE)
  31. #define ISP_USARTx_GPIO_CLK_ENABLE()    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE)

  32. #define ISP_USARTx_RDR_ADDRESS          (uint32_t)&ISP_USARTx->RDR
  33. #define ISP_USARTx_RX_DMA_CHANNEL       DMA1_Channel5
  34. #define ISP_USARTx_TDR_ADDRESS          (uint32_t)&ISP_USARTx->TDR
  35. #define ISP_USARTx_TX_DMA_CHANNEL       DMA1_Channel4

  36. void uart_init (uint8_t baud)
  37. {
  38.     USART_InitTypeDef USART_InitStructure;   
  39.     GPIO_InitTypeDef GPIO_InitStructure;     
  40.     DMA_InitTypeDef DMA_InitStructure;
  41.      
  42.     USARTx_GPIO_CLK_ENABLE();
  43.     USARTx_DMA_CLK_ENABLE();
  44.     USARTx_CLK_ENABLE();

  45.     GPIO_PinAFConfig(USARTx_GPIO_PORT, USARTx_TX_SOURCE, USARTx_TX_AF);
  46.     GPIO_PinAFConfig(USARTx_GPIO_PORT, USARTx_RX_SOURCE, USARTx_RX_AF);

  47.     GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN| USARTx_RX_PIN;               
  48.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;      
  49.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   
  50.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
  51.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;  
  52.     GPIO_Init(USARTx_GPIO_PORT, &GPIO_InitStructure);  

  53.     USART_InitStructure.USART_BaudRate            = 115200;            
  54.     USART_InitStructure.USART_WordLength          = USART_WordLength_8b;  
  55.     USART_InitStructure.USART_StopBits            = USART_StopBits_1;     
  56.     USART_InitStructure.USART_Parity              = baud_type[baud&0x0F];     
  57.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
  58.     USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;   
  59.     USART_Init(USARTx, &USART_InitStructure);      
  60.      
  61.     DMA_InitStructure.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_Byte;
  62.     DMA_InitStructure.DMA_PeripheralInc         = DMA_PeripheralInc_Disable;
  63.     DMA_InitStructure.DMA_PeripheralBaseAddr    = USARTx_RDR_ADDRESS;
  64.     DMA_InitStructure.DMA_MemoryBaseAddr        = ISP_USARTx_TDR_ADDRESS;
  65.     DMA_InitStructure.DMA_MemoryDataSize        = DMA_MemoryDataSize_Byte;
  66.     DMA_InitStructure.DMA_MemoryInc             = DMA_MemoryInc_Disable;
  67.     DMA_InitStructure.DMA_BufferSize            = 1;
  68.     DMA_InitStructure.DMA_DIR                   = DMA_DIR_PeripheralSRC;
  69.     DMA_InitStructure.DMA_M2M                   = DMA_M2M_Disable;
  70.     DMA_InitStructure.DMA_Mode                  = DMA_Mode_Circular;
  71.     DMA_InitStructure.DMA_Priority              = DMA_Priority_High;
  72.     DMA_Init(USARTx_RX_DMA_CHANNEL, &DMA_InitStructure);

  73.     USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE);
  74.     DMA_Cmd(USARTx_RX_DMA_CHANNEL, ENABLE);
  75.     USART_Cmd(USARTx, ENABLE);  

  76. }


  77. void isp_init (void)
  78. {
  79.     USART_InitTypeDef USART_InitStructure;   
  80.     GPIO_InitTypeDef GPIO_InitStructure;     
  81.     DMA_InitTypeDef DMA_InitStructure;

  82.     ISP_USARTx_GPIO_CLK_ENABLE();
  83.     ISP_USARTx_DMA_CLK_ENABLE();
  84.     ISP_USARTx_CLK_ENABLE();

  85.     GPIO_PinAFConfig(ISP_USARTx_GPIO_PORT, ISP_USARTx_TX_SOURCE, ISP_USARTx_TX_AF);
  86.     GPIO_PinAFConfig(ISP_USARTx_GPIO_PORT, ISP_USARTx_RX_SOURCE, ISP_USARTx_RX_AF);

  87.     GPIO_InitStructure.GPIO_Pin = ISP_USARTx_TX_PIN| ISP_USARTx_RX_PIN;               
  88.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;      
  89.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     
  90.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
  91.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;  
  92.     GPIO_Init(ISP_USARTx_GPIO_PORT, &GPIO_InitStructure);  

  93.     USART_InitStructure.USART_BaudRate            = 115200;            
  94.     USART_InitStructure.USART_WordLength          = USART_WordLength_8b;  
  95.     USART_InitStructure.USART_StopBits            = USART_StopBits_1;     
  96.     USART_InitStructure.USART_Parity              = USART_Parity_No;     
  97.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
  98.     USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;   
  99.     USART_Init(ISP_USARTx, &USART_InitStructure);      

  100.     DMA_InitStructure.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_Byte;
  101.     DMA_InitStructure.DMA_PeripheralInc         = DMA_PeripheralInc_Disable;
  102.     DMA_InitStructure.DMA_PeripheralBaseAddr    = ISP_USARTx_RDR_ADDRESS;
  103.     DMA_InitStructure.DMA_MemoryBaseAddr        = USARTx_TDR_ADDRESS;
  104.     DMA_InitStructure.DMA_MemoryDataSize        = DMA_MemoryDataSize_Byte;
  105.     DMA_InitStructure.DMA_MemoryInc             = DMA_MemoryInc_Disable;
  106.     DMA_InitStructure.DMA_BufferSize            = 1;
  107.     DMA_InitStructure.DMA_DIR                   = DMA_DIR_PeripheralSRC;
  108.     DMA_InitStructure.DMA_M2M                   = DMA_M2M_Disable;
  109.     DMA_InitStructure.DMA_Mode                  = DMA_Mode_Circular;
  110.     DMA_InitStructure.DMA_Priority              = DMA_Priority_High;
  111.     DMA_Init(ISP_USARTx_RX_DMA_CHANNEL, &DMA_InitStructure);

  112.     USART_DMACmd(ISP_USARTx, USART_DMAReq_Rx, ENABLE);  
  113.     DMA_Cmd(ISP_USARTx_RX_DMA_CHANNEL, ENABLE);
  114.      
  115.     USART_Cmd(ISP_USARTx, ENABLE);

  116.     return;
  117. }
复制代码
分别初始化两个串口并使能DMA RX功能,且DAMA的模式为DMA_Mode_Circular,内存地址不再是SRAM而是另一个串口的TDR地址。如此这般,就可以把串口1的数据直接从串口2处输出,用户在串口1中输入控制指令就可以操作与串口2相连的蓝牙模块了。
PS:该代码只是在调试阶段方便调试使用。
收藏 2 评论8 发布时间:2017-9-8 22:06

举报

8个回答
epochal 回答时间:2017-9-9 07:09:08
谢谢分享!
anny 回答时间:2017-9-9 10:15:50
多谢楼主,不错的分享
JiNian_04 回答时间:2018-3-22 18:26:56
楼主会出现一次发送多个字节丢数据的情况吗
andey 回答时间:2018-3-22 19:20:49
提示: 作者被禁止或删除 内容自动屏蔽
anobodykey 回答时间:2018-3-22 22:25:13
JiNian_04 发表于 2018-3-22 18:26
楼主会出现一次发送多个字节丢数据的情况吗

还没出现过
ldskendy 回答时间:2018-3-23 09:38:30
不错,谢谢分享,
之前我是在接收中断里,直接把数据给到另一个USART的TDR寄存器。
anobodykey 回答时间:2018-3-23 09:48:41
ldskendy 发表于 2018-3-23 09:38
不错,谢谢分享,
之前我是在接收中断里,直接把数据给到另一个USART的TDR寄存器。 ...

嗯,之前我也是在接收中断中发送数据到另一个USART的TDR寄存器中,后来就想省略中断用DMA,正好顺便测试下DMA的外设到外设的数据传输,这也是我想的一种DMA外设到外设的传输场景。
JiNian_04 回答时间:2018-3-23 09:59:45

我用的电脑虚拟的两对串口进行调试,连续发送一直丢数据,只能等实物出来再调试看看了,感谢楼主的分享与回复

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版