1.USB有很多功能:目前文章只讲虚拟串口的使用
——用到的管脚:PA12——USB_OTG_HS_DP,PA11——USB_OTG_HS_DM。
——芯片:STM32H723ZGT6型号。
————————————————
2.STM32Cubemax配置
——新建工程——选择对应芯片类型
——选择对应芯片——STM32H723ZGT6——
——选yes——
——配置管脚——PA12——USB_OTG_HS_DP 。PA11——USB_OTG_HS_DM。
——配置USB——
——配置时钟——设置完之后,点击上面那个刷新圈圈自动配置——
——配置USB时钟——选择设定USB时钟48MHZ——
——生成文件——
——最后生成代码——
3.编辑程序需要添加的程序
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
// USB_Status_Init();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_BDMA_Init();
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
adc_init();//————————————————————————————主函数+代码//
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Scan_ADC();//—————————————————————————+代码,处理ADC的数据,然后USB打印//
// USB_Transmit();//———————————————————+代码,需要哪个功能放开,调试看/
USB_Receive();//——————————————————————+代码,也可以一起看,两个串口工具//
}
/* USER CODE END 3 */
}
//————————————————————————————————————————————————————————————————————//
//——USB_RX.h文件——创建的独立的文件模块化,
//自己新建一个文件夹来存放USB的功能部分,把USB打印封装成函数,
#include "main.h"
#include <stdarg.h> //printf函数。
#include "usb_device.h"
#define USB_RX_LEN 50//接收数据长度
#define USB_TX_LEN 50//发送数据长度
uint8_t TX_data[USB_TX_LEN];//发送函数的数据缓冲区
char RX_data[USB_RX_LEN];//接收函数的数据缓冲区
uint16_t USB_RX_CBK_FLAG = 0;//接收完成标志
int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len);//提前声明
uint8_t CDC_Transmit_HS(uint8_t* Buf, uint16_t Len);//提前声明
const char Array[20]={"ADC2 PA5 V"};//封装字符串
//———————————————————————————————————————————————————————————————————//
//——USB_RX.c文件——创建的独立的文件模块化
#include "usb_rx.h"
void USB_Receive(void)
{
if(CDC_Receive_HS((uint8_t*)RX_data ,(uint32_t*)sizeof(RX_data))!=USBD_OK)
{
Error_Handler();
}
USB_RX_CBK_FLAG=1;//利用这个标志做数据处理,数据已经存在RX_data数组之中。
//或者直接写函数封装起来放这里。后续我会贴一个处理数据的,便于移植的代码。
}
void USB_printf(char*fmt,...)
{
va_list ap;
va_start(ap,fmt);
vsprintf((char*)TX_data,fmt,ap);
va_end(ap);
if(CDC_Transmit_HS((uint8_t*)TX_data ,sizeof(TX_data))!=USBD_OK)
{
Error_Handler();
}
}
void USB_Transmit(void)
{
int8_t i=9;
USB_printf("%s %d\r\n",Array,i);//类似printf功能使用
}
//——————————————————————————————————————————————————————————————————//
//这部分代码模拟电平,可以在主函数里头初始化部分写,
//我个人没有写这一部分代码,我手动调试。如果写在主函数我注释掉的地方。
void USB_Status_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_SET);
HAL_Delay (100);
}
——需要注意的地方——
——函数需要提前声明
——主要用到两个函数——USB发送和USB接收函数。
——最后编译一下,有些数据错误警告处理一下,主要流程就是这样,然后调试处理一下细节,
连接USB调试,就可以看到现象收到你所写的内容,
——我这里显示的是我自己编写的内容,至于你想显示什么,自己改变打印的字符串的格式。
——这个是接收数据的窗口,用上一个28DMA数据通过USB打印出来显示效果。
需要注意清理错误警告,一些变量使用在头文件声明,局部变量和全局变量注意,
——接收数据的数组一次接收的数组,再一次来数据的时候会覆盖掉之前数据,需要我们及时处理
RX_data数据,或者做第三个变量存起来处理。
以上仅仅属于本人学习心得,可供学习参考,禁止商用~