1 虚拟串口移植
- 项目新建 USB 文件夹,将USB 驱动拷贝过来
- 从官方案例的 src,inc拷贝以下文件
2 添加分组和头文件
3 修改 platform_config.h
4 修改 hw_config.c
先编译
- 注释掉 #include "stm32_it.h"
- 添加如下的头文件
#include "u***_lib.h"
#include "u***_prop.h"
#include "u***_desc.h"
#include "u***_istr.h"
#include "hw_config.h"
#include "u***_pwr.h"
#include "usart.h"
#include "string.h"
#include "stdarg.h"
#include "stdio.h"
- 去掉
- 添加
_u***_usart_fifo uu_txfifo; // u***串口发送FIFO结构体,在 hw_config.h 定义
u8 USART_PRINTF_Buffer[USB_USART_REC_LEN]; // u*** printf 发送缓冲区
u8 USB_USART_RX_BUF[USB_USART_REC_LEN]; // 接收缓冲区
//接收状态
// bit15--接收完成标志
// bit14--接收到 0x0d
// bit13~0--接收到的有效字节的数目
u16 USB_USART_RX_STA = 0;
extern LINE_CODING linecoding; // u***虚拟串口配置信息(波特率、位数等),u***_prop.c 定义
#define USB_USART_TXFIFO_SIZE 1024 // USB虚拟串口发送FIFO大小
#define USB_USART_REC_LEN 200 // 接收缓冲区的最大字节
//定义一个USB USART FIFO 结构体
typedef struct
{
u8 buffer[USB_USART_TXFIFO_SIZE];
vu16 writeptr; // 写指针
vu16 readptr; // 读指针
}_u***_usart_fifo;
extern _u***_usart_fifo uu_txfifo;
- 删除 void Set_System(void) 函数
- 添加函数
void USBWakeUp_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line18); // 清除 USB 唤醒中断挂起位
}
// USB 中断处理
void USB_LP_CAN1_RX0_IRQHandler(void)
{
USB_Istr();
}
- 修改 void Enter_LowPowerMode(void) 函数
void Set_USBClock(void)
{
/* Select USBCLK source */
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5); // USB-48MHz
/* Enable the USB clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
}
- 修改 void Leave_LowPowerMode(void) 函数
void Leave_LowPowerMode(void)
{
DEVICE_INFO *pInfo = &Device_Info;
printf("leave low power modern");
/* Set the device state to the correct state */
if (pInfo->Current_Configuration != 0)
{
/* Device configured */
bDeviceState = CONFIGURED;
}
else
{
bDeviceState = ATTACHED;
}
/*Enable SystemCoreClock*/
//SystemInit();
}
- 修改 void USB_Interrupts_Config(void) 函数
void USB_Interrupts_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_ClearITPendingBit(EXTI_Line18);// 开启线 18 中断
EXTI_InitStructure.EXTI_Line = EXTI_Line18;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//enable u*** interrupt
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; //组2,优先级次之
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// enable u*** wake-up interrupt
NVIC_InitStructure.NVIC_IRQChannel = USBWakeUp_IRQn; // 组2,优先级最高
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_Init(&NVIC_InitStructure);
}
- 修改 void USB_Cable_Config (FunctionalState NewState) 函数
// NewState: DISABLE,不上拉; ENABLE,上拉;
void USB_Cable_Config (FunctionalState NewState)
{
if(NewState != DISABLE)
printf("u*** pull up enablern");
else
printf("u*** pull up disablern");
}
- 删除 void USART_Config_Default(void) 函数
- 添加 USB_Port_Set(u8 enable) 函数
void USB_Port_Set(u8 enable)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
if(enable)
{
_SetCNTR(_GetCNTR() & (~(1<<1))); // 退出断电模式
}else{
_SetCNTR(_GetCNTR() | (1<<1)); // 断电模式
GPIOA -> CRH &= 0xFFF00FFF;
GPIOA -> CRH |= 0x00033000;
PAout(12) = 0;
}
}
- 修改 bool USART_Config(void) 函数
// USB COM 口的配置信息打印
bool USART_Config(void)
{
uu_txfifo.readptr = 0; // 清空读指针
uu_txfifo.writeptr = 0;
USB_USART_RX_STA = 0;
printf("linecoding.format: %drn",linecoding.format);
printf("linecoding.paritytype: %drn",linecoding.paritytype);
printf("linecoding.datatype: %drn",linecoding.datatype);
printf("linecoding.bitrate: %drn",linecoding.bitrate);
return (TRUE);
}
- 修改 void USB_To_USART_Send_Data(uint8_t* data_buffer, uint8_t Nb_bytes) 函数
// 处理从 USB 虚拟串口接收到的数据
void USB_To_USART_Send_Data(uint8_t* data_buffer, uint8_t Nb_bytes)
{
u8 i;
u8 res;
for(i = 0;i < Nb_bytes; i++)
{
res = data_buffer
;
if((USB_USART_RX_STA & 0x8000) == 0) // 接收未完成
{
if(USB_USART_RX_STA & 0x4000) // 接收到了 0x0d
{
if(res != 0x0a) USB_USART_RX_STA = 0; // 错误,重新开始
else USB_USART_RX_STA |= 0x8000; // 接收完成
}else{ // 还没收到 0x0d
if(res == 0x0d) USB_USART_RX_STA |= 0x4000; // 标记接收到了 0x0d
else{
USB_USART_RX_BUF[USB_USART_RX_STA & 0x3FFF] = res;
USB_USART_RX_STA++;
if(USB_USART_RX_STA > (USB_USART_REC_LEN-1))
USB_USART_RX_STA = 0;// 错误,重传
}
}
}
}
}
- 删除 Handle_USBAsynchXfer 和 USART_To_USB_Send_Data 这两个函数;
- 新增 USB_USART_SendData 函数,用于虚拟串口发送一个字节数据到 USB(实际上只是写到了发送 FIFO,最终还是由 EP1_IN_Callback 函数实现输出给 USB)
void USB_USART_SendData(u8 data)
{
uu_txfifo.buffer[uu_txfifo.writeptr] = data;
uu_txfifo.writeptr++;
if(uu_txfifo.writeptr == USB_USART_TXFIFO_SIZE)
{
uu_txfifo.writeptr = 0;
}
}
- 删除 IntToUnicode 函数前面的 static, 在 hw_config.h 中声明这个函数
- 新增 u***_printf 函数,实现 USB 虚拟串口的 printf
// USB 虚拟串口 printf 函数
// 确保一次发送数据不超过 USB_USART_REC_LEN 字节
void u***_printf(char *fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*) USART_PRINTF_Buffer,fmt,ap);
va_end(ap);
i = strlen((const char*) USART_PRINTF_Buffer); // 此次发送数据长度
for(j=0;j
{
USB_USART_SendData(USART_PRINTF_Buffer[j]);
}
}
1 虚拟串口移植
- 项目新建 USB 文件夹,将USB 驱动拷贝过来
- 从官方案例的 src,inc拷贝以下文件
2 添加分组和头文件
3 修改 platform_config.h
4 修改 hw_config.c
先编译
- 注释掉 #include "stm32_it.h"
- 添加如下的头文件
#include "u***_lib.h"
#include "u***_prop.h"
#include "u***_desc.h"
#include "u***_istr.h"
#include "hw_config.h"
#include "u***_pwr.h"
#include "usart.h"
#include "string.h"
#include "stdarg.h"
#include "stdio.h"
- 去掉
- 添加
_u***_usart_fifo uu_txfifo; // u***串口发送FIFO结构体,在 hw_config.h 定义
u8 USART_PRINTF_Buffer[USB_USART_REC_LEN]; // u*** printf 发送缓冲区
u8 USB_USART_RX_BUF[USB_USART_REC_LEN]; // 接收缓冲区
//接收状态
// bit15--接收完成标志
// bit14--接收到 0x0d
// bit13~0--接收到的有效字节的数目
u16 USB_USART_RX_STA = 0;
extern LINE_CODING linecoding; // u***虚拟串口配置信息(波特率、位数等),u***_prop.c 定义
#define USB_USART_TXFIFO_SIZE 1024 // USB虚拟串口发送FIFO大小
#define USB_USART_REC_LEN 200 // 接收缓冲区的最大字节
//定义一个USB USART FIFO 结构体
typedef struct
{
u8 buffer[USB_USART_TXFIFO_SIZE];
vu16 writeptr; // 写指针
vu16 readptr; // 读指针
}_u***_usart_fifo;
extern _u***_usart_fifo uu_txfifo;
- 删除 void Set_System(void) 函数
- 添加函数
void USBWakeUp_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line18); // 清除 USB 唤醒中断挂起位
}
// USB 中断处理
void USB_LP_CAN1_RX0_IRQHandler(void)
{
USB_Istr();
}
- 修改 void Enter_LowPowerMode(void) 函数
void Set_USBClock(void)
{
/* Select USBCLK source */
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5); // USB-48MHz
/* Enable the USB clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
}
- 修改 void Leave_LowPowerMode(void) 函数
void Leave_LowPowerMode(void)
{
DEVICE_INFO *pInfo = &Device_Info;
printf("leave low power modern");
/* Set the device state to the correct state */
if (pInfo->Current_Configuration != 0)
{
/* Device configured */
bDeviceState = CONFIGURED;
}
else
{
bDeviceState = ATTACHED;
}
/*Enable SystemCoreClock*/
//SystemInit();
}
- 修改 void USB_Interrupts_Config(void) 函数
void USB_Interrupts_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_ClearITPendingBit(EXTI_Line18);// 开启线 18 中断
EXTI_InitStructure.EXTI_Line = EXTI_Line18;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//enable u*** interrupt
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; //组2,优先级次之
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// enable u*** wake-up interrupt
NVIC_InitStructure.NVIC_IRQChannel = USBWakeUp_IRQn; // 组2,优先级最高
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_Init(&NVIC_InitStructure);
}
- 修改 void USB_Cable_Config (FunctionalState NewState) 函数
// NewState: DISABLE,不上拉; ENABLE,上拉;
void USB_Cable_Config (FunctionalState NewState)
{
if(NewState != DISABLE)
printf("u*** pull up enablern");
else
printf("u*** pull up disablern");
}
- 删除 void USART_Config_Default(void) 函数
- 添加 USB_Port_Set(u8 enable) 函数
void USB_Port_Set(u8 enable)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
if(enable)
{
_SetCNTR(_GetCNTR() & (~(1<<1))); // 退出断电模式
}else{
_SetCNTR(_GetCNTR() | (1<<1)); // 断电模式
GPIOA -> CRH &= 0xFFF00FFF;
GPIOA -> CRH |= 0x00033000;
PAout(12) = 0;
}
}
- 修改 bool USART_Config(void) 函数
// USB COM 口的配置信息打印
bool USART_Config(void)
{
uu_txfifo.readptr = 0; // 清空读指针
uu_txfifo.writeptr = 0;
USB_USART_RX_STA = 0;
printf("linecoding.format: %drn",linecoding.format);
printf("linecoding.paritytype: %drn",linecoding.paritytype);
printf("linecoding.datatype: %drn",linecoding.datatype);
printf("linecoding.bitrate: %drn",linecoding.bitrate);
return (TRUE);
}
- 修改 void USB_To_USART_Send_Data(uint8_t* data_buffer, uint8_t Nb_bytes) 函数
// 处理从 USB 虚拟串口接收到的数据
void USB_To_USART_Send_Data(uint8_t* data_buffer, uint8_t Nb_bytes)
{
u8 i;
u8 res;
for(i = 0;i < Nb_bytes; i++)
{
res = data_buffer
;
if((USB_USART_RX_STA & 0x8000) == 0) // 接收未完成
{
if(USB_USART_RX_STA & 0x4000) // 接收到了 0x0d
{
if(res != 0x0a) USB_USART_RX_STA = 0; // 错误,重新开始
else USB_USART_RX_STA |= 0x8000; // 接收完成
}else{ // 还没收到 0x0d
if(res == 0x0d) USB_USART_RX_STA |= 0x4000; // 标记接收到了 0x0d
else{
USB_USART_RX_BUF[USB_USART_RX_STA & 0x3FFF] = res;
USB_USART_RX_STA++;
if(USB_USART_RX_STA > (USB_USART_REC_LEN-1))
USB_USART_RX_STA = 0;// 错误,重传
}
}
}
}
}
- 删除 Handle_USBAsynchXfer 和 USART_To_USB_Send_Data 这两个函数;
- 新增 USB_USART_SendData 函数,用于虚拟串口发送一个字节数据到 USB(实际上只是写到了发送 FIFO,最终还是由 EP1_IN_Callback 函数实现输出给 USB)
void USB_USART_SendData(u8 data)
{
uu_txfifo.buffer[uu_txfifo.writeptr] = data;
uu_txfifo.writeptr++;
if(uu_txfifo.writeptr == USB_USART_TXFIFO_SIZE)
{
uu_txfifo.writeptr = 0;
}
}
- 删除 IntToUnicode 函数前面的 static, 在 hw_config.h 中声明这个函数
- 新增 u***_printf 函数,实现 USB 虚拟串口的 printf
// USB 虚拟串口 printf 函数
// 确保一次发送数据不超过 USB_USART_REC_LEN 字节
void u***_printf(char *fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*) USART_PRINTF_Buffer,fmt,ap);
va_end(ap);
i = strlen((const char*) USART_PRINTF_Buffer); // 此次发送数据长度
for(j=0;j
{
USB_USART_SendData(USART_PRINTF_Buffer[j]);
}
}
举报