智能小车45:最小系统(Atmega328p)怎么存数据?
最小系统(Atemga328p芯片)其实是可以存储数据的,在说存数据前先了解下这个芯片有哪些存储器。
1.Flash(32K Bytes)
就是我们的程序存放的地方,这个最大,但和我们电脑的硬盘有点区别就是程序运行时不可写,只能编程时一次烧录进去。Flash中包含了boot loader,这个后面再学。
2.SRAM(2K Bytes)
和电脑的内存差不多。不过这个前面的地址就是一些寄存器的地址,方便编程,如下图:
3.EEPROM(1K Bytes)
这个可以存数据,就是本文的主角。
先看一下试验所有器材和连线:
如图,一个芯片,一个数码管和一堆连线。另外就是与功能无关的面包板与zf009编程器。这个并不是一个标准的试验,因为芯片引脚的5v对数码管来讲电压太高了。但我为了减少线路的复杂度,就省去了电阻,这让我损失了一个led(中间那个横线)。最后会分析这个坏的led带来的问题。
这个试验方法是把数码管里显示的数字存到芯片的eeprom里,断电后下次还能从eeprom里读出断电前的数字。这样就能证明eeprom是可以永久存储的。显示的数字从0到等下,循环显示。
1.引入头文件、定义全局变量、主函数:
定义系统时钟为2M,使用片内振荡器。这个数字对不对我还不懂,只是我肉眼看着数管码的频率应该是正常的。table0是数码管显示的0、1、2、3对应数码管上的各个led的亮灭的二进制形式,转成了16进制。它怎么算出来的呢?
数码管的每段都是个二极管(led),那每段都需要个开关,我用Atemga328p的PB组寄存器(io端口)来控制它们。给每个led编上号,以便与PB寄存器对应。如下图:
根据上面的对应关系,可以画原理图:
2.显示数码管函数、eeprom的读写函数:
关于gpio对对DDRB与PORTB的操作已在前面说过。至于EEPROM的操作要看官方数据手册的第12章6节,它对EEPROM的地址寄存器、数据寄存器、控制寄存器有详细的介绍。我们的代码也官方一致,不过把变量直接写成了值。操作上EEPROM都是先设置地址寄存器,再设置数据寄存器,再设置控制寄存器来执行读/写操作。下图是官方例子:
本次实验还遇到了一个奇葩问题:数码管的共阳脚(3、8)不接电源也能亮。产生问题原因是我中间的那个LED二极管被反向击穿了,击穿的后果有两种,一种是开路,一种是短路。而我的被搞成了短路,这样如果其它的引脚为0,对应的led就通电亮了。最后看下试验结果,这本来是显示3的状态,但中间的led坏了。断电后,数码管继续从3开始往后走,就是因为代码里把数据存进了eeprom。