找回密码
 立即注册
楼主: templeton

STC32G144K246中USB模块和系统时钟的关系

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:156
  • 最近打卡:2026-03-23 08:54:25

25

主题

50

回帖

863

积分

高级会员

积分
863
发表于 2026-1-16 14:37:50 | 显示全部楼层
对这个问题,个人比较感兴趣,猜想存在问题的地方可能在三个地方:
1、USB模块工作异常,2、对USB寄存器操作异常,3、芯片工作异常。

1、USB模块是独立的时钟,和主频无关。这个先排除。
2、系统时钟和USB的时钟差异大时,可能会导致读写寄存器不同步,可以考虑一下。
3、芯片工作异常。除了USB模块外,其他未发现异常,这个先排除。

对USB模块操作主要是通过两个函数usb_read_reg()和usb_write_reg()进行的。
BYTE usb_read_reg(BYTE addr)
{
        BYTE dat;
        while (USBADR & 0x80);
        USBADR = addr | 0x80;
        while (USBADR & 0x80);
        dat = USBDAT;
        return dat;
}
usb_read_reg()函数是有时序控制的。
void usb_write_reg(BYTE addr, BYTE dat)
{
        while (USBADR & 0x80);
        USBADR = addr & 0x7f;
        USBDAT = dat;
}
如果是操作时钟不匹配,大概率是usb_write_reg()的原因。USBADR还没有设置好,就设置了USBDAT。
于是在指令之间加入延时测试。
当主时钟为80MHz时,指令之间加一个nop后通信正常。
void usb_write_reg(BYTE addr, BYTE dat)
{
        while (USBADR & 0x80);
        USBADR = addr & 0x7f;
        NOP1();
        USBDAT = dat;
}
当主时钟为120MHz时,需要加多个时钟才能恢复通信正常。
void usb_write_reg(BYTE addr, BYTE dat)
{
        while (USBADR & 0x80);
        NOP5();
        USBADR = addr & 0x7f;
        NOP10();
        USBDAT = dat;
}
通过以上测试,个人认为应该是主频高时,内核对USB模块寄存器操作出现问题。
如果能加入设置寄存器完成判断,应该可以消除这个问题。

点评

比较倾向于第二点,时钟域配合问题 但是usb_write_reg即便加上while (USBADR & 0x80);也会在120M下识别失败 举个反例: 一个碰巧能在120M下工作的HID例程,而且usb_write_reg未改变:  详情 回复 发表于 2026-1-16 15:51
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:180
  • 最近打卡:2026-03-24 01:57:13

25

主题

231

回帖

2063

积分

金牌会员

积分
2063
发表于 2026-1-16 15:32:49 | 显示全部楼层
分析的有道理。
遇到类似情况,密切关注。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:483
  • 最近打卡:2026-03-23 08:55:58
已绑定手机

104

主题

4195

回帖

9307

积分

荣誉版主

无情的代码机器

积分
9307
发表于 2026-1-16 15:51:38 | 显示全部楼层
templ*** 发表于 2026-1-16 14:37
对这个问题,个人比较感兴趣,猜想存在问题的地方可能在三个地方:1、USB模块工作异常,2、对USB寄存器操作 ...

比较倾向于第二点,时钟域配合问题

但是usb_write_reg即便加上while (USBADR & 0x80);也会在120M下识别失败

举个反例:
69-HID(Human Interface Device)协议范例.zip (462.63 KB, 下载次数: 6)
一个碰巧能在120M下工作的HID例程,而且usb_write_reg未改变:
69-HID(Human Interface Device)协议范例-120M.zip (462.74 KB, 下载次数: 6)
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:156
  • 最近打卡:2026-03-23 08:54:25

25

主题

50

回帖

863

积分

高级会员

积分
863
发表于 2026-1-16 16:01:30 | 显示全部楼层
erci*** 发表于 2026-1-16 15:51
比较倾向于第二点,时钟域配合问题

但是usb_write_reg即便加上while (USBADR & 0x80);也会在120M下识别 ...

usb_write_reg里加while (USBADR & 0x80);是无效的,我也测试过。USBADR中的BUSY是USB正在读取间接寄存器,而这个函数的USBDAT是外部操作的,和BUSY无关。所以我测试时是加延时的。

点评

分析有道理,这里加了延时确实也会变正常  详情 回复 发表于 2026-1-16 16:24
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:483
  • 最近打卡:2026-03-23 08:55:58
已绑定手机

104

主题

4195

回帖

9307

积分

荣誉版主

无情的代码机器

积分
9307
发表于 2026-1-16 16:24:17 | 显示全部楼层
templ*** 发表于 2026-1-16 16:01
usb_write_reg里加while (USBADR & 0x80);是无效的,我也测试过。USBADR中的BUSY是USB正在读取间接寄存器 ...

分析有道理,这里加了延时确实也会变正常
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:483
  • 最近打卡:2026-03-23 08:55:58
已绑定手机

104

主题

4195

回帖

9307

积分

荣誉版主

无情的代码机器

积分
9307
发表于 2026-1-16 17:17:52 | 显示全部楼层
read函数也要加,试下这两120MHz HID&CDC:

usb_120M_test.zip (684.36 KB, 下载次数: 10)
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:156
  • 最近打卡:2026-03-23 08:54:25

25

主题

50

回帖

863

积分

高级会员

积分
863
发表于 2026-1-17 19:59:11 | 显示全部楼层
erci*** 发表于 2026-1-16 17:17
read函数也要加,试下这两120M HID&CDC:

usb_read_reg()函数按照原例程应该是可以的。原例程例在设置完add后,等待dat寄存器准备好后,才能读,这里的while (USBADR & 0x80);是有效的。这时的dat是USB模块准备的,所以可以通过查询USBADR的标志位来确定的。
BYTE usb_read_reg(BYTE addr)
{
        BYTE dat;

        while (USBADR & 0x80);
        USBADR = addr | 0x80;
        while (USBADR & 0x80);
        dat = USBDAT;

        return dat;
}

点评

我这边测试,上面的例程删了read里的NOP改为while会HID识别失败。  详情 回复 发表于 2026-1-17 20:14
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:483
  • 最近打卡:2026-03-23 08:55:58
已绑定手机

104

主题

4195

回帖

9307

积分

荣誉版主

无情的代码机器

积分
9307
发表于 2026-1-17 20:14:43 | 显示全部楼层
templ*** 发表于 2026-1-17 19:59
usb_read_reg()函数按照原例程应该是可以的。原例程例在设置完add后,等待dat寄存器准备好后,才能读,这 ...

我这边测试,上面的例程删了read里的NOP改为while会HID识别失败。
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:156
  • 最近打卡:2026-03-23 08:54:25

25

主题

50

回帖

863

积分

高级会员

积分
863
发表于 2026-1-19 08:37:25 | 显示全部楼层
测试时加一些延时稳定点,会不会刚设置了USBADR,再去读会有问题,有可能USB模块内部还没有处理好。
USBADR和USBDAT这两个寄存器在设置后都稍微延时一下,感觉会稳妥一些。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:359
  • 最近打卡:2026-03-20 21:53:40

844

主题

1万

回帖

2万

积分

管理员

积分
22719
发表于 2026-1-22 20:48:20 | 显示全部楼层
裴工:
USB-CDC/HID,  CPU 可以 120MHz


截图202601222048113110.jpg
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-24 08:27 , Processed in 0.115304 second(s), 89 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表