lgwd 发表于 2023-6-1 10:22:43

CDC串口初始化时如果没有插USB线,程序无法继续

本帖最后由 沈洁 于 2023-6-1 13:43 编辑

如果没有插入USB线,下位机开机后一直等待。插入USB线后才完成初始化状态。可是下位机有时需要单机使用,不连接USB端口。如何处理?

hsrzq 发表于 2023-6-1 10:26:42

代码贴出来看看?感觉你是在main里面死等CDC初始化了?

沈洁 发表于 2023-6-1 13:43:18

做延时跳出程序啊

lgwd 发表于 2023-6-1 14:43:20

主程序如下
void sysu_init();                                    //声明系统基本初始化函数,包括USB初始化

defineFOSC   24000000UL                            //ISP下载时, 需要将工作频率IRC设置为 24MHz。

char *USER_DEVICEDESC = NULL ;
char *USER_PRODUCTDESC = NULL ;
char *USER_STCISPCMD = "@STCISP#" ;                   //不停电ISP自动下载命令

void main(void)//主函数
{
    cta_ini() ;                                       //除了CDC相关的其它系统初始化语句
    sysu_init();                                    //USB的CDC初始化程序

    while(1)                                       //死循环
    {
      其他执行语句
    }
}

void sysu_init()                                           //系统初始化
{
    P_SW2 |= 0x81 ;                                        //允许访问XFR

    P0M1 = 0x00;   P0M0 = 0x00;                            //设置为准双向口。00准双向;01推挽输出;10高阻输入;11开漏输出
    P1M1 = 0x00;   P1M0 = 0x00;                            //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;                            //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;                            //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;                            //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;                            //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;                            //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;                            //设置为准双向口

    P3M0 &=~0x03 ;                                       //P3.0/P3.1与USB的D-/D+共用引脚
    P3M1 |= 0x03 ;                                       //需要将P3.0/P3.1设置为高阻模式。
   
    IRC48MCR = 0x80;                                       //内部48MHz震荡器控制寄存器。使能内部48M的USB专用IRC。第1位是振荡器稳定标志位。
    while (!(IRC48MCR & 0x01));                            //等待振荡器稳定
    USBCLK = 0x00;                                       //设置USB时钟源为内部48MHz的USB专用IRC
    USBCON = 0x90;                                       //使能USB功能
    usb_init();                                          //调用USB CDC初始化库函数
    IE2 |= 0x80;                                           //使能USB中断
    EA = 1;                                                //打开总中断
        while (DeviceState != DEVSTATE_CONFIGURED);            //等待USB完成配置
}

去掉sysu_init(); 就是我们原来的程序。再就是加入了STC的中断CDC库文件。
也就是增加了这一块,USB线就需要插入PC的USB口,否则上电时就停止。初始化结束后,拔下USB线程序可以运行(暂时不使用CDC串口),但是复位后初始化又陷入等待,需要再插入USB线。
去掉sysu_init();,就没有这个问题了。当然也没有CDC串口了。

乘风飞扬 发表于 2023-6-1 14:51:47

while (DeviceState != DEVSTATE_CONFIGURED);            //等待USB完成配置
这条指令导致程序一直在等待USB完成配置。
可以在USB通信相关程序前面加判断,USB没有完成配置就退出,其它代码照常执行。

hsrzq 发表于 2023-6-1 16:45:59

lgwd 发表于 2023-6-1 14:43
主程序如下
void sysu_init();                                    //声明系统基本初始化函数,包括USB初 ...

while (DeviceState != DEVSTATE_CONFIGURED);
果然和我猜的一毛一样,在死等CDC初始化完成~

lgwd 发表于 2023-6-1 20:10:23

如果STC的CDC初始化程序自身没有超时判断,那就只能用户外加定时判断。因为我们的下位机今天也许要联机操作,或许明日需要单机操作,传统串口不需要判定。

梁工 发表于 2023-6-1 21:59:18

增加超时处理。例子为了简单,不加处理。
实际项目,不管程序有多复杂,我任何地方都不会有死等的情况,也不要经常执行几十us以上的软件延时,可以采取的方法有:超时处理(软件定时器),时隙驱动,状态机查询,或者RTOS。

沈洁 发表于 2023-6-2 10:54:41

乘风飞扬 发表于 2023-6-1 14:51
while (DeviceState != DEVSTATE_CONFIGURED);            //等待USB完成配置
这条指令导致程序一直在等待U ...

这句话就是会咬死的,所以正常的是需要给等待加一个时间,超时就跳出,能理解吗

lgwd 发表于 2023-6-2 12:32:45

我们系统中T0定时器中断是最高等级。T0中断服务程序中已经设置了一个防死操作变量。现在就用它在上述语句中再增加一个等待时间判定条件,与“DeviceState != DEVSTATE_CONFIGURED”是“&&”的关系,容易解决。之前只是想既然使用STC的官方操作,看官方有什么标准操作方法。谢谢大家回复!
页: [1]
查看完整版本: CDC串口初始化时如果没有插USB线,程序无法继续