当前位置:网站首页 > R语言数据分析 > 正文

ldrsw指令(ldrh指令)



#include   

#include   

#include "usbreg.h"  

#include "usbuser.h"  

#include "usbcore.h"  

#include "usb_hw.h"  

#define _DEBUG_  

#include "debug.h"  

  

#define USB_EP_NUM 4  

  

/*端点缓冲区的开始地址

*因为每个缓冲块都需要一个端点描术表

*而所有的端点描述表放在,USB缓冲区的首部

*此地址是相对于USB缓冲区的地址,我认为加上Offset更好些

*这里使用2个端点

*端点0与端点1

*此时EP_BUF_ADDR指向缓冲区的内容

*/  

#define EP_BUF_ADDR (sizeof(EP_BUF_DSCR)*USB_EP_NUM)  

  

/*USB缓冲区首地址包括缓冲区描述表,绝对地址*/  

EP_BUF_DSCR * pBUF_DSCR = (EP_BUF_DSCR *) USB_PMA_ADDR;  

  

/*端点空闲缓冲区地址  

*用于指示目前为止USB缓冲区中还没有分配的空闲地址的首地址*/  

WORD FreeBufAddr;  

  

  

/*功能:用于初始化USB的时钟等部分

*参数:无

*返回值:无

*/  

void USB_Init(void)  

{  

printf("进入USB_Init,进行初始化rn");  

//使能USB时钟  

RCC->APB1ENR |= (1<<23);  

  

//使能USB中断  

/*因为USB低优先级中断的中断号为20,而NVIC——IPRX

*寄存器用四位来存储中断优先级,所以20/4=5 ,

*然后使能第20位中断*/  

NVIC->IPR[5] |=0x10;  

NVIC->ISER[0]|=(1<<20);  

}  

/*功能:用于复位USB模块

*参数:无

*返回值:无

*/  

/*现在以我的水平还搞不懂双缓冲为何物,所以先不搞^-^*/  

/*一些资料:

*USB低优先级中断(通道20):可由所有USB事件触发(正确传输,USB复位等).

*USB高优先级中断(通道19):仅能由同步和双缓冲批量传输事件触发,目的是保证最大的传输速率.

*USB唤醒中断(通道42):由USB挂起模式的唤醒事件触发. OTG_FS_WKUP唤醒

*

*复位要执行的内容可以参见rm0008 21.4.2节

*/  

void USB_Reset(void)  

{  

PrintS("USB_Resetrn");  

/*复位了嘛,那所有以前产生的中断都没有用了,清了完事!*/  

ISTR=0;  

  

/*通过设置CNTR来控制stm32的USB模块的工作方式

*所有的USB事件中断都是在低优先级中断(通道20)上处理的

*好吧就先使能这么多吧,先跑起来再说!

*/  

CNTR= CNTR_CTRM | // 使能正确传输中断  

CNTR_RESETM | //使能复位中断  

CNTR_SUSPM | //使能挂起中断  

CNTR_WKUPM ; //使能唤醒中断  

  

FreeBufAddr = EP_BUF_ADDR; //此时FreeBuff指向第一个缓冲区首地址(不包括描述符表),相对地址  

  

BTABLE = 0x00; //设置缓冲区描述表的位置仍是相对地址  

  

/*为端点0设置缓冲区及各种控制位*/  

pBUF_DSCR->ADDR_TX = FreeBufAddr;  

FreeBufAddr+=8; //端点0设置为8个字节,一般控制数据为8个字节  

pBUF_DSCR->ADDR_RX = FreeBufAddr;  

FreeBufAddr+=8;  

/*在count_Rx字段中10~14bit用来表示缓冲区字节的快数

*而15bit用来表示块的大小

*0---2byte

*1---1byte

*我们这里使用了8个字节,bit15为0,所以应该((8<<10)>>1)即8<<9;

*至于count_Rx我们在发送时再来赋值

*/  

pBUF_DSCR->COUNT_RX= 8 << 9;

/*设置端点0为控制端点,接收缓冲区有效

*低四位代表端点地址

*/  

EPxREG(0) = EP_CONTROL | EP_RX_VALID;  

  

/*使能USB模块,并设置USB地址为0,以响应枚举*/  

DADDR = DADDR_EF | 0;  

}  

  

/*功能:复位一个端点

*参数: 端点号

* EPNum:bit3~bit0 ----> 端点号

* EPNum:bit7 ----> 端点方向

*

*返回值:无

*/  

/*其实就是将下一个要发送的数据包变成DATA0*/  

void EP_Reset(DWORD EPNum)  

{  

DWORD num,var;  

PrintS("EP_Resetrn");  

/*获得端点号,低四位为端点号*/  

num = EPNum & 0x0F;  

var = EPxREG(num);  

/*如果bit7为1则将此端点的发送toggle置为0,

*否则将此端点的接收toggle置为0

*因为数据总是从data0数据包开始发送的

*/  

if(EPNum & 0x80)  

EPxREG(num) = var & (EP_MASK | EP_DTOG_TX);/*输入端点*/  

else  

EPxREG(num) = var & (EP_MASK | EP_DTOG_RX);/*输出端点*/  

}  

/*功能:连接或断开USB功能

*参数:true -->连接USB

* false-->关闭USB

*返回值:无

*/  

void USB_Connect(BOOL turnon)  

{  

/*需要注意一点的事,所有的USB寄存器尽量用=而不要用与或非

*在编程手册上有明确表明,这样可能会导至出一些问题*/  

printf("进入连接USB程序rn");  

/*将USB强制复位*/  

CNTR = CNTR_FRES;  

// printf("test1rn");  

/*因为刚连接所以应该跟才启动一样,将所有没有处理的中断给清理掉*/  

ISTR=0;  

// printf("test2rn");  

if(turnon)  

{  

// printf("test3rn");  

/*使能GPIOA,然后将PA.8置低,使USB

*的D+加1.5K上接电阻,使USB集线器识别了高速设备

*这样才能让USB识别

*/  

RCC->APB2ENR |= (1 << 2); /* enable clock for GPIOA */  

GPIOA->CRH &= ~(0x0f << 0 * 4); /* clear port PA8 */  

GPIOA->CRH |= (0x03 << 0 * 4); /* PA6 General purpose output open-drain, max speed 50 MHz */  

GPIOA->BRR = ( 1 << 8 ); /* reset PA8 (set to low) */

/*经过调试发现,这个语句的本意是:复位USB模块

*然后在此使能CNTR_RESETM即复位中断标志

*至于端点0的初始化留在USB低优先级中进行处理

*当然,我们也只开了低优先级中断^_^!*/  

CNTR = CNTR_RESETM; /*此处只使能了复位中断,*/

}  

else  

CNTR = CNTR_FRES | CNTR_PDWN ;/*复位并关闭*/  

  

}  

/*功能:设置端点状态

*参数:EPnum --->端点号

* stat --->要设置的状态值

*返回值:无

*/  

void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD)  

{  

DWORD num,val;  

  

//取得端点号  

num = pEPD->bEndpointAddress & 0xf;  

  

val = pEPD->wMaxPacketSize;  

//如果是IN端点  

if(pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK)  

{  

//此处我只想说pBUF_DSCR是指针,剩下的就是语法问题了  

(pBUF_DSCR + num)->ADDR_TX = FreeBufAddr;  

/*取2的倍数,因为缓冲区都是字对齐的,注意此处如果大于1023会出现浪费现象

*因为USB_COUNTn_TX只能接收bit0~bit9

*/  

val = (val + 1)& ~1;  

}  

//输出端点  

else  

{  

(pBUF_DSCR + num)->ADDR_RX = FreeBufAddr;  

/*因为USB_COUNTn_RX中存储只用bit10~bit14,如果BLSIZE=0(即块大小为2字节),那么只能是0~62个字节

*所以如果大于62,则应将块大小设置为BLSIZE=1(即32个字节)

*/  

if(val > 62 )  

{  

//块大小为32,则大小应该为32的倍数  

val = (val +31)&~31;  

/*关于此计算公式,参见rm0008,21,5.3节

*(val >> 5)<<10 == val <<5

*/  

(pBUF_DSCR + num)->COUNT_RX = ((val << 5)-1) | 0x8000;  

}  

else  

{  

val = (val + 1) & ~1;  

(pBUF_DSCR + num)->COUNT_RX = val << 9;  

}  

}  到此这篇ldrsw指令(ldrh指令)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • uchari什么意思(uchida是什么意思)2026-04-18 13:27:05
  • 颜色代码 转换(颜色代码转换RGBA)2026-04-18 13:27:05
  • bytebufferwrap会复制数组吗(bytebuffer.wrap)2026-04-18 13:27:05
  • list<string>转换为数组(list转换成string字符串)2026-04-18 13:27:05
  • springweb和springwebmvc的关系(spring与springmvc的区别与联系)2026-04-18 13:27:05
  • qpainterpath 平移(qpainter drawpie)2026-04-18 13:27:05
  • entware命令(命令enable)2026-04-18 13:27:05
  • endoport器械(technogym abdominal crunch器械用法)2026-04-18 13:27:05
  • swagger无法访问(swagger-ui访问不到)2026-04-18 13:27:05
  • swagger2 配置(swagger的配置)2026-04-18 13:27:05
  • 全屏图片