qq_23727547 2020-10-16 19:06 采纳率: 0%
浏览 147

OV7670像素时钟按照寄存器配置与实际测试时钟不一致

与像素时钟相关的寄存器:
图片说明
图片说明

上面两个寄存器配置内部时钟频率CLKRC与XCLK(外部输入时钟)
F(clkrc)=f(xclk)*PLL/(bit[5:0]+1)
图片说明
图片说明

实际存在的问题:

当如下配置时(输入时钟12M有源晶振):

 {0x11, 0x81},//时钟分频设置,1
 {0x6b, 0x40},//PLL*4=48Mhz 

{0x3e, 0x00},//10

 {0x73, 0x00},//

    按照使用手册寄存器配置,实际的像素时钟f=12M*4/(1+1)=24M,但实际示波器测量为12M。

继续,修改如下:

 {0x11, 0x80},//时钟分频设置,0
 {0x6b, 0x0a},//PLL*1
{0x3e, 0x00},//10

 {0x73, 0x00},//

    按照使用手册寄存器配置,实际的像素时钟f=12M*1/(0+1)=12M,但实际示波器测量为6M。

继续修改如下:
 {0x11, 0x00},//时钟分频设置,0
 {0x6b, 0x0a},//PLL*1

{0x3e, 0x00},//10

{0x73, 0x00},//

按照使用手册寄存器配置,实际的像素时钟f=12M*1/(0+1)=12M,但实际示波器测量为3M。

继续修改如下:

 {0x11, 0x00},//时钟分频设置,0
 {0x6b, 0x00},//PLL*1

{0x3e, 0x00},//10

 {0x73, 0x00},//

按照使用手册寄存器配置,实际的像素时钟f=12M*1/(0+1)=12M,但实际示波器测量为3M。

图片说明

因此有两个疑问:

1,0x11的最高位为预留位,为何改变此处的值会改变像素时钟?
2,为何按照手册配置,实际像素时钟是配置的1/2

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-07-25 03:27
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    在C语言中,你提到的{0x11, 0x81}{0x11, 0x80}都代表了相同的CLKRC寄存器地址。这两个寄存器都是用来配置像素时钟的,它们的作用是控制内核时钟的分频和预分频系数。

    对于CLKRC寄存器,其默认值为80,这意味着它的最大可能值为11111。然而,由于它是一个16位寄存器,所以它的范围只能从0000011111。这意味着,如果要改变这个寄存器的值,你需要将最高位设为1。例如,如果你想要设置像素时钟为24M Hz,那么你应该将最高位设置为1,然后用剩余的低八位来表示其他部分的分频因子。

    至于为什么按照手册配置的实际像素时钟是配置的1/2,这可能是因为在使用手册中,你可以看到CLKRC寄存器的分频因子是从1开始的,而CLKRC寄存器的值实际上是在初始化时就固定好的。也就是说,在初始化阶段,所有的分频因子都被设定好了,并且在之后的操作中,这些分频因子被用于计算像素时钟的频率。这样做的目的是为了简化初始化过程,避免频繁更改分频因子。

    至于你的第二个问题,关于0x11的最高位为预留位的问题,这并不是一个正确的解释。CLKRC寄存器中的最高位通常并不需要进行任何特殊处理,除非有特定的要求或者硬件设计上的考虑。在这种情况下,最高位可能是留空的,但这并不能直接导致像素时钟的改变。

    总的来说,CLKRC寄存器是用来配置内核时钟的,其值是由初始化程序决定的,而不是由用户通过编程方式改变的。

    评论

报告相同问题?