bozai 发表于 2012-5-27 20:18:26

LGT内部RC精准度问题【已解决】

本帖最后由 bozai 于 2012-5-28 07:47 编辑

--------------------------------------------------------------------------------------------------
需要使用ISP读出配置值,然后把熔丝配置使能选上 再写入即可。

没有勾选熔丝配置使能时写入任何值都没有效果。

或者在code里写OSCCAL值为0x6 或者0x0A (具体要看出厂校验值) 也可以
--------------------------------------------------------------------------------------------------


准备DIY个东西,看到LGT拥有1%精度的内部RC,打算不使用晶振。

测试UART发现57600波特率PC收没问题,LGT收到的是乱码。换9600,两边全是乱码。
于是写了个程序测翻转IO,用频率计测频率,用来间接测量RC频率。 程序很简单 优化等级-Os
#include "iolgt8f0xa.h"
#include <avr/io.h>

#define LED_DDR                DDRA
#define LED_PORT        PORTA
#define LED_BIT                PA5
#define LED_ON                LED_PORT &= ~(1<<LED_BIT)
#define LED_OFF                LED_PORT |= (1<<LED_BIT)

int main(void)
{
        PMCR |= _BV(CFDS);

        CLKPR = _BV(CLKPCE);
        CLKPR = _BV(CLKPCE); /* Set main clock to 16M */


        LED_DDR |= (1<<LED_BIT);


        while(1)
        {
                LED_ON;
                LED_OFF;
        }

        return 0;
}


反汇编后有三条指令。两条IO翻转的,一条跳转指令。因此是每次翻转需要3个时钟。
用示波器量低电平1个时钟周期,高电平2个时钟周期
用频率计测试发现频率为 4834KHz, 因此系统时钟是14.5M

又找来LGT的demo板测试,频率为4991KHz,约为15MHz

以为自己看错了datasheet,看到的不是精度,而是稳定度。
因此还特地用热风枪吹吹芯片,看看频率漂移如何是不是1%。
用200度的热风正对芯片吹20秒,频率由4991KHz 降到4962KHz。 稳定度的确小于1%。
但是后来仔细看看datasheet,写的的确是精度。

想到芯片可以自己微调,于是用ISP写入RC时钟校验值 (试验的这块默认读出来的值是06),(分别为00,,10,3f)发现没啥影响,都为4991KHz。
自己在code里调整OSCCAL值,发现写入最大值,频率是最小的。 约4940KHz,写0是最大的4992KHz.

由我的试验看LGT的精度并没有1% (稳定性还是不错的), 不知道是不是因为这一批芯片是工程样片的原因。
还是我code 写的有问题。 请帮忙分析一下,谢谢!

niba 发表于 2012-5-27 20:53:14

稳定性有1%,不错呀

sync765 发表于 2012-5-27 21:50:27

楼主的实验好仔细
不懂支持下

淋湿的鸡毛 发表于 2012-5-27 22:22:08

不懂 ~~帮顶

neutronlmk 发表于 2012-5-27 22:36:40

还没用上LGT,也没有下载到详细的规格书。
据我的经验是选择<=8M的内部时钟才有1%精度,台系芯片大都选择<=4M的内部时钟有3%精度。
lZ选择的内部时钟可能太高了,想想目标芯片的时钟远高于 ISP的时钟,ISP如何能给目标芯片校准?

lxvtag 发表于 2012-5-27 22:40:19

还没做过多少测试,关注。

huayuliang 发表于 2012-5-27 22:46:43

俺用默认的设置,115200 全正常。

aozima 发表于 2012-5-27 23:18:32

while(1)
{
   LED_ON;
   LED_OFF;
}这样是不准的,while(1)
{
   LED_ON;
   LED_OFF;
   LED_ON;
   LED_OFF;
   LED_ON;
   LED_OFF;
   LED_ON;
   LED_OFF;
   LED_ON;
   LED_OFF;
   LED_ON;
   LED_OFF;
   LED_ON;
   LED_OFF;
   LED_ON;
   LED_OFF;
}这样就准多了,至少,除头尾都是准的。

logicgreen 发表于 2012-5-28 00:31:33

我测试过很多,大多把OSCCAL设为$0A或$06都是16Mhz+-1%。

rifjft 发表于 2012-5-28 00:36:32

16Mhz+-1% ,那看来还不错

bozai 发表于 2012-5-28 07:20:45

neutronlmk 发表于 2012-5-27 22:36 static/image/common/back.gif
还没用上LGT,也没有下载到详细的规格书。
据我的经验是选择

谢谢! LGT只有一个16M的

bozai 发表于 2012-5-28 07:21:17

aozima 发表于 2012-5-27 23:18 static/image/common/back.gif
这样是不准的,这样就准多了,至少,除头尾都是准的。

这样子测IO翻转频率不错

bozai 发表于 2012-5-28 07:30:01

logicgreen 发表于 2012-5-28 00:31 static/image/common/back.gif
我测试过很多,大多把OSCCAL设为$0A或$06都是16Mhz+-1%。

听了你的建议, 我把两块板子在code里设置成06 或者0A,的确频率上来了,一个是5283KHz,一个是5315KHz, 这样子的确是1%的精度。
另外通过ISP 写入06 或者0A时 要把 “熔丝配置使能位”选上,然后就能配置成功。

另外问个问题,我一直以为芯片出厂时已经校准好的。直接就能用,不需要ISP读出来校准值,然后配置熔丝使能位再写进去才可以。请问芯片使用前是需要这样操作吗?

fsclub 发表于 2012-5-28 09:10:55

看来不错呢?~~

logicgreen 发表于 2012-5-28 10:01:28

bozai 发表于 2012-5-28 07:30 static/image/common/back.gif
听了你的建议, 我把两块板子在code里设置成06 或者0A,的确频率上来了,一个是5283KHz,一个是5315KHz,...

我们测试的时候会校正RC16Mhz的,不过不知道你那片肿么没有了?ISP工具可以删除配置数据的!

bozai 发表于 2012-5-28 10:19:50

logicgreen 发表于 2012-5-28 10:01 static/image/common/back.gif
我们测试的时候会校正RC16Mhz的,不过不知道你那片肿么没有了?ISP工具可以删除配置数据的! ...

两片都这样的,所以有可能是被我误删了?
可是我刚开始发现问题的那个芯片是第一次使用,只是烧了个flash,后来发现问题后才尝试去动熔丝的。
另一块是在demo板上的,有可能被设置过熔丝。不过没有选过“熔丝配置使能”为允许。 所以按我得实验这样不会改变时钟值的。

下次再用新的芯片试试。

hyg2012 发表于 2012-5-28 12:53:15

我的片子也是一样,刚开始用频率正常,串口波特率正常。烧写几次后就不对了,我用的是jtag调试,不知道jtag可不可以修改。

bozai 发表于 2012-5-28 18:25:12

hyg2012 发表于 2012-5-28 12:53 static/image/common/back.gif
我的片子也是一样,刚开始用频率正常,串口波特率正常。烧写几次后就不对了,我用的是jtag调试,不知道jtag ...

我发现以下情况会导致丢失配置

Code里面对OSCCAL进行了配置,比如写入0x1f
并且 ISP 没有使能 “熔丝配置使能”

这样就会乱掉。 单纯烧flash (代码中没有对OSCCAL赋值的语句)不会导致配置丢失。自己试过30次没发现问题。

bozai 发表于 2012-5-28 21:19:56

logicgreen 发表于 2012-5-28 10:01 static/image/common/back.gif
我们测试的时候会校正RC16Mhz的,不过不知道你那片肿么没有了?ISP工具可以删除配置数据的! ...

晚上又做了一次实验。拿一片全新的芯片。 只用ISP烧flash,不操作熔丝位。 结果出来的频率是5010KHz。

程序见附件,只是简单的翻转IO (输出到PA5),简单的连一个变量都没有。 具体可看压缩包内的lss文件。
能帮忙检查一下么?

millwood0 发表于 2012-5-28 21:35:36

#define LED_ON                LED_PORT &= ~(1<<LED_BIT)
...
                LED_ON;
                LED_OFF;
use this instead:
#define LED_FLP(bit)                LED_PORT ^= (1<<(bit))
...
                LED_FLP(RA5);
you will need to see the assembly listing to see how many instructions / cycles for each loop.

millwood0 发表于 2012-5-28 21:46:00

for comparison, a usb1286 running at 16Mhz produces 143khz waveform in gcc-avr release mode and 74khz waveform in debug mode.

bozai 发表于 2012-5-28 22:12:37

millwood0 发表于 2012-5-28 21:35 static/image/common/back.gif
use this instead:you will need to see the assembly listing to see how many instructions / cycles for ...

It uses 4 cycles to toggle an IO with your method. The frequency is about 1.87MHz (frc=15MHz).                LED_FLP(PA5);
aa:        90 e2               ldi        r25, 0x20        ; 32
ac:        82 b1               in        r24, 0x02        ; 2
ae:        89 27               eor        r24, r25
b0:        82 b9               out        0x02, r24        ; 2
b2:        fc cf               rjmp        .-8              ; 0xac <main+0x18>While use “|=” and "&=" operand, the compiler is smart enough to translate it to "cbi" and "sbi" instuction. (but the duty cycle is not 50%, a nop is needed)                LED_ON;
aa:        15 98               cbi        0x02, 5        ; 2
                LED_OFF;
ac:        15 9a               sbi        0x02, 5        ; 2
ae:        fd cf               rjmp        .-6              ; 0xaa <main+0x16>

aozima 发表于 2012-5-28 22:24:05

bozai 发表于 2012-5-28 22:12 static/image/common/back.gif
It uses 4 cycles to toggle an IO with your method. The frequency is about 1.87MHz (frc=15MHz).Whil ...

几年少有露面,原来造小bozai去了呀。。

bozai 发表于 2012-5-28 22:37:42

aozima 发表于 2012-5-28 22:24 static/image/common/back.gif
几年少有露面,原来造小bozai去了呀。。

哈哈,是女儿。 等稳定了才有点小时间搞搞东西。
页: [1]
查看完整版本: LGT内部RC精准度问题【已解决】