【问题标题】:Attiny13 Clock frequency and ADCAttiny13 时钟频率和 ADC
【发布时间】:2016-07-03 20:55:58
【问题描述】:

我正在使用 Attiny13 AVR,它由 arduino UNO 通过 SPI 编程。

我找到了attiny13的一个core,boards.txt文件内容如下;

#attiny13.name=Attiny13 @ 128 KHz (internal watchdog oscillator)

#attiny13.upload.using=arduino:arduinoisp
# attiny13.upload.protocol=avrispv2
# attiny2313at1.upload.using=pololu

#attiny13.upload.maximum_size=1024
#attiny13.upload.speed=250 # important for not losing connection to a slow processor

#attiny13.bootloader.low_fuses=0x7B
#attiny13.bootloader.high_fuses=0xFF

#attiny13.bootloader.unlock_bits=0x3F
#attiny13.bootloader.lock_bits=0x3F

#attiny13.build.mcu=attiny13
#attiny13.build.f_cpu=128000
#attiny13.build.core=core13
########################

attiny13e.name=Attiny 13A standalone 9.6Mhz
attiny13e.upload.using=arduino:arduinoisp
attiny13e.upload.maximum_size=1024
attiny13e.upload.speed=19200
attiny13e.maximum_data_size=64
attiny13e.bootloader.low_fuses=0x7A
attiny13e.bootloader.high_fuses=0xFF
attiny13e.bootloader.path=empty
attiny13e.bootloader.file=empty
attiny13e.bootloader.unlock_bits=0xFF
attiny13e.bootloader.lock_bits=0xFF
attiny13e.build.mcu=attiny13
attiny13e.upload.tool=avrdude
attiny13e.build.f_cpu=9600000L
attiny13e.build.core=core13

当我对 attiny13 进行编程时,我选择“Attiny 13A Standalone 9.6Mhz”作为目标板。

所以,我希望它以 9.6Mhz 运行。

我将 TCCR0B 寄存器设置如下以获得“无预分频”

TCCR0B |= _BV(CS00);
TCCR0B &= ~_BV(CS01);
TCCR0B &= ~_BV(CS02);

还可以通过更改 TCCR0A 寄存器将 PWM 模式设置为“Fast PWM”。

TCCR0A |= _BV(WGM00);
TCCR0A |= _BV(WGM01);
TCCR0A &= ~_BV(WGM02);

通过这些设置,我应该得到 9.6Mhz/256 = 37.5 Khz PWM 频率。但是,当我将 PWM 的输出连接到用于驱动和 LED 灯条的 MOSFET 时,我会听到 MOSFET 发出的嗡嗡声。

这促使我认为我的时钟不是以 9.6Mhz 运行,因为 37.5Khz 不是可听频率。

于是,我又快速搜索了时钟频率的话题,找到了以下网页;

https://www.avrprogrammers.com/howto/sysclk-prescaler

如果我没记错的话,这个页面说我的时钟频率默认是8分频的。

为了不能得到除数,我需要重置所有位。

我这样做并重置了所有 CLKPS 位。

CLKPR = (1<<CLKPCE);
CLKPR = (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);

所以,理论上,我应该得到 9.6Mhz 时钟频率,除数为 1。

当我使用上述所有设置时,我不再听到嗡嗡声。

不过,这次又出现了一个问题。

我使用电位器来控制亮度。将时钟除数设置为“1”时,电位器的行为发生了变化。当我转动电位器时,模拟输入没有立即读取值,所以我需要再转动一点以获得最小亮度,并在到达电位器的另一端之前达到最大亮度。所以,我认为 ADC 有问题。

在模数转换器标题下,我找到了以下信息;

默认情况下,逐次逼近电路需要输入 时钟频率在 50 kHz 和 200 kHz 之间以获得最大分辨率。 如果需要低于 10 位的分辨率,则输入时钟 ADC 的频率可以高于 200 kHz 以获得更高的样本 率。

所以,我的时钟频率是 9.6Mhz,我需要为 ADCSRA 寄存器设置一个介于 9.6Mhz/20Khz= 48 和 9.6Mhz/50Khz = 192 之间的预分频器。 我选择了128的分频系数,需要设置ADPS2、ADPS1和ADPS0这三个位。

ADCSRA != 1<< ADPS2;
ADCSRA != 1<< ADPS1;
ADCSRA != 1<< ADPS0;

这应该设置所有三个位并将 ADC 的频率保持在 50Khz - 200Khz 之间。

但是,电位器的行为仍然相同。

我哪里错了?

【问题讨论】:

  • 昨天我在设置上工作了一点,我意识到问题可能与我正在写入 PWM 的占空比有关。例如,当我通过模拟写入(输出,5)命令将“5”值写入 PWM 时,LED 根本不发光。同样,我达到了最大亮度,例如,“200”左右的值。因此,我可能正确地读取了电位器,而由于时钟速度的变化,PWM 在某种程度上具有不同的范围。这些值不是确切的值,我只是举例说明情况。那么,有什么想法可能是 PWM 的问题吗?

标签: microcontroller clock avr adc attiny


【解决方案1】:
ADCSRA != 1<< ADPS2;
ADCSRA != 1<< ADPS1;
ADCSRA != 1<< ADPS0;

是三个没有效果的空语句。 (他们每个都返回一个布尔结果。)你的意思是写

ADCSRA |= 1<< ADPS2;
ADCSRA |= 1<< ADPS1;
ADCSRA |= 1<< ADPS0;

ADCSRA |= 1<< ADPS2 | 1<< ADPS1 | 1<< ADPS0;

【讨论】:

  • 是的,我是说第二个,抱歉。
猜你喜欢
  • 2020-04-28
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 2010-10-15
  • 1970-01-01
  • 2019-02-09
  • 1970-01-01
  • 2014-10-09
相关资源
最近更新 更多