使用avrdude让Atmega16A启用外部晶振
Atmega16A出厂默认配置的融丝位让其使用内部RC震荡电路,对于温度敏感的场合(比如超声波测距),自带的RC震荡电路的误差就会变大,因此有必要使用外部晶振。
通过在网上搜索到的资料,这里记录下我现在的做法,方便以后回忆。
首先焊好最小系统后,连接上ISP,然后在命令行下进入avrdude的shell模式:
[lexchou@localhost avr-test]$ sudo avrdude -P usb -pm16 -c usbasp -t
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9403
avrdude>
命令part可以得到当前MCU的详细信息,这里我的Atmega16A的结果:
avrdude> part
>>> part
AVR Part : ATMEGA16
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PA0
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 4 10 128 0 no 512 4 0 9000 9000 0xff 0xff
flash 33 6 128 0 yes 16384 128 128 4500 4500 0xff 0xff
lock 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
lfuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
calibration 0 0 0 0 no 4 0 0 0 0 0x00 0x00
其中hfuse和lfuse分别为融丝位的高字节和低字节,具体的定义为:
<td>
位号
</td>
<td>
描述
</td>
<td>
默认值
</td>
<td>
7
</td>
<td>
使能 OCD
</td>
<td>
1 ( 未编程, OCD 禁用 )
</td>
<td>
6
</td>
<td>
使能 JTAG
</td>
<td>
0 ( 编程, JTAG 使能 )
</td>
<td>
5
</td>
<td>
使能串行程序和数据下载
</td>
<td>
0 ( 被编程, SPI 编程使能 )
</td>
<td>
4
</td>
<td>
振荡器选项
</td>
<td>
1 ( 未编程 )
</td>
<td>
3
</td>
<td>
执行芯片擦除时 EEPROM 的内
</td>
<td>
1 ( 未被编程 ),EEPROM 内容不保留
</td>
<td>
2
</td>
<td>
选择 Boot 区大小
</td>
<td>
0 ( 被编程 )
</td>
<td>
1
</td>
<td>
选择 Boot 区大小
</td>
<td>
0 ( 被编程 )
</td>
<td>
0
</td>
<td>
选择复位向量
</td>
<td>
1 ( 未被编程 )
</td>
<td>
位号
</td>
<td>
描述
</td>
<td>
默认值
</td>
<td>
7
</td>
<td>
BOD 触发电平
</td>
<td>
1 ( 未被编程 )
</td>
<td>
6
</td>
<td>
BOD 使能
</td>
<td>
1 ( 未被编程, BOD 禁用 )
</td>
<td>
5
</td>
<td>
选择启动时间
</td>
<td>
1 ( 未被编程 )
</td>
<td>
4
</td>
<td>
选择启动时间
</td>
<td>
0 ( 被编程 )
</td>
<td>
3
</td>
<td>
选择时钟源
</td>
<td>
0 ( 被编程 )
</td>
<td>
2
</td>
<td>
选择时钟源
</td>
<td>
0 ( 被编程 )
</td>
<td>
1
</td>
<td>
选择时钟源
</td>
<td>
0 ( 被编程 )
</td>
<td>
</td>
<td>
选择时钟源
</td>
<td>
1 ( 未被编程 )
</td>
要配置使用外部晶振,就得改lfuse的CKSEL0~CKSEL3了,文档中这么定义的:
<td>
CKSEL3..0
</td>
<td>
1111 – 1010
</td>
<td>
1001
</td>
<td>
1000 – 0101
</td>
<td>
0100 – 0001
</td>
<td>
0000
</td>
看看这个新的MCU的lfuse值是多少:
avrdude> d lfuse
>>> d lfuse
0000 e1 |. |
为了让MCU使用外部晶振,需要将低4位设置为1111,使用w命令:
avrdude> w lfuse 0 0xef
>>> w lfuse 0 0xef
然后就可以用了。
Last modified on 2013-06-06