STM32Cubemx 配置
1.打开一个usb设备勾选为从设备
2.在这里选择CDC选项
代码
- 添加环形缓冲区
/** 环形缓冲区驱动文件
*
*
*
*
*
*/
#include "driver_buffer.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* 初始化环形缓冲区 */
RingBuffer USERRxDataBuffer1;
RingBuffer USERRxDataBuffer2;
RingBuffer USERRxDataBuffer3;
int Driver_Buffer_Init(ptRingBuffer buffer,uint16_t size)
{
if(buffer == NULL||size == 0 ) return -1; /* 判断合法性 */
if(buffer->fifo == NULL) /* 判断是否为内存大小空*/
{
buffer->fifo =(uint8_t*)malloc(size); /* 动态分配内存 */
if(buffer->fifo == NULL)
{
printf("Malloc %d bytes failed.\r\n", size);
return -1;
}
}
buffer->pw = buffer->pr = 0;
buffer->buf_size = size;
return 0;
}
/* 环形缓冲区写一个字节 */
int Driver_Buffer_Write(ptRingBuffer buffer,const uint8_t data)
{
if(buffer == NULL || buffer->fifo == NULL ) return -1; /* 判断合法性 */
int i = (buffer->pw + 1)%buffer->buf_size;
if(i != buffer->pr) /* 判断是否写满 */
{
buffer->fifo[buffer->pw] = data; /* */
buffer->pw = i; /* 重置写指针 */
return 0;
}
return -1;
}
/* 环形缓冲区写多个字节 */
int Driver_Buffer_WriteBytes(ptRingBuffer buffer,const uint8_t *data_stream,uint8_t len)
{
int i;
if(buffer == NULL || buffer->fifo == NULL ) return -1; /* 判断合法性 */
if(data_stream == NULL||len == 0 ) return -1;
for(i = 0;i<len ;i++ )
{
if(Driver_Buffer_Write(buffer, data_stream[i]) != 0) break;
}
return i;
}
/* 环形缓冲区 读一个字节 */
int Driver_Buffer_Read(ptRingBuffer buffer,uint8_t *data)
{
if(buffer == NULL || buffer->fifo == NULL ) return -1; /* 判断合法性 */
if(data == NULL) return -1;
if(buffer->pr == buffer->pw ) return -1; /* 满 */
*data = buffer ->fifo[buffer->pr];
buffer ->pr =(buffer ->pr+1)%buffer ->buf_size ; /* 自增 */
return 0;
}
/* 环形缓冲区 读多个字节 */
int Driver_Buffer_ReadBytes(ptRingBuffer buffer,uint8_t *data_stream,uint8_t len)
{
int i = 0;
if(buffer == NULL || buffer->fifo == NULL ) return -1; /* 判断合法性 */
if(data_stream == NULL || len == 0) return -1;
for(i = 0; i<len; i++)
{
if(Driver_Buffer_Read(buffer, &data_stream[i]) != 0) break;
}
return i;
}
/* 清空环形缓冲区 */
int Driver_Buffer_Clean(ptRingBuffer buffer)
{
if(buffer == NULL || buffer->fifo == NULL ) return -1; /* 判断合法性 */
memset(buffer->fifo,0,buffer->buf_size); /* 清空 */
buffer->pr = buffer->pw = 0; /* 归零 */
return 0;
}
/**
* @brief 更新数据到数组
* @param buffer
* @param data_stream
* @return 返回更新的数据长度
*/
int Driver_Buffer_RefreshData(ptRingBuffer buffer,uint8_t *data_stream)
{
uint16_t len=0;
if(buffer->pw == buffer->buf_size)
buffer->pw = 0;
while(buffer->pw != buffer->pr)
{
data_stream[len++] = buffer ->fifo[buffer->pr];
buffer ->fifo[buffer->pr] = 0;
buffer->pr++;
if(buffer->pr >= buffer->buf_size)
buffer->pr = 0;
if(len >= buffer->buf_size)
break;
}
return len;
}
#ifndef __DRIVER_BUFFER_H
#define __DRIVER_BUFFER_H
#include "main.h"
typedef struct{
uint8_t *fifo;
uint16_t pw; /*写地址*/
uint16_t pr;
uint16_t buf_size;
}RingBuffer,*ptRingBuffer;
extern RingBuffer USERRxDataBuffer1;
extern RingBuffer USERRxDataBuffer2;
extern RingBuffer USERRxDataBuffer3;
/* 初始化环形缓冲区 */
int Driver_Buffer_Init(ptRingBuffer buffer,uint16_t size);
/* 环形缓冲区写一个字节 */
int Driver_Buffer_Write(ptRingBuffer buffer,const uint8_t data);
/* 环形缓冲区写多个字节 */
int Driver_Buffer_WriteBytes(ptRingBuffer buffer,const uint8_t *data_stream,uint8_t len);
/* 环形缓冲区 读一个字节 */
int Driver_Buffer_Read(ptRingBuffer buffer,uint8_t *data);
/* 环形h缓冲区 读多个字节 */
int Driver_Buffer_ReadBytes(ptRingBuffer buffer,uint8_t *data_stream,uint8_t len);
/* 清空环形缓冲区 */
int Driver_Buffer_Clean(ptRingBuffer buffer);
int Driver_Buffer_RefreshData(ptRingBuffer buffer,uint8_t *data_stream);
#endif
在usbd_cdc_if.c文件中个更新环形缓冲区的写入
在main.c 中初始化环形缓冲区
然后添加以下的代码
if(USERRxDataBuffer1.pr!=USERRxDataBuffer1.pw)
{
CDC_Tx_Lenth = abs(USERRxDataBuffer1.pw-USERRxDataBuffer1.pr);
Driver_Buffer_ReadBytes(&USERRxDataBuffer1,USB_CDC_RxData,CDC_Tx_Lenth);
CDC_Transmit_HS(USB_CDC_RxData,CDC_Tx_Lenth);
memset(USB_CDC_RxData,0,sizeof(USB_CDC_RxData));
}
则实现了USB做虚拟串口的回调功能