呆萌球球 2021-08-26 17:14 采纳率: 0%
浏览 172

STM32F1的usb不能发送数据

不想去移植,为了追求代码量,决定从底层驱动开始做起。经过了两周的死磕,我马上就要崩溃了,就是发不出去。哎呀呀。。。。求救求救
void USB_Init(void)
{
    NVIC->ISER[0]                    |= 1<<20;        //USB低优先级或CAN接收0中断
    NVIC->ISER[1]                    |= 1<<10;        //EXTI的从USB待机唤醒中断
    RCC->AHBENR                        |= 1<<6;        //CRC时钟开启
    RCC->APB1ENR                    |= 1<<23;        //USB时钟开启
    USB->CNTR                            &= ~(1<<1);    //退出断电模式
    Wait_us(1);                                                //等待电路稳定
    USB->CNTR                            &= ~(1<<0);    //清除USB复位信号
    USB->ISTR                            &= 0x00E0;    //清除所有中断
    USB->CNTR                            |= 1<<15;        //正确传输(CTR)中断使能,在中断寄存器的相应位被置1时产生中断
    USB->CNTR                            |= 1<<12;        //唤醒中断使能,在中断寄存器的相应位被置1时产生中断
    USB->CNTR                            |= 1<<11;        //挂起(SUSP)中断使能,在中断寄存器的相应位被置1时产生中断
    USB->CNTR                            |= 1<<10;        //USB RESET中断使能
    USB->CNTR                            |= 1<<9;        //SOF中断使能
//    USB->CNTR                            |= 1<<8;        //ESOF中断使能
//    USB->EP0R                              = 0x2260;    //
    USB_SHEET->ADDR0_TX         = 0x0010;    //端点0发送缓冲区地址。即描述表紧接后0x40006020
    USB_SHEET->COUNT0_TX     = 0x0040;    //端点0发送缓冲区64字节(实际是64个short)
    USB_SHEET->ADDR0_RX         = 0x0050;    //端点0发送缓冲区地址:0x40006100
    USB_SHEET->COUNT0_RX     = 0x8100;    //端点0接收缓冲区64字节(实际是64个short)
    USB_SHEET->ADDR1_TX         = 0x0090;    //端点0发送缓冲区地址。即描述表紧接后0x40006120
    USB_SHEET->COUNT1_TX     = 0x0100;    //端点0发送缓冲区128字节(实际是128个short)
    USB_SHEET->ADDR1_RX         = 0x0110;    //端点0发送缓冲区地址:0x40006220
    USB_SHEET->COUNT1_RX     = 0x8300;    //端点0接收缓冲区128字节(实际是128个short)
    USB->DADDR                        |= 1<<7;        //USB模块使能位
}


    void USB_LP_CAN1_RX0_IRQHandler(void)
{
    static unsigned char i=0,TX_COUNT=0;    //i:第几次SETUP        TX_COUNT:发送了的次数
    static unsigned char setup_ok=0;
    switch(USB->ISTR)
    {
        case 12: ;
    }
    if(USB->ISTR & 1<<12)                        //唤醒
        {    
            if(USB->FNR    &    1<<15)
                {                
                }
                else
                {
                    USB->CNTR        &= ~(1<<2);    //非低功耗模式
                    USB->CNTR        &= ~(1<<3);    //退出挂起模式
                }
                USB->ISTR        &= ~(1<<12);    //清除唤醒请求
                
        }
    
    if(USB->ISTR & 1<<11)                        //挂起
        {
            USB->ISTR        &= ~(1<<11);        //清除挂起标志
            USB->CNTR        |= 1<<3;                //进入挂起模式,USB模拟收发器的时钟和静态功耗仍然保持
            USB->CNTR        |= 1<<2;                //低功耗模式
        }
        
    if(USB->ISTR    &    1<<10)                    //USB复位请求
        {
                USB->ISTR     &= 0x00E0;            //清除所有中断
                USB->EP0R        = 0x2260;            //重置端点寄存器
                USB->EP1R        = 0x2001;            //分组缓冲区描述表地址位ARM缓冲区的首地址0x40006000
        }
        
    if(USB->ISTR    &    1<<9)                        //帧首标志
        {
            USB->ISTR    &=    ~(1<<9);            //清除帧首标志
            USB->ISTR    &=    ~(1<<8);            //清除期望帧首标识位
            USB->EP0R    |=1<<12;                    //接收使能
        }
    if(USB->EP0R & 1<<7)                        //发送完成
        {
            USB->EP0R    &= ~(1<<7);                //清除发送完成标志
            switch(TX_COUNT)
            {
                case 0:        USB_SHEET->COUNT0_TX     = 0x0012;    TX_COUNT++;    break;
                case 1:        USB_SHEET->COUNT0_TX     = 0x009;        TX_COUNT++;    break;
                case 2:        USB_SHEET->COUNT0_TX     = 0x009;        TX_COUNT++;    break;
                case 3:        USB_SHEET->COUNT0_TX     = 0x009;        TX_COUNT++;    break;
                case 4:        USB_SHEET->COUNT0_TX     = 0x007;        TX_COUNT++;    break;
            }
        }
        
    if(     USB->EP0R & 1<<15)                    //CTR_RX
        {    
/*枚举过程先将SETP发送,DATA0,ACK。IN,DATA1,ACK
            */
            USB->EP0R    &= ~(1<<15);            //清除CTR_RX标志
/*接收到SETUP后的数据分组后发送DATA1数据包_________________________
*/
            if(setup_ok==1)
            {
                setup_ok=0;        //
                switch(i)        //设备描述
                    {        
                        case 0:    
                        {    
                
                            PA8=!PA8;
                            USB_DATA->duandian0_TX[0] = 0x0112u;
                            USB_DATA->duandian0_TX[1] = 0x0200u;
                            USB_DATA->duandian0_TX[2] = 0x0002u;
                            USB_DATA->duandian0_TX[3] = 0x4000u;
                            USB_DATA->duandian0_TX[4] = 0x0483u;
                            USB_DATA->duandian0_TX[5] = 0x5740u;
                            USB_DATA->duandian0_TX[6] = 0x0200u;
                            USB_DATA->duandian0_TX[7] = 0x0201u;
                            USB_DATA->duandian0_TX[8] = 0x0103u;
                            i++;    
                            USB->EP0R    |= 1u<<4;
                            break;
                        }
                        default :    break;
                    }
            }
/*判断有无SETUP分组______________________________
*/
            if(USB->EP0R & 1<<11)                        //SETUP
            {
                USB->EP0R    |= 1u<<12;                    //接收使能
                setup_ok=1;                                        //标记下一个接收到的数据包位紧随SETUP后的数据分组
                USB->EP0R    &= ~(1<<11);                //清除SETUP标志
            }
            
    }
}

  • 写回答

2条回答 默认 最新

  • qq_41851997 2021-08-26 17:44
    关注

    这种都是寄存器操作很难看的,建议先用例程调通了,慢慢在往你寄存器一步步改。再说这种代码量是没有意义的,真正的代码量是你写的功能,对系统调度的理解。其实官方库函数底层都是寄存器操作,你用库函数成功后再进到函数里一个个对比更好

    评论

报告相同问题?

问题事件

  • 创建了问题 8月26日

悬赏问题

  • ¥15 io.jsonwebtoken.security.Keys
  • ¥15 急,ubuntu安装后no caching mode page found等
  • ¥15 联想交换机NE2580O/NE1064TO安装SONIC
  • ¥15 防火墙的混合模式配置
  • ¥15 Ubuntu不小心注销了要怎么恢复啊
  • ¥15 win10电脑安装完plcsim advanced4.0运行时为什么会提示找不到虚拟网卡
  • ¥15 安装powerbuilder10卡在安装程序正在运行这个页面 没有下一步任何指令
  • ¥15 关于mpi的问题:请问遇到这种情况需要怎么解决,出现这个问题后电脑不能进行mpi多核运行只能进行单核运行
  • ¥50 微信聊天记录备份到电脑提示成功了,但还是没同步到电脑微信
  • ¥15 python怎么在已有视频文件后添加新帧