ldrsw指令(ldrh指令)

ldrsw指令(ldrh指令)p include stm32f10x lib h nbsp nbsp stm32f10x lib h p p include stm32f10x map h nbsp nbsp stm32f10x map h p p include usbreg h nbsp nbsp p

大家好,我是讯享网,很高兴认识大家。




讯享网

 <p>#include <stm32f10x_lib.h>&nbsp;&nbsp;<p>#include <stm32f10x_map.h>&nbsp;&nbsp;<p>#include "usbreg.h"&nbsp;&nbsp;<p>#include "usbuser.h"&nbsp;&nbsp;<p>#include "usbcore.h"&nbsp;&nbsp;<p>#include "usb_hw.h"&nbsp;&nbsp;<p>#define _DEBUG_&nbsp;&nbsp;<p>#include "debug.h"&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>#define USB_EP_NUM&nbsp; 4&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>/*端点缓冲区的开始地址&nbsp;<p>&nbsp;*因为每个缓冲块都需要一个端点描术表&nbsp;<p>&nbsp;*而所有的端点描述表放在,USB缓冲区的首部&nbsp;<p>&nbsp;*此地址是相对于USB缓冲区的地址,我认为加上Offset更好些&nbsp;<p>&nbsp;*这里使用2个端点&nbsp;<p>&nbsp;*端点0与端点1&nbsp;<p>&nbsp;*此时EP_BUF_ADDR指向缓冲区的内容&nbsp;<p>&nbsp;*/&nbsp;&nbsp;<p>#define EP_BUF_ADDR (sizeof(EP_BUF_DSCR)*USB_EP_NUM)&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>/*USB缓冲区首地址包括缓冲区描述表,绝对地址*/&nbsp;&nbsp;<p>EP_BUF_DSCR * pBUF_DSCR = (EP_BUF_DSCR *) USB_PMA_ADDR;&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>/*端点空闲缓冲区地址&nbsp;&nbsp;<p>&nbsp;*用于指示目前为止USB缓冲区中还没有分配的空闲地址的首地址*/&nbsp;&nbsp;<p>WORD&nbsp; &nbsp; FreeBufAddr;&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp;&nbsp;<p>/*功能:用于初始化USB的时钟等部分&nbsp;<p>&nbsp;*参数:无&nbsp;<p>&nbsp;*返回值:无&nbsp;<p>&nbsp;*/&nbsp;&nbsp;<p>void USB_Init(void)&nbsp;&nbsp;<p>{&nbsp;&nbsp;<p>&nbsp; &nbsp; printf("进入USB_Init,进行初始化rn");&nbsp;&nbsp;<p>&nbsp; &nbsp; //使能USB时钟&nbsp;&nbsp;<p>&nbsp; &nbsp; RCC->APB1ENR |= (1<<23);&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>&nbsp; &nbsp; //使能USB中断&nbsp;&nbsp;<p>&nbsp; &nbsp; /*因为USB低优先级中断的中断号为20,而NVIC——IPRX&nbsp;<p>&nbsp; &nbsp; &nbsp;*<a href="https://www.eeworld.com.cn/zhuanti/4KSerL" style="color:#4595e6;" target="_blank">寄存器</a>用四位来存储中断优先级,所以20/4=5 ,&nbsp;<p>&nbsp; &nbsp; &nbsp;*然后使能第20位中断*/&nbsp;&nbsp;<p>&nbsp; &nbsp; NVIC->IPR[5] |=0x10;&nbsp;&nbsp;<p>&nbsp; &nbsp; NVIC->ISER[0]|=(1<<20);&nbsp;&nbsp;<p>}&nbsp;&nbsp;<p>/*功能:用于复位USB模块&nbsp; &nbsp; &nbsp;<p>&nbsp;*参数:无&nbsp;<p>&nbsp;*返回值:无&nbsp;<p>&nbsp;*/&nbsp;&nbsp;<p>/*现在以我的水平还搞不懂双缓冲为何物,所以先不搞^-^*/&nbsp;&nbsp;<p>/*一些资料:&nbsp;<p>&nbsp; *USB低优先级中断(通道20):可由所有USB事件触发(正确传输,USB复位等).&nbsp;<p>&nbsp; *USB高优先级中断(通道19):仅能由同步和双缓冲批量传输事件触发,目的是保证最大的传输速率.&nbsp;<p>&nbsp; *USB唤醒中断(通道42):由USB挂起模式的唤醒事件触发.&nbsp; <a href="https://www.eeworld.com.cn/zhuanti/fr90OS" style="color:#4595e6;" target="_blank">OTG</a>_FS_WKUP唤醒&nbsp;<p>&nbsp; *&nbsp;<p>&nbsp; *复位要执行的内容可以参见rm0008 21.4.2节&nbsp;<p>&nbsp; */&nbsp;&nbsp;<p>void USB_Reset(void)&nbsp;&nbsp;<p>{&nbsp;&nbsp;<p>&nbsp; &nbsp; PrintS("USB_Resetrn");&nbsp;&nbsp;<p>&nbsp; &nbsp; /*复位了嘛,那所有以前产生的中断都没有用了,清了完事!*/&nbsp;&nbsp;<p>&nbsp; &nbsp; ISTR=0;&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>&nbsp; &nbsp; /*通过设置CNTR来控制stm32的USB模块的工作方式&nbsp;<p>&nbsp; &nbsp; &nbsp;*所有的USB事件中断都是在低优先级中断(通道20)上处理的&nbsp;<p>&nbsp; &nbsp; &nbsp;*好吧就先使能这么多吧,先跑起来再说!&nbsp;<p>&nbsp; &nbsp; &nbsp;*/&nbsp;&nbsp;<p>&nbsp; &nbsp; CNTR=&nbsp; &nbsp;CNTR_CTRM&nbsp; &nbsp; &nbsp; &nbsp;|&nbsp; &nbsp;// 使能正确传输中断&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CNTR_RESETM&nbsp; &nbsp; &nbsp;|&nbsp; &nbsp;//使能复位中断&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CNTR_SUSPM&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp;//使能挂起中断&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CNTR_WKUPM&nbsp; &nbsp; &nbsp; ;&nbsp; &nbsp;//使能唤醒中断&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp;&nbsp;<p>&nbsp; &nbsp; FreeBufAddr =&nbsp; &nbsp;EP_BUF_ADDR; //此时FreeBuff指向第一个缓冲区首地址(不包括描述符表),相对地址&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>&nbsp; &nbsp; BTABLE&nbsp; = 0x00;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //设置缓冲区描述表的位置仍是相对地址&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp;&nbsp;<p>&nbsp; &nbsp; /*为端点0设置缓冲区及各种控制位*/&nbsp;&nbsp;<p>&nbsp; &nbsp; pBUF_DSCR->ADDR_TX&nbsp; &nbsp;=&nbsp; &nbsp;FreeBufAddr;&nbsp;&nbsp;<p>&nbsp; &nbsp; FreeBufAddr+=8;&nbsp; &nbsp; &nbsp;//端点0设置为8个字节,一般控制数据为8个字节&nbsp;&nbsp;<p>&nbsp; &nbsp; pBUF_DSCR->ADDR_RX&nbsp; &nbsp;=&nbsp; &nbsp;FreeBufAddr;&nbsp;&nbsp;<p>&nbsp; &nbsp; FreeBufAddr+=8;&nbsp;&nbsp;<p>&nbsp; &nbsp; /*在count_Rx字段中10~14bit用来表示缓冲区字节的快数&nbsp;<p>&nbsp; &nbsp; &nbsp;*而15bit用来表示块的大小&nbsp;<p>&nbsp; &nbsp; &nbsp;*0---2byte&nbsp;<p>&nbsp; &nbsp; &nbsp;*1---1byte&nbsp;<p>&nbsp; &nbsp; &nbsp;*我们这里使用了8个字节,bit15为0,所以应该((8<<10)>>1)即8<<9;&nbsp;<p>&nbsp; &nbsp; &nbsp;*至于count_Rx我们在发送时再来赋值&nbsp;<p>&nbsp; &nbsp; &nbsp;*/&nbsp;&nbsp;<p>&nbsp; &nbsp; pBUF_DSCR->COUNT_RX= 8 << 9;&nbsp; &nbsp; &nbsp;<p>&nbsp; &nbsp; /*设置端点0为控制端点,接收缓冲区有效&nbsp;<p>&nbsp; &nbsp; &nbsp;*低四位代表端点地址&nbsp;<p>&nbsp; &nbsp; &nbsp;*/&nbsp;&nbsp;<p>&nbsp; &nbsp; EPxREG(0) = EP_CONTROL | EP_RX_VALID;&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>&nbsp; &nbsp; /*使能USB模块,并设置USB地址为0,以响应枚举*/&nbsp;&nbsp;<p>&nbsp; &nbsp; DADDR = DADDR_EF | 0;&nbsp;&nbsp;<p>}&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>/*功能:复位一个端点&nbsp;<p>&nbsp;*参数:&nbsp; &nbsp;端点号&nbsp;<p>&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EPNum:bit3~bit0 ----> 端点号&nbsp;<p>&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EPNum:bit7&nbsp; &nbsp; &nbsp; ----> 端点方向&nbsp;<p>&nbsp;*&nbsp;<p>&nbsp;*返回值:无&nbsp;<p>&nbsp;*/&nbsp;&nbsp;<p>&nbsp;/*其实就是将下一个要发送的数据包变成DATA0*/&nbsp;&nbsp;<p>&nbsp;void&nbsp; &nbsp;EP_Reset(DWORD&nbsp; EPNum)&nbsp;&nbsp;<p>&nbsp;{&nbsp;&nbsp;<p>&nbsp; &nbsp; DWORD&nbsp; &nbsp;num,var;&nbsp;&nbsp;<p>&nbsp; &nbsp; PrintS("EP_Resetrn");&nbsp;&nbsp;<p>&nbsp; &nbsp; /*获得端点号,低四位为端点号*/&nbsp;&nbsp;<p>&nbsp; &nbsp; num = EPNum & 0x0F;&nbsp;&nbsp;<p>&nbsp; &nbsp; var = EPxREG(num);&nbsp;&nbsp;<p>&nbsp; &nbsp; /*如果bit7为1则将此端点的发送toggle置为0,&nbsp;<p>&nbsp; &nbsp; &nbsp;*否则将此端点的接收toggle置为0&nbsp;<p>&nbsp; &nbsp; &nbsp;*因为数据总是从data0数据包开始发送的&nbsp;<p>&nbsp; &nbsp; &nbsp;*/&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp;if(EPNum & 0x80)&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; EPxREG(num) = var & (EP_MASK | EP_DTOG_TX);/*输入端点*/&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp;else&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; EPxREG(num) = var & (EP_MASK | EP_DTOG_RX);/*输出端点*/&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp;<p>&nbsp;}&nbsp;&nbsp;<p>&nbsp;/*功能:连接或断开USB功能&nbsp;<p>&nbsp; *参数:true -->连接USB&nbsp;<p>&nbsp; *&nbsp; &nbsp; &nbsp; false-->关闭USB&nbsp;<p>&nbsp; *返回值:无&nbsp;<p>&nbsp; */&nbsp;&nbsp;<p>void USB_Connect(BOOL turnon)&nbsp;&nbsp;<p>{&nbsp;&nbsp;<p>&nbsp; &nbsp; /*需要注意一点的事,所有的USB寄存器尽量用=而不要用与或非&nbsp;<p>&nbsp; &nbsp; &nbsp;*在编程手册上有明确表明,这样可能会导至出一些问题*/&nbsp;&nbsp;<p>&nbsp; &nbsp; printf("进入连接USB程序rn");&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp;/*将USB强制复位*/&nbsp;&nbsp;<p>&nbsp; &nbsp; CNTR = CNTR_FRES;&nbsp;&nbsp;<p>//&nbsp; printf("test1rn");&nbsp;&nbsp;<p>&nbsp; &nbsp; /*因为刚连接所以应该跟才启动一样,将所有没有处理的中断给清理掉*/&nbsp;&nbsp;<p>&nbsp; &nbsp; ISTR=0;&nbsp;&nbsp;<p>//&nbsp; printf("test2rn");&nbsp;&nbsp;<p>&nbsp; &nbsp; if(turnon)&nbsp;&nbsp;<p>&nbsp; &nbsp; {&nbsp;&nbsp;<p>//&nbsp; &nbsp; &nbsp; printf("test3rn");&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; /*使能GPIOA,然后将PA.8置低,使USB&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*的D+加1.5K上接电阻,使USB集线器识别了高速设备&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*这样才能让USB识别&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RCC->APB2ENR |= (1 << 2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* enable clock for GPIOA */&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GPIOA->CRH &= ~(0x0f << 0 * 4);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* clear port PA8 */&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GPIOA->CRH |=&nbsp; (0x03 << 0 * 4);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* PA6 General purpose output open-drain, max speed 50 MHz */&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GPIOA->BRR&nbsp; =&nbsp; (&nbsp; &nbsp;1 << 8&nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* reset PA8&nbsp; (set to low) */&nbsp; &nbsp; &nbsp; &nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; /*经过调试发现,这个语句的本意是:复位USB模块&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*然后在此使能CNTR_RESETM即复位中断标志&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*至于端点0的初始化留在USB低优先级中进行处理&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*当然,我们也只开了低优先级中断^_^!*/&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CNTR = CNTR_RESETM;&nbsp; &nbsp; /*此处只使能了复位中断,*/&nbsp; &nbsp; &nbsp; &nbsp;<p>&nbsp; &nbsp; }&nbsp;&nbsp;<p>&nbsp; &nbsp; else&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; CNTR = CNTR_FRES | CNTR_PDWN ;/*复位并关闭*/&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>}&nbsp;&nbsp;<p>/*功能:设置端点状态&nbsp;<p>&nbsp;*参数:EPnum --->端点号&nbsp;<p>&nbsp;*&nbsp; &nbsp; &nbsp;stat&nbsp; --->要设置的状态值&nbsp;<p>&nbsp;*返回值:无&nbsp;<p>&nbsp;*/&nbsp;&nbsp;<p>&nbsp;void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD)&nbsp;&nbsp;<p>&nbsp;{&nbsp;&nbsp;<p>&nbsp; &nbsp; DWORD num,val;&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp;&nbsp;<p>&nbsp; &nbsp; //取得端点号&nbsp;&nbsp;<p>&nbsp; &nbsp; num = pEPD->bEndpointAddress & 0xf;&nbsp;&nbsp;<p>&nbsp;&nbsp;<p>&nbsp; &nbsp; val = pEPD->wMaxPacketSize;&nbsp;&nbsp;<p>&nbsp; &nbsp; //如果是IN端点&nbsp;&nbsp;<p>&nbsp; &nbsp; if(pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK)&nbsp;&nbsp;<p>&nbsp; &nbsp; {&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; //此处我只想说pBUF_DSCR是指针,剩下的就是语法问题了&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; (pBUF_DSCR + num)->ADDR_TX = FreeBufAddr;&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; /*取2的倍数,因为缓冲区都是字对齐的,注意此处如果大于1023会出现浪费现象&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*因为USB_COUNTn_TX只能接收bit0~bit9&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; val = (val + 1)& ~1;&nbsp;&nbsp;<p>&nbsp; &nbsp; }&nbsp;&nbsp;<p>&nbsp; &nbsp; //输出端点&nbsp;&nbsp;<p>&nbsp; &nbsp; else&nbsp;&nbsp;<p>&nbsp; &nbsp; {&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; (pBUF_DSCR + num)->ADDR_RX = FreeBufAddr;&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; /*因为USB_COUNTn_RX中存储只用bit10~bit14,如果BLSIZE=0(即块大小为2字节),那么只能是0~62个字节&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*所以如果大于62,则应将块大小设置为BLSIZE=1(即32个字节)&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; if(val > 62&nbsp; )&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //块大小为32,则大小应该为32的倍数&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; val = (val +31)&~31;&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /*关于此计算公式,参见rm0008,21,5.3节&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*(val >> 5)<<10 == val <<5&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (pBUF_DSCR + num)->COUNT_RX = ((val << 5)-1) | 0x8000;&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; val = (val + 1) & ~1;&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (pBUF_DSCR + num)->COUNT_RX = val << 9;&nbsp;&nbsp;<p>&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;&nbsp;<p>&nbsp; &nbsp; }&nbsp;&nbsp; 

讯享网
小讯
上一篇 2025-05-11 08:54
下一篇 2025-06-12 19:29

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/170770.html