STM32F103C8 虚拟串口移植实验(2)

1 修改 hw_config.h

  • 删除
    在这里插入图片描述

  • 新增
extern u8 USB_USART_RX_BUF[USB_USART_REC_LEN];
extern u16 USB_USART_RX_STA;

在这里插入图片描述

2 修改 usb_endp.c

  • 修改 EP1_IN_Callback函数
void EP1_IN_Callback (void)
{
	u16 USB_Tx_ptr;
	u16 USB_Tx_length;
	if(uu_txfifo.readptr == uu_txfifo.writeptr) return;// 无任何数据发送,直接退出
	if(uu_txfifo.readptr < uu_txfifo.writeptr) //没有超过数组,读指针 < 写指针
	{
		USB_Tx_length = uu_txfifo.writeptr - uu_txfifo.readptr; // 要发送数据长度
	}else{
		// 读指针 > 写指针时,发送数据长度
		USB_Tx_length = USB_USART_TXFIFO_SIZE - uu_txfifo.readptr;
	}
	
	if(USB_Tx_length > VIRTUAL_COM_PORT_DATA_SIZE) // 超过 64 字节
	{
		USB_Tx_length = VIRTUAL_COM_PORT_DATA_SIZE; // 此次发送数据量
	}
	USB_Tx_ptr = uu_txfifo.readptr; // 发送起始地址
	uu_txfifo.readptr += USB_Tx_length; // 读指针偏移
	
	if(uu_txfifo.readptr >= USB_USART_TXFIFO_SIZE)
	{
		uu_txfifo.readptr = 0;
	}
	
	UserToPMABufferCopy(&uu_txfifo.buffer[USB_Tx_ptr],ENDP1_TXADDR,USB_Tx_length);
	SetEPTxCount(ENDP1,USB_Tx_length); // 设置发送数据长度
	SetEPTxValid(ENDP1); // 设置 端点1 发送有效
}

  • 修改 void SOF_Callback(void) 函数
void SOF_Callback(void)
{
  static uint32_t FrameCount = 0;
  
  if(bDeviceState == CONFIGURED)
  {
    if (FrameCount++ == VCOMPORT_IN_FRAME_INTERVAL)
    {
      /* Reset the frame counter */
		FrameCount = 0;
		EP1_IN_Callback(); // Tx数据发送给 USB
		
    }
  }  
}

3 修改 usb_prop.c

  • 由于没有用到 USART_Config_Default 函数,所以注释掉 Virtual_Com_Port_init 函数里对该函数的调用;

4 修改 usb_pwr.c

  • 修改 void Suspend(void) 函数
void Suspend(void)
{
	uint32_t i=0;
	uint16_t wCNTR;
	__IO uint32_t savePWR_CR = 0;
	wCNTR = _GetCNTR(); // 存储 CNTR 的值
	for(i=0;i<8;i++) EP[i] = _GetENDPOINT(i);
	wCNTR |= CNTR_RESETM; // unmask RESET flag
	_SetCNTR(wCNTR);
	wCNTR |= CNTR_FRES; // apply FRES
	_SetCNTR(wCNTR);
	wCNTR &= ~CNTR_FRES; // clear FRES
	_SetCNTR(wCNTR);
	while((_GetISTR() & ISTR_RESET) == 0) ; //poll for RESET flag in ISTR
	_SetISTR((uint16_t)CLR_RESET); // clear RESET flag in ISTR
	for(i=0;i<8;i++) _SetENDPOINT(i,EP[i]); // restore Endpoints
	wCNTR |= CNTR_FSUSP;
	_SetCNTR(wCNTR);
	wCNTR = _GetCNTR(); // force low-power mode inthe macrocell
	wCNTR |= CNTR_LPMODE;
	_SetCNTR(wCNTR);
	Enter_LowPowerMode();
}

6 main.c

#include "stm32f10x.h" 
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "led.h"

#include "usb_lib.h"
#include "hw_config.h"
#include "usb_pwr.h"

int main(void)
{
	u16 t;
	u16 len;
	u16 times = 0;
	u8 usbstatus = 0;
	
	delay_init();
	LED_Init();
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	// 虚拟化串口和真实的串口没有关系
	// 此处初始化串口是因为有的地方用到了 printf 函数
	// 屏蔽掉 printf,就不用初始化串口了
	uart_init(9600);

	USB_Port_Set(0); // USB 先断开
	delay_ms(500);
	USB_Port_Set(1);// USB 再次连接
	
	Set_USBClock();
	USB_Interrupts_Config();
	USB_Init();
	
	while(1)
	{
		if(usbstatus != bDeviceState) // USB 连接状态发生改变
		{
			usbstatus = bDeviceState; // 记录新的状态
			if(usbstatus == CONFIGURED)
			{
				LED0 = 1; // 灯亮
			}else{
				LED0 = 0;
			}
		}
		
		if(USB_USART_RX_STA & 0x8000)
		{
			len = USB_USART_RX_STA & 0x3FFF; // 得到接收数据的长度
			usb_printf("\r\n接收数据的长度:%d\r\n",len);
			for(t=0;t<len;t++)
			{
				USB_USART_SendData(USB_USART_RX_BUF[t]);
			}
			usb_printf("\r\n\r\n");
			USB_USART_RX_STA = 0;
		}else{
			times++;
			if(times % 5000 == 0)
			{
				usb_printf("\r\nUSB虚拟串口实验\r\n");
			}
			if(times % 200 == 0)
			{
				usb_printf("请输入数据,以回车结束\r\n");
			}
			if(times % 30 == 0)
			{
				LED0 = !LED0;// 提示系统在运行
			}
			delay_ms(10);
		}
	}
}


STM32F103C8 Serial(UART) to USB HID Keyboard Mouse 串口 转 USB键盘鼠标 (1) 使用Composite Device 组合(复合)设备 (1.1) 1个Device -> 1个 Configuation -> 2个Interfance (Keyboard & Mouse) (1.2) Keyboard Interfance -> HID (boot mode) -> 2个Endpoint(IN_0x81 & OUT_0x01) -> KeyboardReportDescriptor(不使用Report ID) (1.3) Mouse Interfance -> HID (boot mode) -> 1个Endpoint(IN_0x82) -> MouseReportDescriptor(不使用Report ID) (1.4) 使用HID boot模式, 不使用Report ID, 以便兼容在 计算器设定BIOS模式 中的操作 (2) 串口接收 命令 (2.1) UART协议: 115200, n, 8, 1 (2.2) 1帧发送字符串格式, 以 '{'开始; '}'结束; ','分隔. 共9个10进制数字 例如: {1,2,3,4,5,6,7,8,9} (2.3) 第9位 区分 Keyboard(64) 或是 Mouse(128) 命令 例如: {0,0,0,0,0,0,0,0,64} --- 发送Keyboard命令 {0,0,0,0,0,0,0,0,128} --- 发送Keyboard命令 (3) 发送Keyboard键盘命令时 : 第1~8位 分别如下 (3.1) 第1位 : Key_Release = 0x00, Left_Control = 0x01, Left_Shift = 0x02, Left_Alt = 0x04, Left_GUI = 0x08, Right_Control = 0x10, Right_Shift = 0x20, Right_Alt = 0x40, Right_GUI = 0x80, 例如: {8,0,0,0,0,0,0,0,64} --- 发送 Win_Key键 {128,0,0,0,0,0,0,0,64} --- 发送 WinApp_Key键 {32,0,0,0,0,0,0,0,64} --- 发送 右Shift键 (3.2)2位 : 保留,不使用,一律填0 (3.3) 第3~8位 : 可以同时发送6个Keyboard按键 例如: {0,0,4,5,6,7,8,9,64} --- 发送 'abcdef'键 {2,0,4,5,6,7,8,9,64} --- 按住 左Shift 发送 'abcdef'键 => 'ABCDEF' {0,0,0,5,0,7,0,9,64} --- 发送 'bdf'键 (0表示 无按键) 按键码 可参阅: (HID Usage ID) http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf https://www.hiemalis.org/~keiji/PC/scancode-translate.pdf https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2 http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (4) 发送Mouse鼠标命令时 : 第1~8位 分别如下 (4.1) 第1位 : Button_Release = 0x00, Left_Button = 0x01, Right_Button = 0x02, Mid_Button = 0x04, 例如: {1,0,0,0,0,0,0,0,128} --- 点击 左键 {2,0,0,0,0,0,0,0,128} --- 点击 右键 {4,0,0,0,0,0,0,0,128} --- 点击 中键 (4.2)2~4位 : 移动(X,Y), 滚轮(Wheel) X: -127~127:左右移动鼠标 Y: -127~127:上下移动鼠标 Wheel: -127~127:上下转动滚轮 例如: {0,20,-10,0,0,0,0,0,128} --- 鼠标 右移20,上移10 {0,0,0,-30,0,0,0,0,128} --- 滚轮-30 (4.2) 第5~8位 : 保留,不使用,一律填0
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值