STM32-USB使用方法
STM32-USB使用方法
开发板买的是奋斗mini开发板,芯片是:STM32F103VET6. 如果需要源程序keil4-arm工程,上位机vb。加qq339396264要程序。
USB开发涉及主机和设备,为了避免开发驱动程序,使用Windows自带的驱动程序。所以设备枚举成HID类设备。USB鼠标就是标准的USB-HID设备。不过操作系统阻止了应用程序直接访问USB鼠标返回的报告。所以本例使用自定义HID设备。一来免去了开发驱动程序,二来自定义的HID设备应用程序和设备可以自由收发数据(仅指数据内容)。
本文主要介绍STM32的USB模块的简单使用,不会介绍USB协议。主要是介绍一下STM32F103的USB模块使用。
USB模块从初始化首先是配置和使能时钟
下面是时钟的初始化:
void Set_USBClock(void) { }
首先系统时钟要设置为72MHz,然后配置USB时钟为48MHz并使能。
然后是配置中断
void USB_Interrupts_Config(void) { }
//【使能USB中断】
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; //【USB低优先级中断】 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitTypeDef NVIC_InitStructure; #define USB_LP_CAN1_RX0_IRQn 20
//RCC_USBCLKSource_PLLCLK_1Div5表示【USB时钟 = PLL时钟除以1.5】【72/1.5=48MHz】 RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);//【使能配置好了的USB时钟】
然后初始化模块的一些寄存器 USART_send_str(\断开\\r\\n\
USB_DISCONNECT//这是断开1.5k上拉电阻 delay(0x7AFFFF);//延时一会
USB_CONNECT//使能1.5K上拉电阻 USART_send_str(\连接\\r\\n\
DADDR = 0x0080;//USB模块使能位。EF必须置1
CNTR = 0x0001;//强制复位 CNTR = 0x0000;//退出复位
ISTR = 0x0000;//清除可能产生的假中断
CNTR = (I_CTR | I_RESET);//使能一些中断,为了简单这里只使能了【总线复位中断】和【数据正确传输中断】 ISTR = 0x0000;//清除可能产生的假中断
自此USB模块初始化完毕。
以后的流程就在USB中断的驱动下执行。
USB中断函数:
void USB_LP_CAN1_RX0_IRQHandler(void) { u16 wIstr; //USB中断状态寄存器 wIstr = (u16)ISTR; //【USB复位中断】 if(wIstr &I_RESET) { USB_RST_Process(); return; } //【正确传输中断】 if (wIstr & I_CTR) { USB_CTR_Process(); return; } }
在USB中断函数中就是判断中断源,并转向相应的中断服务函数。
USB总线复位后,USB相关的一些寄存器会复位。在USB总线复位中要配置一下寄存器和数据收发的缓冲区。程序如下 void USB_RST_Process(void) { //清除中断 ISTR = (u16)(~I_RESET);//清除ISTR寄存器中断RESET位。写0清除,写1寄存器位内容不变。
// USART_send_str(\【USB】【复】【位】【中】【断】\\r\\n\ usb_status = 0; //复位处理 DADDR = 0x0080; //USB模块使能位。EF必须置1 BTABLE = 0; //复位后默认为0 EP0REG = (u16)(0x0220); //0000 0010 0010 0000 端点0初始化:控制端点,NAK主机的IN令牌,端点号0 //设置TX/RX起始地址 USB_ADDR0_TX = 32;//32-95 端点0的发送缓冲区从32开始到95,共64字节 USB_ADDR0_RX = 96;//96-159 端点0的接收缓冲区从96开始到159,共64字节 //设置端点0接收缓冲区大小:64Byte USB_CNT0_RX = 0x8400;//1000,0100,0000,0000
//【端点1】
EP1REG = (u16)(0x0621);//0000 0110 0010 0001 端点0初始化:中断端点,NAK主机的IN令牌,端点号1
//设置TX/RX起始地址
USB_ADDR1_TX = 160;//160-223 端点1的发送缓冲区从160开始到223,共64字节 USB_ADDR1_RX = 224;//224-287 端点1的接收缓冲区从224开始到287,共64字节 //设置端点1接收缓冲区大小:64Byte
USB_CNT1_RX = 0x8400;//1000,0100,0000,0000 //设置RX Valid .端点0可用于接收 { u16 t = EP0REG;//读出端点0寄存器值 t &= 0x8F8F;//1000 1111 1000 1111 由于t位写0不影响原来的值,写1翻转,所以把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 由于w0位写0清除,写1无影响,所以w0位都设置为1 t |= 0x3000;//0011 0000 0000 0000 把 SRAT_RX[1:0]设置为1,通过写1翻转来实现。 EP0REG = t; } }
下面是正确传输中断 //USB分组正确传输处理 void USB_CTR_Process(void) {
/******************************************【端点0】******************************************/ if((ISTR & 0x0F) == 0)//端点0 { // //
if((ISTR & 0x10) == 0)//in分组 { }
USART_send_str(\端点0的IN分组发送完成****************\\r\\n\
if(usb_status == 1) { usb_status = 2; DADDR = 0x80 | (usb_addr&0xFF);//设置地址一定要找控制传输的状态完成后写入地址寄存器 USART_send_str(\【写入地址完成】\\r\\n\}
//发送剩余数据 USB_ep0_send();
//清除CTR_TX { u16 t = EP0REG; t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 t &= 0xFF7F;//1111 1111 0111 1111 把CTR_TX设置为0,清除CTR_RX位 EP0REG = t; }
if(ISTR & 0x10)//【OUT】分组 or 【SETUP】分组 { u16 ep0r= EP0REG;
//清除CTR_RX { u16 t = EP0REG; t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 t &= 0x7FFF;//0111 1111 1111 1111 把CTR_RX设置为0,清除CTR_RX位 EP0REG = t; }
if(ep0r & 0x0800)//SETUP令牌包 { //USART_send_str(\端点0收到【SETUP】分组\\r\\n\ //默认控制端点处理——枚举处理 ep0_setup_Process(); memset(USB_rcv_buffer, 0x00, sizeof(USB_rcv_buffer)); USB_enable_ep0_rx(); } else { //USART_send_str(\控制读传输:状态阶段\\r\\n\ USB_read_EP0_buf(USB_rcv_buffer, (u32*)(PMAAddr+96*2)); USB_enable_ep0_rx(); } } //else//【IN分组传输成功】 }
/******************************************【端点1】******************************************/ else if((ISTR & 0x0F) == 1) { USART_send_str(\端点1数据完成传输\\r\\n\ if(ISTR & 0x10)//【OUT分组】 { //清除CTR_RX { u16 t = EP1REG; t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 t &= 0x7FFF;//0111 1111 1111 1111 把CTR_RX设置为0,清除CTR_RX位 EP1REG = t; …… 此处隐藏:3188字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [综合文档]应答器设备技术规范(征求意见稿)A1
- [综合文档]教师 2012年高考政治试题按考点分类汇
- [综合文档]保险公司的总经理助理竞职演说
- [综合文档]卫生应急大练兵大比武活动考试--题库(
- [综合文档]徐州经济技术开发区总体规划环境影响报
- [综合文档]汉语拼音表(带声调)
- [综合文档]二年级 上 思维训练( 1~18)
- [综合文档]特色学校五年发展规划
- [综合文档]机床经常出现报警“X1轴定位监控”
- [综合文档]《电子技术基础》21.§5—2、3、4 习题
- [综合文档]浙江省深化普通高中课程改革
- [综合文档]CRISP原理 - 图文
- [综合文档]2017年电大社会调查研究与方法形考答案
- [综合文档]浅析建筑施工安全毕业论文
- [综合文档]《回忆我的母亲》名师教案
- [综合文档]装饰装修工程监理规划
- [综合文档]三下乡心得体会-文艺
- [综合文档]柱计算长度系数 - 图文
- [综合文档]全流程思考,提高燃电系统热电转换率--
- [综合文档]2018年嘉定区中考物理一模含答案
- 433M车库门滚动码遥控器
- 8、架空线路施工规范
- 大学四年声乐学习的体会
- 新北师大版五年级数学上册《轴对称再认
- 部编版五年级上册语文第六单元小结复习
- 小学六年级英语形容词用法
- 第2课 抗美援朝保家卫国 课件01(岳麓版
- 2015年天津大学运筹学基础考研真题,考
- 微机计算机控制技术课后于海生(第2版)
- 安全教育实践活动
- Delphi程序设计教程_第1章_Delphi概述
- 第八讲 工业革命与启蒙运动
- 《中华人民共和国药典》2005年版二部勘
- 科粤版九年级化学2.3构成物质的微粒(1)
- 西师大版数学三年级下册《长方形、正方
- ch6_冒泡排序演示
- 第4章 冲裁模具设计
- 浙江中小民营企业员工流失论文[终稿]
- 再议有线数字电视市场营运模式
- 昆明供水工程监理大纲




