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

STM32串口发送中断

[复制链接]
万里-363223 发布时间:2014-12-19 08:49
阅读主题, 点击返回1楼
收藏 1 评论17 发布时间:2014-12-19 08:49
17个回答
奔跑小蜗牛 回答时间:2014-12-20 08:18:54
.。。。。总结的好细致。。。。受教了。。不过,51终究是51,用起来简单,当然也就没那么强大了,stm32虽然复杂,那只是在配置和工作原理上,都熟悉了,性能绝对够不错,万事开头难,上手了就好了。
万里-363223 回答时间:2014-12-21 09:39:00
奔跑小蜗牛 发表于 2014-12-20 08:18
.。。。。总结的好细致。。。。受教了。。不过,51终究是51,用起来简单,当然也就没那么强大了,stm32虽然 ...

恩恩,没错,还是STM32爽
王建 回答时间:2014-12-21 10:51:09

STM32的串口通信,最好使用DMA方式发送。

本帖最后由 王建 于 2014-12-21 10:57 编辑

至于接收,根据实际情况而定。
王建 回答时间:2014-12-21 10:53:00
/**
  * @file    usb_endp.c
  * @author  wjandcf@gmail.com
  * @version V7.0.2
  * @date    2014.12.20
  * @brief   Endpoint routines
  *  
  */
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_desc.h"
#include "usb_mem.h"
#include "hw_config.h"
#include "usb_istr.h"
#include "usb_pwr.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Interval between sending IN packets in frame number (1 frame = 1ms) */
#define VCOMPORT_IN_FRAME_INTERVAL             5

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t USB_Rx_Buffer[VIRTUAL_COM_PORT_DATA_SIZE];

extern uint8_t VCP1_Tx_Buffer1[];      /* VCP1 DMA发送缓冲1 */
extern uint8_t VCP2_Tx_Buffer1[];      /* VCP2 DMA发送缓冲1 */
extern uint8_t VCP3_Tx_Buffer1[];      /* VCP3 DMA发送缓冲1 */

extern uint8_t VCP1_Tx_Buffer2[];      /* VCP1 第二缓冲(临时存放来自PC主机的数据包) */
extern uint8_t VCP2_Tx_Buffer2[];      /* VCP2 第二缓冲 */
extern uint8_t VCP3_Tx_Buffer2[];      /* VCP3 第二缓冲 */

extern uint8_t  Flag_VCP1_Tx_Buf_Use;  /* 1: 表示DMA发送已启动,VCP1_Tx_Buffer1被锁定 */
extern uint8_t  Flag_VCP1_Tx_Buf_Full; /* 1: 表示VCP1_Tx_Buffer2数据可能已放满,暂时不能再从主机接收数据 */
extern uint16_t VCP1_Tx_Buffer_Cnt;    /* VCP1 第二缓冲 收到的字符总数 */

extern uint8_t  Flag_VCP2_Tx_Buf_Use;  /* 1: 表示DMA发送已启动,VCP2_Tx_Buffer1被锁定 */
extern uint8_t  Flag_VCP2_Tx_Buf_Full; /* 1: 表示VCP2_Tx_Buffer2数据可能已放满,暂时不能再从主机接收数据 */
extern uint16_t VCP2_Tx_Buffer_Cnt;    /* VCP2 第二缓冲 收到的字符总数 */

extern uint8_t  Flag_VCP3_Tx_Buf_Use;  /* 1: 表示DMA发送已启动,VCP3_Tx_Buffer1被锁定 */
extern uint8_t  Flag_VCP3_Tx_Buf_Full; /* 1: 表示VCP3_Tx_Buffer2数据可能已放满,暂时不能再从主机接收数据 */
extern uint16_t VCP3_Tx_Buffer_Cnt;    /* VCP3 第二缓冲 收到的字符总数 */

extern uint8_t  VCP1_Rx_Buffer[];
extern uint32_t VCP1_Rx_ptr_in;
extern uint32_t VCP1_Rx_ptr_out;
extern uint32_t VCP1_Rx_length;
extern uint8_t  CDC1_Tx_State;

extern uint8_t  VCP2_Rx_Buffer[];
extern uint32_t VCP2_Rx_ptr_in;
extern uint32_t VCP2_Rx_ptr_out;
extern uint32_t VCP2_Rx_length;
extern uint8_t  CDC2_Tx_State;

extern uint8_t  VCP3_Rx_Buffer[];
extern uint32_t VCP3_Rx_ptr_in;
extern uint32_t VCP3_Rx_ptr_out;
extern uint32_t VCP3_Rx_length;
extern uint8_t  CDC3_Tx_State;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/* USB的IN端点 发送数据到PC主机 */
#define EPx_IN_Callback(ENDPx, CDCx_Tx_State, VCPx_Rx_Buffer, VCPx_Rx_ptr_out, VCPx_Rx_length) {\
    uint16_t USB_Tx_ptr;\
    uint16_t USB_Tx_length;\
    if (CDCx_Tx_State == 1) {\
        USB_Tx_ptr = VCPx_Rx_ptr_out;\
        if (VCPx_Rx_length == 0) {\
            CDCx_Tx_State = 0;\
            SetEPTxCount(ENDPx,0);\
            SetEPTxValid(ENDPx);\
        } else {\
            if (VCPx_Rx_length > VIRTUAL_COM_PORT_DATA_SIZE) {\
                USB_Tx_length = VIRTUAL_COM_PORT_DATA_SIZE;\
                VCPx_Rx_ptr_out += VIRTUAL_COM_PORT_DATA_SIZE;\
                VCPx_Rx_length -= VIRTUAL_COM_PORT_DATA_SIZE;\
            } else {\
                USB_Tx_length = VCPx_Rx_length;\
                VCPx_Rx_ptr_out += VCPx_Rx_length;\
                VCPx_Rx_length = 0;\
            }\
            USB_SIL_Write(ENDPx, &VCPx_Rx_Buffer[USB_Tx_ptr], USB_Tx_length);\
            SetEPTxValid(ENDPx);\
        }\
    }\
}
/* USB的OUT端点 通过物理串口向外发送数据(阻塞方式) */
#define EPx_OUT_Callback(ENDPx, USARTx, GPIOx, GPIO_Pin_x) {\
    uint32_t i;\
    uint16_t USB_Rx_Cnt;\
    USB_Rx_Cnt = USB_SIL_Read(ENDPx | 0x00, USB_Rx_Buffer); \
    GPIOx->BSRR = GPIO_Pin_x;\
    for (i = 0; i < USB_Rx_Cnt; i++) {\
        USARTx->DR = *(USB_Rx_Buffer + i);\
        while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);\
    }\
    SetEPRxValid(ENDPx);\
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);\
    USART_ClearFlag(USARTx, USART_FLAG_TC);\
    GPIOx->BRR = GPIO_Pin_x;\
}

/* USB的OUT端点 通过物理串口向外发送数据(DMA方式) */
#define EPx_OUT_Callback_DMA(Flag_VCPx_Tx_Buf_Use, ENDPx, VCPx_Tx_Buffer1,VCPx_Tx_Buffer2,\
    GPIOx, GPIO_Pin_x, DMA1_Channelx, VCPx_Tx_Buffer_Cnt, Flag_VCPx_Tx_Buf_Full) {\
    uint16_t USB_Rx_Cnt;\
    if(Flag_VCPx_Tx_Buf_Use == 0){\
        USB_Rx_Cnt = GetEPRxCount(ENDPx & 0x7F);\
        PMAToUserBufferCopy(&VCPx_Tx_Buffer1[0], GetEPRxAddr(ENDPx & 0x7F), USB_Rx_Cnt);\
        SetEPRxValid(ENDPx);\
        GPIOx->BSRR = GPIO_Pin_x;\
        DMA1_Channelx->CNDTR = USB_Rx_Cnt;\
        DMA_Cmd(DMA1_Channelx, ENABLE);\
        Flag_VCPx_Tx_Buf_Use = 1;\
        VCPx_Tx_Buffer_Cnt = 0;\
    } else {\
        USB_Rx_Cnt = GetEPRxCount(ENDPx & 0x7F);\
        if(VCPx_Tx_Buffer_Cnt < (1024-128)){\
          PMAToUserBufferCopy(&VCPx_Tx_Buffer2[VCPx_Tx_Buffer_Cnt], GetEPRxAddr(ENDPx & 0x7F), USB_Rx_Cnt);\
          VCPx_Tx_Buffer_Cnt += USB_Rx_Cnt;\
          SetEPRxValid(ENDPx);\
        } else {\
          PMAToUserBufferCopy(&VCPx_Tx_Buffer2[VCPx_Tx_Buffer_Cnt], GetEPRxAddr(ENDPx & 0x7F), USB_Rx_Cnt);\
          VCPx_Tx_Buffer_Cnt += USB_Rx_Cnt;\
          Flag_VCPx_Tx_Buf_Full = 1;\
        }\
    }\
}
/**
* Function Name  : EP2_IN_Callback
* Description    :
**/
void EP2_IN_Callback (void) {
    EPx_IN_Callback(ENDP2,CDC1_Tx_State,VCP1_Rx_Buffer,VCP1_Rx_ptr_out,VCP1_Rx_length);
}
/**
* Function Name  : EP4_IN_Callback
* Description    :
**/
void EP4_IN_Callback(void)
{
    EPx_IN_Callback(ENDP4,CDC2_Tx_State,VCP2_Rx_Buffer,VCP2_Rx_ptr_out,VCP2_Rx_length);
}
/**
* Function Name  : EP6_IN_Callback
* Description    : VCP3 向PC主机发送数据
**/
void EP6_IN_Callback(void)
{
    EPx_IN_Callback(ENDP6,CDC3_Tx_State,VCP3_Rx_Buffer,VCP3_Rx_ptr_out,VCP3_Rx_length);  
}
/**
* Function Name  : EP2_OUT_Callback
* Description    : VCP1 通过USART1向外送数据
**/
void EP2_OUT_Callback(void) {
#ifdef USB_DMA_SEND
    EPx_OUT_Callback_DMA(Flag_VCP1_Tx_Buf_Use, ENDP2, VCP1_Tx_Buffer1,VCP1_Tx_Buffer2,\
            GPIOB, GPIO_Pin_9, DMA1_Channel4, VCP1_Tx_Buffer_Cnt, Flag_VCP1_Tx_Buf_Full);
#else
    EPx_OUT_Callback(ENDP2,USART1, GPIOB, GPIO_Pin_9); // DR1 PB9
#endif
}
/**
* Function Name  : EP4_OUT_Callback
* Description    : VCP2 通过USART2向外送数据
* Input          : None.
* Output         : None.
* Return         : None.
**/
void EP4_OUT_Callback(void)
{
#ifdef USB_DMA_SEND
    EPx_OUT_Callback_DMA(Flag_VCP2_Tx_Buf_Use, ENDP4, VCP2_Tx_Buffer1,VCP2_Tx_Buffer2,\
            GPIOB, GPIO_Pin_8, DMA1_Channel7, VCP2_Tx_Buffer_Cnt, Flag_VCP2_Tx_Buf_Full);
#else
    EPx_OUT_Callback(ENDP4,USART2, GPIOB, GPIO_Pin_8); // DR2 PB8
#endif
}
/**
* Function Name  : EP6_OUT_Callback
* Description    : VCP3 通过USART3向外送数据
**/
void EP6_OUT_Callback(void){
#ifdef USB_DMA_SEND
    EPx_OUT_Callback_DMA(Flag_VCP3_Tx_Buf_Use, ENDP6, VCP3_Tx_Buffer1,VCP3_Tx_Buffer2,\
            GPIOA, GPIO_Pin_5, DMA1_Channel2, VCP3_Tx_Buffer_Cnt, Flag_VCP3_Tx_Buf_Full);
#else  
    EPx_OUT_Callback(ENDP6,USART3,GPIOA,GPIO_Pin_5);  // DR3 PA5
#endif
}
/**
* Function Name  : SOF_Callback / INTR_SOFINTR_Callback
* Description    :
**/
void SOF_Callback(void)
{
    static uint32_t FrameCount = 0;
    static uint32_t Led_Count = 0;
    if(bDeviceState == CONFIGURED) {
        if (FrameCount++ >= VCOMPORT_IN_FRAME_INTERVAL) {
            /* Reset the frame counter */
            FrameCount = 0;
            /* Check the data to be sent through IN pipe */
            Handle_USBAsynchXfer();
        }
    }
    if(++Led_Count > 999) {
        Led_Count = 0;
        if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2) == 0){
            GPIOB->BSRR = GPIO_Pin_2; // PB2 H
        } else {
            GPIOB->BRR = GPIO_Pin_2;  // PB2 L
        }
    }
}

王建 回答时间:2014-12-21 10:59:47
补充下,上一段是USB转多路串口(USB-Multiple-CDC)例程中的部分代码,仅支持STM32F103xx系列。
小贾-370388 回答时间:2014-12-22 10:56:21
谢谢楼主分享,对楼主的精神表示支持
万里-363223 回答时间:2014-12-22 12:41:37
小贾-370388 发表于 2014-12-22 10:56
谢谢楼主分享,对楼主的精神表示支持

为论坛贡献自己的一份力
沐紫 回答时间:2014-12-22 13:33:44
表示感谢!
12

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

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