终于利用stm32cube生成了usb虚拟串口程序并初步调试通过,分享代码和配置先!!

今天终于调通了,虽然只是PC电脑上接收到了数据.......(发送的还没研究)
先弄上来让大家知道怎么配置和大体程序的流程(我也没多研究).....
至于配置,我先前一个帖子已经贴图了....
这里再写一次
Pinout界面中修改:
开启USB_OTG_FS模式下的Device_Only,其他不选
middleWare里面的USB_DEVICE中的Class For FS IP选择Communication Device Class (Virtual Port Com)
时钟配置界面:8M外部晶振,设置系统168M,Apb1分频4,APB2分频2
Configuration界面中:
GPIO设置PD12,13,14,15输出上拉,中速
无标题.png

usb的GPIO的DM和DP均为AF,DM无上啦,DP上拉,高速模式(High)

开启中断优先组GRoup4
NVIC中断开启usb on the Go FS Global interrupt 中断1,0
USB_FS configuration 设置 speed为Full , ENDpoint 0 max packet size为64bytes
低功耗不使能, vbus不使能.....
usb_device configuration中的Parameter setting设置
!(http://www.stm32cube.com/uploads/answer/20141215/d212a1f69a5b8da9bdbb8caaf0cad780.png) 

!(http://www.stm32cube.com/uploa ... a4.png)

ok,生成代码
已邀请:

admin

赞同来自:

GPIO方面的配置图

无标题.png

admin

赞同来自:

生成之后,我用的事keil 编译的, 要去修改启动文件里面一个代码
打开工程的启动文件 startup_stm32f407xx.s
将里面的 Heap_Size EQU 0x00000200
改成 Heap_Size EQU 0x00001000
或者改成Heap_Size EQU 0x00001500
其中1500是官方那个演示程序的设置.

再次打开main.c文件
添加头文件
#include "usbd_cdc.h"
算了直接上main.c里面的全部代码,其他的文件都不用修改

/[i] Includes ------------------------------------------------------------------[/i]/
#include "stm32f4xx_hal.h"
#include "usb_device.h"
#include "gpio.h"

/[i] USER CODE BEGIN Includes [/i]/
#include "usbd_cdc.h"
/[i] USER CODE END Includes [/i]/

/[i] Private variables ---------------------------------------------------------[/i]/

/[i] USER CODE BEGIN PV [/i]/

/[i] USER CODE END PV [/i]/

/[i] Private function prototypes -----------------------------------------------[/i]/
void SystemClock_Config(void);

/[i] USER CODE BEGIN PFP [/i]/

/[i] USER CODE END PFP [/i]/

/[i] USER CODE BEGIN 0 [/i]/
uint16_t mmss;

/[i] USER CODE END 0 [/i]/

int main(void)
{

/[i] USER CODE BEGIN 1 [/i]/
uint8_t UserTxBuffer55 = 0x55;
/[i] USER CODE END 1 [/i]/

/[i] MCU Configuration----------------------------------------------------------[/i]/

/[i] Reset of all peripherals, Initializes the Flash interface and the Systick. [/i]/
HAL_Init();

/[i] Configure the system clock [/i]/
SystemClock_Config();

/[i] Initialize all configured peripherals [/i]/
MX_GPIO_Init();
MX_USB_DEVICE_Init();

/[i] USER CODE BEGIN 2 [/i]/

/[i] USER CODE END 2 [/i]/

/[i] USER CODE BEGIN 3 [/i]/
/[i] Infinite loop [/i]/
while (1)
{
if(mmss>=500)
{
HAL_GPIO_TogglePin (GPIOD,GPIO_PIN_12);

USBD_CDC_SetTxBuffer(&hUsbDeviceFS, (uint8_t*)&UserTxBuffer55, 1);

USBD_CDC_TransmitPacket(&hUsbDeviceFS);

mmss = 0;

}

}
/[i] USER CODE END 3 [/i]/

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

__PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

}

/[i] USER CODE BEGIN 4 [/i]/
void HAL_SYSTICK_Callback(void)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_SYSTICK_Callback could be implemented in the user file
*/
mmss++;
}
/[i] USER CODE END 4 [/i]/

#ifdef USE_FULL_ASSERT

/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/[i] USER CODE BEGIN 6 [/i]/
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/[i] USER CODE END 6 [/i]/

}

#endif

好了,编译烧录,打开串口调试助手
额,先上图

2.png


3.png


**注意啊,串口调试助手里面,只需要选择相应的串口就可以了......其他的什么波特率啊,位数啊,都没用的..........
咱是usb虚拟的,没定义这个....不信你可以自己试试**

admin

赞同来自: 十包泡面

晚上回去测试接收然后原数据返回.....................
占楼广告.....................

popdes

赞同来自:

期待楼猪速更...................

admin

赞同来自: 小七 houerdan

发现生成的代码里面有几个问题:
第一个,
usbd_cdc_if.c文件里面的最后一个函数

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/[i] USER CODE BEGIN 8 [/i]/
USBD_CDC_SetTxBuffer(hUsbDevice_0, [b]Buf[/b], Len);
result = USBD_CDC_TransmitPacket(hUsbDevice_0);
/[i] USER CODE END 8 [/i]/
return result;
}

应该改成上面的,这个应该是整合了下发送函数,毕竟每次发送都要用到.但是他原来里面粗体部分用的是UserTxBufferFS[],这就说不通了......导致变量Puf木有屁用了...
然后以后的main.c中的main就可以直接调用这个函数了,
额,调用前,先声明下
extern uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
ok,继续
测试的话,随便定义一个uint8_t datausb = {0x77,0x88,0x99,0x11,0x22,0x33,0x55};
发送用 CDC_Transmit_FS((uint8_t *)&datausb ,7);

admin

赞同来自:

下面测试接收数据.要添加个东西...
打开usbd_cdc_if.c文件里面的倒数第二个函数
改为

static int8_t CDC_Receive_FS (uint8_t[i] Buf, uint32_t [/i]Len)
{
/[i] USER CODE BEGIN 7 [/i]/

USBD_CDC_SetRxBuffer(&hUsbDeviceFS, (uint8_t *)&UserRxBufferFS);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/[i] USER CODE END 7 [/i]/
}

不改的话,接收一次数据可以,第二次串口调试助手就会死机..............
我main函数中这样写

while (1)
{
if(addtime >=500)
{
addtime = 0;
HAL_GPIO_TogglePin (GPIOD,GPIO_PIN_12);
// UsbSendData (&datausb ,1);
CDC_Transmit_FS(UserRxBufferFS ,7);
}
}

每次500ms发送一次接收到的数据回去....
我每次发送接收到的头7个数据...

无标题.png

图中,我发送16进制数 55 44 两个字节......
返回的是16进制数 55 44 C1 2C 60 18 7C 七个字节.....
这是我随便发送后,再次发送55 44两个字节的结果...
数据没清零.......说明程序还是有问题.........
明天再改改

admin

赞同来自:

多次试验发现,有时候上电我设置的系统正常情况下必闪的led没闪烁,不知道什么原因,这样貌似是系统死在了哪里......导致usb也发送不到数据和接收....
还有就是如上面代码的写法,加入接收5个或者更少的数据,但是发送大于此数量那么接收还是正确的5数,但是紧接着就是两个错误的数据.....难道是CRC校验?但是我没开啊,而且也貌似也不是校验啊........
奇怪?
难道用虚拟串口必须用特征码筛选有用信息?
谁遇到过这种问题

王建

赞同来自:

驱动包里有例子,生成的还不能直接用

中子星

赞同来自:

这么说可以直接USB下载程序了?

wangxuemin

赞同来自:

可以把接收的代码贴上来吗?楼主

cubeuser_Terry - 想去看世界

赞同来自:

时钟配置一直不对啊

a.jpg

deltak

赞同来自:

怎么没有下文了?

泡泡龙

赞同来自:

最后的main()函数的最后一行CDC_Transmit_FS(UserRxBufferFS,7)是不是写错啦,函数是Transmit,参数却是RxBuffer,应该是CDC_Receive_FS(UserRxBufferFS,7)吧

ZJZTO - 各种打酱油

赞同来自:

不知道楼主有没有试过F10X、F30X系列的芯片测试。按照教程测试了429,PC可以发现虚拟串口,可是用了个302的开发板(stm32f302r8t6),USB的配置就缩水了,插上后一点反应都没。难道还得手动上拉DP? 部分配置如下图 缺少: NVIC中断开启usb on the Go FS Global interrupt 中断1.0 ;vbus 设置。

ZJZTO - 各种打酱油

赞同来自: admin oceansue

在DP脚添加了一个上拉电阻后终于可以枚举 stm32f302r8t6 VCP了。第一步 check。

SЁv⑦ēЙ

赞同来自:

我的开发板是STM3240G-EVAL,用CUBEMX设置了很多次,电脑上始终有个黄色感叹号,不能正常使用,用demo程序就没有问题

若、相惜

赞同来自:

开启中断优先组GRoup4是不是默认的?我的怎么改不了?还有NVIC中断开启usb on the Go FS Global interrupt 中断1,0什么意思?貌似只有是能usb on the Go FS Global interrupt 中断啊!

love无%殇#

赞同来自:

关注

love无%殇#

赞同来自:

大家好,我将f429例程的CDC代码移植到407中,电脑设备管理器中端口显示出端口号,但有个黄色感叹号,双击感叹号,显示“设备无法启动,代码10”,移植到407需要改哪些地方额,大家遇到过这个问题吗?谢谢

淋漓

赞同来自: xiaoguai Aousen

借楼提示下,楼主的方法少最后会出现黄色惊叹号,串口无法工作,根本原因是cube给的堆空间不够,按照上图中设置即可解决。

qwer13579246

赞同来自:

感谢楼上的回答,困扰已久的问题终于解决了,对着这个黄色感叹号都看了2天了

蒋符之

赞同来自:

是什么原因有黄色叹号?

瑜珞

赞同来自:

雪上飞

赞同来自:

接收数据时,你不知道电脑到底发的数据有多少个字节时,要怎么办!?在哪里知道需要接收的字节数?

tieguanyin2008

赞同来自:

谢谢分享!!!!!!!!!

拔葱儆蒜

赞同来自:

连续发要检测发送返回值,不然只能有第一个buff被发送,别问我怎么知道的,毕竟傻了一天图片.png

Tian博文

赞同来自:

我用的STM32F107,生成的代码就是按照楼主那样在主循环里面调用发送,以达到不停发数的目的,但是我的板子一点反应都没有,感觉根本没走到我的主循环里,有人和我一样的情况吗

备羽飞龙

赞同来自:

楼主是否试验过USB虚拟出多个串口节点的,我现在需要一个问题,虚拟出多个节点在板子启动的第一次,接收到PC的数据不正确,后边的每一包都正确了,不知道是何原因

qi1206568569

赞同来自:

楼主你好!你有没有尝试过给软件复位后,看USB——VCP通讯是否正常识别,USB_VCP 在软件复位后,USB_VCP通讯会出错,必须重新插拔才能通讯正常。

要回复问题请先登录注册