马伟力AVR笔记:九、基于AT24C16的数据存储实验
《单片机原理与应用》课程设计基于atmega16实现的电压和温度的采集及液晶显示系统
课程设计任务书学生姓名:专业班级:自动化0501班指导教师:工作单位:自动化学院题目: 电压和温度的采集及液晶显示要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)系统能够测量环境温度,测量范围0-100摄氏度。
(2)系统能够测量给定电压,测量范围0-5V。
(3)电压测量精确到0.01伏,温度测量精确到0.1摄氏度。
(4)具有液晶实时显示当前电压及温度的功能。
时间安排:指导教师签名:年月日系主任(或责任教师)签名:年月日目录摘要 (3)1. 硬件选择及各模块组成 (4)1.1设计原理 (4)1.2器件选择及基本原理 (4)1.2.1 模数转换模块 (5)1.2.2 ATmega16芯片模块....................... 错误!未定义书签。
1.2.3 DS18B20模块 (6)1.2.4 液晶显示器模块 (7)2各模块实现方法说明及整体电路图 (9)2.1 温度采集.................................... 错误!未定义书签。
2.2 电压采集 (9)2.3液晶中文显示 (10)2.4整体电路图 (10)3.软件设计 (11)3.1程序设计流程图 (11)3.2源程序 (11)4 仿真调试结果 (12)总结 (13)参考文献: (14)附录1 (15)主程序源程序: (15)显示驱动程序源程序: (22)摘要此次课程设计是基于ATmega16实现的电压和温度的采集及液晶显示系统。
该系统主要包括控制器、温度传感器、外部参考电压及测试电压、液晶显示器几个硬件部分。
控制器采用的8位AVR系列单片机-ATmega16,有高性能、低功耗等优点,电压采集是通过单片机内部的数模转换器实现的;温度传感器则采用DS18B20实现,该传感器有低功耗单总线控制的特点,显示部分采用控制芯片为KS0108的12864液晶显示器,通过单片机的I/O口直接驱动。
《AVR单片机应用技术项目化教程》读书笔记模板
7.2.1 SPI总线概述 7.2.2 ATmega16的SPI接口
任务8.1 PGA2310原 理
任务8.2红外遥控原 理
任务8.3软件设计 任务8.4测试与结论
8.1.1引脚功能 8.1.2内部结构 8.1.3串行通信口 8.1.4 PGA2310功能
8.2.1红外编码传输 8.2.2红外接收解码 8.2.3系统原理图
AVR单片机应用技术项目化教 程
读书笔记模板
01 思维导图
03 目录分析 05 精彩摘录
目录
02 内容摘要 04 读书笔记 06 作者介绍
思维导图
本书关键字分析思维导图
技术
转换器
设计
原理
总结
项目
工作
单片
单片
数字 任务
训练项目
机
单片
程序
项目
功能
原理
器
内容摘要
本书以“项目”为载体,以任务为驱动,并借助Proteus仿真调试手段,在编写过程中力求便于实现“教、 学、做”一体化教学。全书设计有广告灯、数字时钟、频率计、电压表、差分转换器、双机串行通信、万年历、 红外遥控音量控制器、数字调谐收音机等15个项目,内容涉及单片机编程基础、I/O口原理与操作、人机交互接 口、定时/计数器、PWM调制、A/D-D/A转换器、串行通信口、SPI/IIC总线接口等,介绍单片机基础知识、AVR单 片机内核结构和应用,系统阐述了ATmega16单片机的原理、结构与应用。
1
任务9.1单芯 片FM接收
任务9.2
2
TEA5767 PLL
频率合成
3 任务9.3
TEA5767编程 操作
4
任务9.4 FM调 频接收设计
AVR学习笔记四、定时计数器1实验
A VR学习笔记四、定时/记数器1实验-------基于LT_Mini_M164.1 定时/计数器1的计数实验4.1.1 实例功能ATmega16的T/C1是一个16位的多功能定时计数器,其主要特点有:●真正的16位设计,允许16位的PWM。
● 2个独立的输出比较匹配单元。
●双缓冲输出比较寄存器。
●一个输入捕捉单元。
●输入捕捉躁声抑制。
●比较匹配时清零计数器(自动重装特性,Auto Reload)。
●可产生无输出抖动(glitch-free)的,相位可调的脉宽调制(PWM)信号输出。
●周期可调的PWM波形输出。
●频率发生器。
●外部事件计数器。
●带10位的时钟预分频器。
● 4个独立的中断源(TOV1、OCF1A、OCF1B、ICF1)。
在前面的实例中,我们已经学习了AVR单片机的定时/计数器0,本实例和下一个我们学习定时/计数器1,从上面的介绍我们可以看出,ATmega16单片机的定时/计数器1功能更为强大,值得我们深入学习。
定时/计数器的基本功能都是定时、计数等,掌握了一个定时/计数器的用法就能很容易的掌握其他定时/计数器的用法,所以我们不在学习定时/计数器1的定时、计数等基本功能。
在接下来的两个实例中,我们将学习定时/计数器1的增强功能。
在本实例中,我们利用ATmega16单片机的定时/计数器1的输入捕捉功能实现对按键时间的捕捉,并检测两次按键之间的时间间隔,然后通过LED指示实例运行效果。
本实例共有3个功能模块,分别描述如下:●单片机系统:使用定时/计数器1的输入捕捉功能检测按键的按下,并判断两次按键按下的时间间隔,然后通过LED灯的亮灭指示按键按下次数。
●外围电路:按键检测电路以及显示运行结果的LED显示电路。
●软件程序:熟悉掌握ATmega16单片机的定时/计数器1的输入捕捉中断程序的编写。
3.1.2、器件和原理本实例首先介绍ATmega16单片机的定时/计数器1的输入捕捉功能,然后详细介绍如何利用定时/计数器1实现对外部事件进行输入捕捉。
铁电存储器FM24C16原理及其综合应用
铁电存储器FM24C16原理及其综合应用Ramtron铁电存储器FRAM1、铁电存储器技术原理、特性及应用美国Ramtron公司铁电存储器(FRAM)的核心技术是铁电晶体材料。
这一特殊材料使铁电存储器同时拥有随机存取记忆体(RAM)和非易失性存储器的特性。
铁电晶体的工作原理是:当在铁电晶体材料上加入电场,晶体中的中心原子会沿着电场方向运动,达到稳定状态。
晶体中的每个自由浮动的中心原子只有2个稳定状态,一个记为逻辑中的0,另一个记为1。
中心原子能在常温、没有电场的情况下,停留在此状态达100年以上。
铁电存储器不需要定时刷新,能在断电情况下保存数据。
由于整个物理过程中没有任何原子碰撞,铁电存储器有高速读写、超低功耗和无限次写入等特性。
铁电存储器和E2PROM比较起来,主要有以下优点:(1)FRAM可以以总线速度写入数据,而且在写入后不需要任何延时等待,而E2PROM在写入后一般要5~10ms的等待数据写入时间;(2)FRAM有近乎无限次写入寿命。
一般E2PROM的寿命在十万到一百万次写人时,而新一代的铁电存储器已经达到一亿个亿次的写入寿命。
(3)E2PROM的慢速和大电流写入使其需要高出FRAM 2 500倍的能量去写入每个字节。
由于FRAM有以上优点,其特别适合于那些对数据采集、写入时间要求很高的场合,而不会出现数据丢失,其可靠的存储能力也让我们可以放心的把一些重要资料存储于其中,其近乎无限次写入的使用寿命,使得他很适合担当重要系统里的暂存记忆体,用来在于系统之间传输各种数据,供各个子系统频繁读写。
从FRAM问世以来,凭借其各种优点,已经被广泛应用于仪器仪表、航空航天、工业控制系统、网络设备、自动取款机等。
在设计的碳控仪系统中,由于对控制碳势适时性的要求较高,而且系统由2个子系统构成,每个子系统都要频繁读写存储器,所以我们把原来的X25045换成FM24C16以满足要求。
2 FM24C16引脚说明及工作过程FM24C16-P(8脚双列直插)外形图及引脚定义如图1及表1所示。
计算机组成原理存储器实验报告
计算机组成原理存储器实验报告一、实验目的本次实验的目的是通过实际操作,了解存储器的组成和工作原理,掌握存储器的读写操作。
二、实验原理存储器是计算机中的重要组成部分,用于存储程序和数据。
存储器按照存储介质的不同可以分为内存和外存,按照存储方式的不同可以分为随机存储器(RAM)和只读存储器(ROM)等。
本次实验使用的是随机存储器,随机存储器是一种易失性存储器,数据在断电后会丢失。
随机存储器按照存储单元的位数可以分为8位、16位、32位等,按照存储单元的数量可以分为256×8、512×16、1024×32等。
随机存储器的读写操作是通过地址线和数据线来实现的。
读操作时,CPU将要读取的地址通过地址线发送给存储器,存储器将该地址对应的数据通过数据线返回给CPU。
写操作时,CPU将要写入的数据通过数据线发送给存储器,存储器将该数据写入到对应的地址中。
三、实验器材1. 存储器芯片:AT24C022. 单片机:STC89C523. 电源、示波器、万用表等四、实验步骤1. 连接电路将AT24C02存储器芯片和STC89C52单片机按照电路图连接好,连接好电源和示波器等设备。
2. 编写程序编写程序,实现对AT24C02存储器的读写操作。
程序中需要设置存储器的地址和数据,以及读写操作的指令。
3. 烧录程序将编写好的程序通过编程器烧录到STC89C52单片机中。
4. 运行程序将电源接通,运行程序,观察示波器上的信号波形,检查读写操作是否正确。
五、实验结果经过实验,我们成功地实现了对AT24C02存储器的读写操作。
通过示波器观察到了地址线和数据线的信号波形,证明了程序的正确性。
六、实验总结通过本次实验,我们深入了解了存储器的组成和工作原理,掌握了存储器的读写操作。
同时,我们也学会了如何编写程序并将程序烧录到单片机中。
这些知识对于我们深入学习计算机组成原理和嵌入式系统开发都具有重要的意义。
基于at24c01的存储电路设计与应用
基于at24c01的存储电路设计与应用AT24C01是一种串行EEPROM芯片,具有1K位的存储容量。
它主要用于存储少量的数据,并且支持通过I2C总线进行读写操作。
下面是基于AT24C01的存储电路设计与应用的步骤:1. 设计电路:首先确定使用AT24C01芯片的存储容量是否满足你的需求。
如果需要更大的容量,可以选择其他型号的EEPROM芯片。
然后根据AT24C01的数据手册,设计电路图,包括连接AT24C01芯片所需的电源、时钟、I2C总线接口等。
2. 布局和焊接:根据电路设计图,进行PCB布局设计,并进行焊接。
确保电路板上的元件连接正确、焊接牢固。
3. 电源供应:为AT24C01芯片提供适当的电源电压。
通常,AT24C01芯片的工作电压为2.7V至5.5V,可以根据实际需求选择合适的电源电压。
4. I2C总线连接:将AT24C01芯片的SDA和SCL引脚连接到主控制器的对应引脚。
确保连接正确,避免反向连接或短路。
5. 编程和读写数据:使用主控制器(如单片机或微处理器)通过I2C总线对AT24C01进行编程和读写操作。
根据AT24C01的数据手册,可以了解如何发送正确的命令和地址,以及如何读取和写入数据。
6. 测试和验证:完成电路连接和编程后,进行测试和验证。
可以使用示波器或逻辑分析仪监测信号波形,以确保数据的正确读写和传输。
7. 应用开发:根据具体应用需求,开发相应的软件程序或固件来控制AT24C01芯片的读写操作。
可以使用各种编程语言和开发工具进行开发。
需要注意的是,在设计和应用AT24C01存储电路时,要遵循数据手册中提供的规范和建议,以确保电路的可靠性和性能。
另外,还要考虑数据的保护和安全性,避免非授权访问和意外擦写数据。
AVR单片机嵌入式系统原理与应用实践——学习笔记上课讲义
A V R单片机嵌入式系统原理与应用实践——学习笔记AVR单片机嵌入式系统原理与应用实践学习笔记1.AVR单片机的基本结构1.1.单片机的基本组成1.1.1.单片机的基本组成结构单片机的基本组成单元➢CPU➢程序存储器➢数据存储器➢I/O接口CPU与各基本单元通过芯片内的内部总线连接。
一般情况下,内部总线中的数据总线宽度(或指CPU字长)也是单片机等级的一个重要指标。
内部总线:数据总线、地址总线、控制总线。
1.1.2.单片机的基本单元与作用1)MCU单元MCU单元部分包括CPU、时钟系统、复位、总线控制逻辑等电路。
➢CPU:➢时钟和复位电路:➢总线控制电路:2)片内存储器单片机的存储器一般分为程序存储器和数据存储器,它们往往构成互不相同的两个存储空间,分别寻址,互不干扰。
单片机的内部结构通常使用哈佛体系结构,在这种体系中采用分开的指令和数据总线以及分开的指令和数据空间,分别采用专用的总线与CPU交换,可以实现对程序和数据的同时访问,提高了CPU的执行速度和数据的吞吐量。
3)程序存储器程序存储器用于存放嵌入式系统的应用程序。
4)数据存储器单片机在片内集成的数据存储器一般有两类:随机存储器RAM、电可擦除存储器EEPROM。
➢随机存储器RAM:➢电可擦除存储器EEPROM5)输入输出端口➢并行总线I/O端口:➢通用数字I/O端口:➢片内功能单元的I/O端口:➢串行I/O通信口:➢其他专用接口:6)操作管理寄存器管理、协调、控制、操作单片机芯片中各功能单元的使用和运行。
1.2.ATmega16单片机的组成1.2.1.AVR单片机的内核结构“快速访问”意味着在一个周期内执行一个完整的ALU操作。
AVR的算术逻辑单元ALU支持寄存器之间、立即数与寄存器之间的算术与逻辑运算功能,以及单一寄存器操作。
每一次运算操作的结果将影响和改变状态寄存器(SREG)的值。
ALU操作➢从寄存器组中读取两个操作数➢将执行结果写回目的寄存器➢操作数被执行1.2.2.ATmega16的外部引脚与封装I/O引脚共32只,分成PA、PB、PC、PD4个8位端口,它们全部是可编程控制的多功能复用的I/O引脚。
铁电存储器FM24C16及其应用
2.学位论文 彭刚 PZT第一性原理计算及其铁电性能研究 2006
;发送第9个时钟,接收应 答信号
(下转第25页)
万方数据-壁翌丝茎型Fra bibliotek型重三竖二;旦竺.生笪!塑 .一
图4频率测量软件框图 /*定义计数器1输出为1kHz*/ outportb(BASE8254+12,0X00)5 )
main() { Init 8254(); clrscr(); if(kbhit()!一0)
本文介绍的铁电存储器,由于其独特的数据存 储方式,可以较好地解决上述非易失性数据保存过 程中遇到的难题。
概述
铁电存储技术早在1921年提出,但直到1993 年美国Ramtron公司才成功开发出第一个4K位的 铁电存储器(FRAM)产品。目前所有的FRAM产 品均由Ramtron公司制造或授权。最近几年 FRAM又有新的发展,采用了o.35“m工艺,推出 了3V产品,开发出“单管单容”存储单元的FRAM, 最大密度可达256K位。
目前Ramtron公司的FRAM主要包括两大 类:串行FRAM和并行FRAM。其中又分12C两 线方式的FM24xx系列和SPI三线方式的FM25xx 系列。串行FRAM与传统的24xx、25xx型的EE— PROM引脚及时序兼容,可以直接替换,如Micro— chip、xicor公司的同型号产品。但各项性能要好得 多,性能比较如表1所示。
FM24C16遵守12 C总线协议,在没有数据传输
万方数据
国外电子测量技术·2004年第6期
设计与应用
表1 串行FRAM和EEPROM性能比较(16K位存储器,访问速度400kHz)
供应商
Ramtron Annel sT
型号 FM24C16 AT24C16 ST24C16
AVR学习笔记移植笔记_1
林夕依然ATmega16学习笔记例程移植到Atmel Studio 6.2笔记相信你已经有了一定的C语言及数字电路基础,以及能定下心来,决心学点东西。
如果做不到的话,麻烦您把我轻轻的放开,该干啥干啥去。
前言最近学习A VR,网上找了N多资料后,发现就算林夕依然ATmega16学习笔记最合俺的心意。
优点如下:1、不讲原理,直接操作,适合俺这种不愿背书的差生。
2、每个例程都附有源程序及PROTEUS仿真文件,省了买零件的金钱及焊板的时间。
缺点当然也有:1、太省事了,初学者容易只跑跑例程,不求甚解(这也是市售所有学习板的通病)。
2、基于ICCA VR,而不是最新的AtmelStudio。
3、理论知识太少(也算是优点)。
还有一条就是这玩意是用EXE文件打包的,初次下载时,我不敢打开,生怕会给我强装软件或者开个后门什么的。
后来在网上下载了一个开发板的附带光盘文件,发现里面也带着这玩意。
心想这里面不该会有问题呀,才不是太放心的打开,打开后发现相见恨晚呀!好吧,先把这些例程一个一个琢磨完吧。
不过看程序时发现想打瞌睡,也难怪,看这玩意也太没挑战性了。
既然我的电脑中装了AtmelStudio,即然ICCA VR迟早要过时,不如把这里面的例程移植到AtmelStudio中吧!顺便也可以学习一下编程。
笔记不妨公开,俺也好刷一点成在感。
本文中所有例程均在AtmelStudio6.2+Proteus7.8中调试通过。
本文是我个人学习时的笔记,希望后来者能少走一点弯路。
学习MCU的惟一捷径是多读例程,多写程序,别无他法。
林夕依然ATmega16学习笔记下载链结如下:链接:密码:mzah实验1:8种LED点亮模式1、移植到AtmelStudio中的步骤打开Atmel Studio 6.2,新建一个项目。
不知道啥意思,我选第二个后,在下面起好项目名称及选好项目目录后OK。
这个好办,按CPU型号选就好了。
终于进入编辑窗口了。
一言蔽之,提取包中所有.c(C源码)、.h(C头文件)、.dsn(PROTEUS仿真文件)文件。
AVRATmega16实验教程
A VR学习笔记(基于LT_Mini_M16)一、点亮发光二极管一、实验内容和目的本实验通过硬件电路和软件程序,利用ATMega16单片机来控制发光二极管的点亮和熄灭。
通过此实验初步掌握单片机的I/O口功能。
二、硬件电路1、电路分析(对照LT_Mini_M16原理图)1)电源电路:外接稳压直流电源(最好是DC9V)加到电路的U1处,经过电容C16稳压滤波后加到稳压模块AMS1117-5.0上,然后连接到电源开关按钮S1,从开关按钮出来后经过发光二极管D9和电阻R7,再经过电容C1、C2、C3、C4、C5、C7稳压滤波后加到单片机以及各个模块的电源端。
分析:a) 电容的作用是稳压滤波,其中C1、C2、C3、C4、C5这5电容为0.1PF (俗称104电容,一般为瓷片电容)。
主要作用为滤出电源电路中的高频成分;而C16、C7是电解电容,主要作用是稳压,即把电源电路中的尖峰电压拉低到正常电压水平;C16是稳定外接直流电源的电压(9V),C7是稳定AMS1117-5.0输出的5V电压。
b)稳压芯片采用ASM1117-5.0,该稳压芯片输入电压范围为6.5V-15V,输出电压稳定在5.0+0.1V,最大输出电流可达1A,可以满足一般电路需要。
c) 电源开关按钮S1的作用当然是接通和断开电源了。
在此电路中S1采用的是单刀双掷开关,一旦断开电源,则电源的正负极都断开了。
d)发光二极管D9的作用是指示电源是否连接成功,如果外部电源成功的连接上,则发光二极管发光指示电源连接成功;电阻R7的作用是对发光二极管进行限流,一般发光二极管只能通过10mA左右的电流,且发光二极管上面的压降只需要1.5V左右,加到发光二极管上面的电流如果超出额定值,则会烧毁。
而系统工作的电压是5V,如果全部加在发光二极管上,则发光二极管很容易就会被烧毁。
所以要在电源和发光二极管之间串接一个限流电阻。
该限流电阻阻值的计算:(VCC-发光二极管上的电压)/流过发光二极管的电流。
AVR单片机笔记
A VR单片机笔记说明:主要使用的编译环境为IAR,使用A VR的ATmega16 和128目录IO (2)时钟: (2)MCU控制寄存器-MCUCR (2)MCU控制和状态寄存器-MCUCSR (2)看门狗定时器控制寄存器-WDTCR (3)外部中断控制寄存器A -EICRA (4)外部中断控制寄存器B -EICRB (4)外部中断屏蔽寄存器-EIMSK (4)外部中断标志寄存器-EIFR (5)中断矢量表 (5)在IAR环境中AVR中断程序的格式 (6)定时器 (6)定时器/计数器0和2: (6)定时器/计数器1和3: (7)使用IAR调试注意事项 (7)IIC(TWI) (8)o8515.h头文件 (10)IOPort A-G:都含有内部上拉电阻数据:PORTA-G;方向DDRA-G;PINA-G 时钟:XTAL 分频控制寄存器-XDIVMCU控制寄存器-MCUCRMCU控制和状态寄存器-MCUCSR• Bit 4 – JTRF: JTAG 复位标志通过JTAG 指令A VR_RESET 可以使JTAG 复位寄存器置位,并引发MCU 复位,并使JTRF 置位。
上电复位将使其清零,也可以通过写”0” 来清除。
• Bit 3 – WDRF: 看门狗复位标志看门狗复位发生时置位。
上电复位将使其清零,也可以通过写”0” 来清除。
• Bit 2 – BORF: 掉电检测复位标志掉电检测复位发生时置位。
上电复位将使其清零,也可以通过写”0” 来清除。
• Bit 1 – EXTRF: 外部复位标志外部复位发生时置位。
上电复位将使其清零,也可以通过写”0” 来清除。
• Bit 0 – PORF: 上电复位标志上电复位发生时置位。
只能通过写”0” 来清除。
看门狗定时器控制寄存器-WDTCR• Bits 7..5 – Res: 保留保留位,读操作返回值为零。
• Bit 4 – WDCE: 看门狗修改使能清零WDE 时必须先置位WDCE,否则不能禁止看门狗。
AVR单片机ATMEGA161602液晶驱动程序及心得
AVR单片机ATMEGA16 1602液晶驱动程序及心得首先,祝福各位同仁,光棍节快乐!今天,给我最好的节日礼物就是,我自己研发的AVR微控制器芯片开发板,1602液晶屏实验成功!我很欣慰.写了一整天的程序,反复实验,最终在凌晨0点.终于成功了.在此过程中,最大的问题莫过于那个所谓配套的1602液晶屏数据手册!这个手册简直是误人子弟,里面资料写的很含糊.并且有错误,而导致我反复试验失败,最终,我使用了通用的1602液晶屏数据手册,才得以成功.我自制的AVR开发板尺寸和我买的51开发板差不多大小,ATmega16最小系统,8位数码管,蓝光流水灯,isp编程接口.过载保护保险丝,两个74hc573锁存器.1602液晶屏都已焊接完成,万用板是12X18cm的单孔玻纤板(质量不太好,便宜没好货).现在我才发现不够用,模块数量相同的两块实验板,手工焊接的一定要比机器印刷的大2~3倍才行.....没办法,我只能用5X7cm的万用板做小模块,ADC模块,DS1302时钟模块,激光二极管模块等等,然后用杜邦线把它们和AVR核心板链接起来,目前计划是这样的,往往计划很丰满,实际很骨感,伤脑筋啊,,,此次,首次接触了12864大液晶,能显示中文,和超声波测距传感器,这得好好研究一下,我一直想要了解一下2.4g无线传输模块,和陀螺仪传感器,还有GPS模块,不过那些还早,把AVRATMEGA16学的差不多了,再了解,也不迟. /*Program name: AVR ATMEGA16 1602驱动程序初次实验通过时间: 2013-11-11 00:04:01 ^_^ ;注意:在bysy()函数中严重出错!下次注意!while((PINA&0x80)==0x80); 此语句检测到PA7为零时终止循环;表明空闲状态心得:AVR单片机的IO口位操作比较复杂,由三个寄存器控制IO口的输出与输入;DDRn(输出/输入控制) 寄存器;PORTn(输出时控制数据,输入时控制内部上拉电阻)寄存器;PINn(用于读取IO口数据)寄存器;最终校验通过时间: 2013年11月12日15:12:28*/#include ;#include ;#define uint8 unsigned char#define uint16 unsigned int//========IO口位操作========================================void rs(uint8 h)//数据/指令选择操作;{if(h)PORTB|=1<<3; //置一;elsePORTB&=~(1<<3); //清零; }void rw(uint8 h)//读/写选择操作;{if(h==0){PORTB&=~(1<<4); //清零;}else{DDRA=0X00;PORTA=0XFF;PORTB|=1<<4; //置一;}}void e(uint8 h)//传输使能位;{if(h){PORTB|=1<<5;//置一;}elsePORTB&=~(1<<5);//清零;}//=============================================== =========void ddra(uint8 h)//PA口输入输出函数;{if(h){DDRA=0XFF;//输出模式;PORTA=0xff;}else{DDRA=0X00; PORTA=0XFF; } //输入模式并且有上拉; }void busy()//繁忙检测;{ddra(0);//设置PA口为输入,有上拉;do{e(0);//传输使能为0;rs(0);//指令;rw(1);//读;e(1);//e为高电平;}while((PINA&0x80)==0x80);//如果读到数据是01111111,表示空闲状态,跳出循环;e(0);ddra(1);//PA口输出状态;}void delay() //小延时;{uint8 j=0;j=1;}void w_cmd(uint8 cmd){busy();//繁忙检测通过时,PA口为输出状态,默认输出0xff; PORTA=cmd; //向PA口装载数据;rs(0);//指令;rw(0);//写入;e(1);//传输使能脉冲高;delay();//延时;e(0);//传输使能脉冲低;}void w_dat(uint8 dat){busy();//繁忙检测通过时,PA口为输出状态,默认输出0xff; PORTA=dat; //向PA口装载数据;rs(1);//数据;rw(0);//写入;e(1);//传输使能脉冲高;delay();//延时;e(0);//传输使能脉冲低;}void init_1602(){w_cmd(0x3c); //写入显示设置:8位数据,两行,5x10显示;w_cmd(0x0c); //整屏显示,光标不闪,字符不闪; w_cmd(0x06); //写入一个数据时地址自动加一.整屏不移动;w_cmd(0x01); //写入'清屏'指令;}void display(uint8 addr ,uint8 dat )//可在任意位置显示字符,{//addr地址,dat数据;w_cmd(addr);w_dat(dat);}void main(void)//====主函数================={uint8 i=0, j=0x80,ak[]="I'am ironman!"; //要显示的字符串"我是钢铁侠!"uint8 sj[]="2013-11-11 ^_^"; //今天的日期;uint16 s=0;//16位的变量;DDRB=0XFF;//PB口输出状态;PORTB=0X03; //PB0=1;PB1=1;DDRA=0XFF;//PA口输出状态;PORTA=0X00;//8个数码管共阴极为'0'.八位阳极为'0'; PORTB=0X00;//锁存数据;init_1602();//液晶屏初始化;w_cmd(0x81); //初始化完成以后先发送要写入的数据的显示位置.//0x81是第一行,第1位. 0x80是第0位;while(ak[i]!='\0') //将ak[]数组内的所有数据发送; {w_dat(ak[i++]);//每发送一个字节数据,数据的存储地址自动加一; for(s=0;s<50000;s++); //延时一下,字符会有一个,一个显示的效果;}w_cmd(0xc1);//发送第二排的数据地址,接下来字符会在第二排第1位开始显示;i=0;while(sj[i]!='\0')//将sj[]数组内的数据全部发完;{w_dat(sj[i++]);for(s=0;s<25000;s++);//效果延时;}while(1);//死亡循环; }。
AVR马老师讲义
第一章绪论单片机嵌入式系统的硬件基本构成可分成两大部分,单片微控制器芯片和外围的接口电路。
其中单片微控制器是构成单片机嵌入式系统的核心。
单片微控制器(Microcontroller)又称为单片微型计算机(Single-Chip Microcomputre 或One-Chip Microcomputre),我国普遍采用的名字为单片机(许多年以来,国内一直采用单片机的叫法,为了符合我国的实际情况,本书仍采用单片机的名称)。
它的外表通常只是一块大规模集成电路芯片,但在芯片中却集成了中央处理器(CPU)、存储器(种类有RAM、ROM、EPROM、E2PROM和FlashROM 等)、和各种输入/输出接口(定时器/计数器、并行I/O、串行I/O 以及A/D转换接口等)。
因此,一片芯片构成了一个基本的微型计算机系统。
由于单片机芯片的微小体积,极低的成本和面向控制的设计,使的它作为智能控制的核心器件被广泛地应用于嵌入到工业控制、智能仪器仪表、家用电器、电子通信产品等各个领域中的电子设备和电子产品中。
可以说,由单片机为核心构成的单片机嵌入式系统已成为现代电子系统中最重要的组成部分。
第一节单片机嵌入式系统基础知识1.1.1 嵌入式计算机系统计算机的出现首先是应用于数值计算。
随着计算机技术的不断发展,计算机的处理速度越来越快,存储容量越来越大,外围设备的性能越来越好,满足了高速数值计算和海量数据处理的需要,形成了高性能的通用计算机系统。
以往我们按照计算机的体系结构、运算速度、结构规模、适用领域,将其分为大型计算机、中型机、小型机和微型计算机,并以此来组织学科和产业分工,这种分类沿袭了约40年。
近20年来,随着计算机技术的迅速发展,以及计算机技术和产品对其它行业的广泛渗透,使得以应用为中心的分类方法变得更为切合实际。
具体的说,就是按计算机的嵌入式应用和非嵌入式应用将其分为嵌入式计算机系统和通用计算机系统。
通用计算机具有计算机的标准形态,通过装配不同的应用软件,以类同面目出现并应用在社会的各个方面,现在广泛普及应用的PC机就是其最典型的代表。
AVR学习笔记九、基于AT24C16的数据存储实验
Ema{@AVR学习笔记九、基于AT24C16的数据存储实验-------基于LT_Mini_M169.1 用I/O口模拟I2C总线实现AT24C16的读写9.1.1、实例功能I2C总线(Inter Integrate Circuit BUS)全称为芯片间总线,是Philips公司推出的一种双向二进制总线。
它在芯片间以两根连线实现全双工同步数据传送,一条数据线(SDA)和一条串行时钟线(SCL),可以很方便的构成外围器件扩展系统。
I2C总线协议允许总线介入多个期间,总线上的器件既可以作为主控制器也可以作为被控制器,既可以是发送器,也可以是接收器。
I2C总线在进行数据交换时,作为主控制器的器件需要通过总线竞争获得主控权,然后才可以启动数据传输。
系统中每个器件都具有唯一的芯片地址,数据传输时通过寻址可以确定数据接收方。
I2C总线自从出现以后,得到了广泛应用。
I2C总线结构简单,可靠性和抗干扰性好,可构成各种通用的硬件和软件模块。
方便重复利用,大大简化了系统的设计过程。
I2C总线的实现有两种方法:一、软件模拟I2C通信协议实现数据传输,二、利用硬件I2C接口实现数据传输。
ATmega16单片机集成了硬件I2C模块,称为TWI接口,TWI电路结构简单,只占用两个I/O口,可以实现多个器件共享一条总线,使用比较方便,系统也很简洁。
A VR单片机用硬件实现了这种总线的时序,省去了很多编程工作。
只要控制相关的寄存器,就可以实现通过TWI总线传输数据。
但是使用硬件I2C接口的缺点是接口固定,在特定的系统里面,会增加硬件和软件设计的复杂程度。
在本例中我们采用模拟I2C总线时序的方法实现I2C通信。
软件模拟I2C时序的方法增加了软件的复杂程度,但是方便了硬件设计,模拟I2C接口可以使用单片机的如何普通I/O口。
本节首先介绍I2C总线的的一些基本知识:特点、结构、原理、控制时序、与单片机的接口方法等。
最后通过一个实例实现模拟I2C接口。
数据存储AT24Cxx及其应用
I2C总线的信号类型
• 开始信号:SCL为高电平时,SDA由高电 平向低电平跳变,开始传送数据。 • 结束信号:SCL为高电平时,SDA由低电 平向高电平跳变,结束传送数据。
I2C总线的信号类型
• 位的传输 SDA 线上的数据必须在时钟的高电平周期 保持稳定,数据线的高或低电平状态只有 在SCL 线的时钟信号是低电平时才能改变。
读操作
• 读操作
立即/当前地址读操作 选择/随机地址读操作 顺序/连续地址读操作
立即/当前地址读多字节操作 选择/随机地址读多字节操作
立即/当前地址读操作
• 从器件地址计数器内容为最后操作字节的地址加1,也就是说如果上 次读/写的操作地址为N,则立即读的地址从地址N+1开始。 • 接收到从器件地址信号后(R/W位置1),它首先发送一个应答信号, 然后发送一个8 位字节数据;主器件不需发送一个应答信号但要产生 一个停止信号。 • 本次读取数据的地址是在上次读取数据的地址加1(可以不在同一页 面内,最后一页最后一个字节第一页第一个字节)
I2C总线接口EEPROM存储器
• 目前,市场上I2C总线接口器件有多种,利于A/D转换器、 D/A转换器、时钟芯片和存储器等。这里以典型的I2C总线 接口的存储器为例进行介绍。 • I2C总线接口EEPROM存储器是一种采用I2C总线接口的 串行总线存储器,这类存储器具有体积小、引脚少、功耗 低、工作电压范围宽等特点。目前,Atmel、Microchip、 National等公司均提供各种型号的I2C总线接口的串行 EEPROM(电可擦出可编程只读存储器,即Electrically Erasable Programmable Read-Only Memory)存储器。 在单片机系统中使用较多的EEPROM存储器是24系列串 行EEPROM。它具有型号多、容量大、支持I2C总线协议、 占用单片机I/O端口少、芯片扩展方便、读写简单等优点。
FM24C16A-AT24C16中文资料
地址到最后一个字节,地址计数器从7FFH翻转 到000H。与其它的非易失性存储器技术不同,
FRAM在本质上没有写延时。既然读写内存的 周期都是相同的,用户无须任何总线延时。整 个存取周期有时比一个总线周期还短,这样, 在一个写操作后,可以进行任何操作,包括写 操作或者读操作。 ”应答轮循 ”是EEPROM写操 作过程中用到的一个方法,它用来查询一个写 操作是否已经完成,对于FRAM来说,这是不 需要的,如果去查询,那么将总是返回一个已 完成信号。
l 硬件上可以直接替换EEPROM
描述
引脚定义
FM24C16A是用先进的铁电技术制造的16K位的
非易失性铁电随机存储器。FRAM具有非易失性,
并且可以象RAM一样快速读写数据。在掉电状态
下,数据可以保存10年。比EEPROM或其他非易失
性存储器可靠性更高,系统更简单。
二线制协议即是总线上的所有的操作都是由 SDA和SCL两个脚位的状态来确定的,共有四个状态: 开始,停止,数据以及应答,图3描述了四个状态的 时序图。详细时序在电气特性章节描述。
FM24C16A 的 大 多 数 功 能 由 两 线 协 议 控 制
或由片上电路自动完成。它以二线制总线的速
度进行读写,与 EEPROM不同,FM24C16A不必
数据/地址传送
所有数据传送(包括地址)都发生在SCL为 高电平的时候,除了以上两种情况外,SDA信 号在SCL为高电平时不能改变。
m16基于AT24C02的密码锁(1602)
//rs----PD4//rw----PD5//en----PD6//data---PORTB//SDA---PC1//SCL---PC0//beep--PA6//开锁---PB7//开锁状态----PB5//如果把uchar const initpassword[6]={0,0,0,0,0,0};改为_flash uchar initpassword[6]={0,0,0,0,0,0}; //则出现这错误found `unsigned' expecting `;'可我没找到错误在哪???#include <iom16v.h>#include<macros.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define uchar unsigned char#define uint unsigned int#define w 6 //定义密码位数uchar operation=0; //操作标志位uchar pass=0; //密码正确标志uchar ReInputEn=0; //重置输入充许标志uchar s3_keydown=0; //3秒按键标志位uchar key_disable=0; //锁定键盘标志uchar countt0,second; //t1中断计数器,秒计数器//void Delay5Ms(void);uchar InputData[6]; //输入密码暂存区uchar CurrentPassword[6]={1,3,1,4,2,0}; //当前密码值uchar TempPassword[6];uchar N=0; //密码输入位数记数uchar ErrorCont; //错误次数计数uchar CorrectCont; //正确输入计数uchar ReInputCont; //重新输入计数#pragma data:codeuchar const a[]={0xFE,0xFD,0xFB,0xF7}; //控盘扫描控制表uchar const start_line[] = {"password: "};uchar const name[] = {"===Coded Lock==="}; //显示名称uchar const Correct[] = {" correct "}; //输入正确uchar const Error[] = {" error "}; //输入错误uchar const codepass[] = {" pass "};uchar const LockOpen[] = {" open "}; //OPENuchar const SetNew[] = {"SetNewWordEnable"};uchar const Input[] = {"input: "}; //INPUTuchar const ResetOK[] = {"ResetPasswordOK "};uchar const initword[] = {"Init password..."};uchar const Er_try[] = {"error,try again!"};uchar const again[] = {"input again "};uchar const initpassword[6]={0,0,0,0,0,0};/************************************************************************************************* **/void port_init(){DDRA|=BIT(6);PORTA|=BIT(6);DDRB=0xFF;PORTB=0xFF;DDRC=0xFF;PORTC=0xFF;}/***********************************************************************************************/ void segg()//关数码显示管函数{DDRA|=BIT(PA3); //PA3设置为输出状态DDRA|=BIT(PA4); //PA4设置为输出状态DDRB=0xff; //PB口设置为输出状态PORTB=0xff; //发送模码PORTA|=BIT(PA3); //PA3输出高电平,DU拉高PORTA&=~BIT(PA3); //PA3输出低电平,DU拉低,段选锁存PORTB=0xff; //发送为选关掉数码管显示PORTA|=BIT(PA4); //PA4输出高电平,WE拉高PORTA&=~BIT(PA4); //PA4输出低电平,WE拉低,位选锁存DDRA|=BIT(PA2); //PA2设置为输出状态用于LED流水灯控制IO口PORTA&=~BIT(PA2); //PA2输出低电平,DU拉低,段选LED流水灯锁存}/****************************************5ms延时*************************************/void Delay5Ms(void){uint TempCyc = 5552;while(TempCyc--);}/****************************************400ms延时*************************************/void Delay400Ms(void){uchar TempCycA = 5;uint TempCycB;while(TempCycA--){TempCycB=7269;while(TempCycB--);}}/****************************************24C02****************************************/void mDelay(uint t) //延时{uchar i;while(t--){for(i=0;i<125;i++){;}}}/*******************************************************************************************/ void Nop(void) //空操作{_nop_();_nop_();_nop_();_nop_();}/*****************************************起始条件*****************************************/ void Start(void){//Sda=1;PORTC|=BIT(1);////Scl=1;PORTC|=BIT(0);//Nop();//Sda=0;PORTC&=~BIT(1);//Nop();}/*****************************************停止条件*****************************************/ void Stop(void){//Sda=0;PORTC&=~BIT(1);////Scl=1;PORTC|=BIT(0);//Nop();//Sda=1;PORTC|=BIT(1);//Nop();}/*****************************************应答位*****************************************/ void Ack(void){//Sda=0;PORTC&=~BIT(1);//Nop();//Scl=1;PORTC|=BIT(0);//Nop();//Scl=0;PORTC&=~BIT(0);//}/*****************************************反向应答位*****************************************/ void NoAck(void){//Sda=1;PORTC|=BIT(1);//Nop();//Scl=1;PORTC|=BIT(0);//Nop();//Scl=0;PORTC&=~BIT(0);//}/****************************发送数据子程序,Data为要求发送的数据***********************/ void Send(uchar Data){uchar BitCounter=8;uchar temp;do{temp=Data;//Scl=0;PORTC&=~BIT(0);//Nop();if((temp&0x80)==0x80)//Sda=1;PORTC|=BIT(1);else//Sda=0;PORTC&=~BIT(1);////Scl=1;PORTC|=BIT(0);//temp=Data<<1;Data=temp;BitCounter--;}while(BitCounter);//Scl=0;PORTC&=~BIT(0);//}/********************读一字节的数据,并返回该字节值************************************/ uchar Read(void){uchar temp=0;uchar temp1=0;uchar BitCounter=8;//Sda=1;PORTC|=BIT(1);//do{//Scl=0;PORTC&=~BIT(0);//Nop();//Scl=1;PORTC|=BIT(0);//Nop();//if(Sda)if(PORTC&0xF2)/////////////temp=temp|0x01;elsetemp=temp&0xfe;if(BitCounter-1){temp1=temp<<1;temp=temp1;}BitCounter--;}while(BitCounter);return(temp);}/****************************************************************************************/ void WrToROM(uchar Data[],uchar Address,uchar Num){uchar i;uchar *PData;PData=Data;for(i=0;i<Num;i++){Start();Send(0xa0);Ack();Send(Address+i);Ack();Send(*(PData+i));Ack();Stop();mDelay(20);}}/********************************************************************************/void RdFromROM(uchar Data[],uchar Address,uchar Num){uchar i;uchar *PData;PData=Data;for(i=0;i<Num;i++){Start();Send(0xa0);Ack();Send(Address+i);Ack();Start();Send(0xa1);Ack();*(PData+i)=Read();//Scl=0;PORTC&=~BIT(0);NoAck();Stop();}}//**********************************LCD1602*********************************************//#define yi 0x80 //LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80)#define er 0x80+0x40 //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)//*********************************************************************************************// void delay(uint xms)//延时函数,有参函数{uint x,y;for(x=xms;x>0;x--)for(y=110;y>0;y--);}/**********************************写指令****************************************/ write_1602com(uchar com)//****液晶写入指令函数****{PORTD&=~BIT(4);////数据/指令选择置为指令PORTD&=~BIT(5);////读写选择置为写PORTB=com;//送入数据delay(1);PORTD|=BIT(6);//拉高使能端,为制造有效的下降沿做准备delay(1);PORTD&=~BIT(6);//en由高变低,产生下降沿,液晶执行命令}/**********************写数据*****************************************************/ write_1602dat(uchar dat)//***液晶写入数据函数****{PORTD|=BIT(4);//////数据/指令选择置为数据PORTD&=~BIT(5);////读写选择置为写PORTB=dat;//送入数据delay(1);PORTD|=BIT(6);////en置高电平,为制造下降沿做准备delay(1);PORTD&=~BIT(6);////en由高变低,产生下降沿,液晶执行命令}/************************************初始化***************************************/ void lcd_init(void){write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据write_1602com(0x0c);//开显示不显示光标write_1602com(0x06);//整屏不移动,光标自动右移write_1602com(0x01);//清显示}/*******************************************将按键值编码为数值*************************/ uchar coding(uchar m){uchar k;switch(m){case (0x18): k=1;break;case (0x28): k=2;break;case (0x48): k=3;break;case (0x88): k='A';break;case (0x14): k=4;break;case (0x24): k=5;break;case (0x44): k=6;break;case (0x84): k='B';break;case (0x12): k=7;break;case (0x22): k=8;break;case (0x42): k=9;break;case (0x82): k='C';break;case (0x11): k='*';break;case (0x21): k=0;break;case (0x41): k='#';break;case (0x81): k='D';break;}return(k);}/******************************按键检测并返回按键值*************************************/ uchar keynum(void){uchar row,col,i;DDRD=0x0F;PORTD=0xF0;//KeyRead=PIND; //读取键盘结果//KeyRead&=0x0f; //屏蔽高四位//if((P1&0xf0)!=0xf0)if((PIND&0xf0)!=0xf0){Delay5Ms();Delay5Ms();if((PIND&0xf0)!=0xf0){row=PIND^0xf0; //确定行线i=0;PORTD=a[i];////精确定位while(i<4){if((PIND&0xf0)!=0xf0){col=~(PIND&0xff); //确定列线break; //已定位后提前退出}else{i++;PORTD=a[i];}}}else{return 0;}while((PORTD&0xf0)!=0xf0);return (row|col); //行线与列线组合后返回}else return 0; //无键按下时返回0}/********************************一声提示音,表示有效输入*************************************/ void OneAlam(void){PORTA&=~BIT(6);//Delay5Ms();PORTA|=BIT(6);//}/*********************************二声提示音,表示操作成功*********************************/void TwoAlam(void){PORTA&=~BIT(6);//Delay5Ms();PORTA|=BIT(6);//Delay5Ms();PORTA&=~BIT(6);//Delay5Ms();PORTA|=BIT(6);//}/*******************************三声提示音,表示错误************************************/ void ThreeAlam(void){PORTA&=~BIT(6);//Delay5Ms();PORTA|=BIT(6);//Delay5Ms();PORTA&=~BIT(6);//Delay5Ms();PORTA|=BIT(6);//Delay5Ms();PORTA&=~BIT(6);//Delay5Ms();PORTA|=BIT(6);//}/*****************显示输入的N个数字,用H代替以便隐藏*************************************/ void DisplayOne(void){// DisplayOneChar(9+N,1,'*');write_1602com(yi+5+N);write_1602dat('*');}/***********************************显示提示输入**************************************/ void DisplayChar(void){unsigned char i;if(pass==1){//DisplayListChar(0,1,LockOpen);write_1602com(er);for(i=0;i<16;i++){write_1602dat(LockOpen[i]);}}else{if(N==0){//DisplayListChar(0,1,Error);write_1602com(er);for(i=0;i<16;i++){write_1602dat(Error[i]);}}else{//DisplayListChar(0,1,start_line);write_1602com(er);for(i=0;i<16;i++){write_1602dat(start_line[i]);}}}}/**************************************************************************************/ void DisplayInput(void){uchar i;if(CorrectCont==1){//DisplayListChar(0,0,Input);write_1602com(er);for(i=0;i<16;i++){write_1602dat(Input[i]);}}}/******************************************重置密码*******************************/ void ResetPassword(void){uchar i;uchar j;if(pass==0){pass=0;DisplayChar();ThreeAlam();}else{if(ReInputEn==1){if(N==6){ReInputCont++;if(ReInputCont==2){for(i=0;i<6;){if(TempPassword[i]==InputData[i]) //将两次输入的新密码作对比i++;else{//DisplayListChar(0,1,Error);write_1602com(er);for(j=0;j<16;j++){write_1602dat(Error[j]);}ThreeAlam(); //错误提示pass=0;ReInputEn=0; //关闭重置功能,ReInputCont=0;DisplayChar();break;}}if(i==6){//DisplayListChar(0,1,ResetOK);write_1602com(er);for(j=0;j<16;j++){write_1602dat(ResetOK[j]);}TwoAlam(); //操作成功提示WrToROM(TempPassword,0,6); //将新密码写入24C02存储///////// ReInputEn=0;}ReInputCont=0;CorrectCont=0;}else{OneAlam();//DisplayListChar(0, 1, again); //显示再次输入一次write_1602com(er);for(j=0;j<16;j++){write_1602dat(again[j]);}for(i=0;i<6;i++){TempPassword[i]=InputData[i]; //将第一次输入的数据暂存起来}}N=0; //输入数据位数计数器清零}}}}/****************************输入密码错误超过三过,报警并锁死键盘********************************/ void Alam_KeyUnable(void){PORTD=0x00;//{PORTA^=BIT(6);//Delay5Ms();}}/*************************************取消所有操作***********************/void Cancel(void){uchar i;uchar j;//DisplayListChar(0, 1, start_line);write_1602com(er);for(j=0;j<16;j++){write_1602dat(start_line[j]);}TwoAlam(); //提示音for(i=0;i<6;i++){InputData[i]=0;}PORTB|=BIT(7);//关闭锁PORTA|=BIT(6);//报警关operation=0; //操作标志位清零pass=0; //密码正确标志清零ReInputEn=0; //重置输入充许标志清零ErrorCont=0; //密码错误输入次数清零CorrectCont=0; //密码正确输入次数清零ReInputCont=0; //重置密码输入次数清零PORTB|=BIT(5);s3_keydown=0;key_disable=0;N=0; //输入位数计数器清零}/*******************************确认键,并通过相应标志位执行相应功能************************/ void Ensure(void){uchar i,j;RdFromROM(CurrentPassword,0,6); //从24C02里读出存储密码if(N==6){if(ReInputEn==0) //重置密码功能未开启{for(i=0;i<6;){if(CurrentPassword[i]==InputData[i]){i++;}else{ErrorCont++;if(ErrorCont==3) //错误输入计数达三次时,报警并锁定键盘{write_1602com(er);for(i=0;i<16;i++){write_1602dat(Error[i]);}doAlam_KeyUnable();while(1);}else{TIMSK|=BIT(2); //开启定时key_disable=1; //锁定键盘pass=0;break;}}}if(i==6){CorrectCont++;if(CorrectCont==1) //正确输入计数,当只有一次正确输入时,开锁,{//DisplayListChar(0,1,LockOpen);write_1602com(er);for(j=0;j<16;j++){write_1602dat(LockOpen[j]);}TwoAlam(); //操作成功提示音PORTB&=~BIT(7);//开锁///////////////////////////////////pass=1; //置正确标志位TIMSK|=BIT(2); //开启定时/////////////////////////PORTB&=~BIT(5);//开锁指示灯亮//////////////////////////////for(j=0;j<6;j++) //将输入清除{InputData[i]=0;}}else//当两次正确输入时,开启重置密码功能{//DisplayListChar(0,1,SetNew);write_1602com(er);for(j=0;j<16;j++){write_1602dat(SetNew[j]);}TwoAlam(); //操作成功提示ReInputEn=1; //允许重置密码输入CorrectCont=0; //正确计数器清零}}else//============当第一次使用或忘记密码时可以用131420对其密码初始化{if((InputData[0]==1)&&(InputData[1]==3)&&(InputData[2]==1)&&(InputData[3]==4)&&(InputData[4]==2)&& (InputData[5]==0)){WrToROM(initpassword,0,6); //强制将初始密码写入24C02存储//DisplayListChar(0,1,initword); //显示初始化密码write_1602com(er);for(j=0;j<16;j++){write_1602dat(initword[j]);}TwoAlam();Delay400Ms();TwoAlam();N=0;}else{//DisplayListChar(0,1,Error);write_1602com(er);for(j=0;j<16;j++){write_1602dat(Error[j]);}ThreeAlam(); //错误提示音pass=0;}}}else//当已经开启重置密码功能时,而按下开锁键,{//DisplayListChar(0,1,Er_try);write_1602com(er);for(j=0;j<16;j++){write_1602dat(Er_try[j]);}ThreeAlam();}}else{//DisplayListChar(0,1,Error);write_1602com(er);for(j=0;j<16;j++){write_1602dat(Error[j]);}ThreeAlam(); //错误提示音pass=0;}N=0; //将输入数据计数器清零,为下一次输入作准备operation=1;}/********************************************************************************************/ void main(void){uchar KEY,NUM;uchar i,j;segg();port_init();Delay400Ms(); //启动等待,等LCM讲入工作状态lcd_init(); //LCD初始化write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示PORTD=0xFF;TCCR1B=0X05;//1024分频//5msTCNT1H=0XFF;//TCNT1L=0XC5;//TIMSK|=BIT(2);SREG|=BIT(7);for(i=0;i<16;i++){write_1602dat(name[i]);//向液晶屏写日历显示的固定符号部分}write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示for(i=0;i<16;i++){write_1602dat(start_line[i]);//写显示时间固定符号,两个冒号}write_1602com(er+9); //设置光标位置write_1602com(0x0f); //设置光标为闪烁Delay5Ms(); //延时片刻(可不要)N=0; //初始化数据输入位数while(1){if(key_disable==1)Alam_KeyUnable();elsePORTA|=BIT(6); //关报警KEY=keynum();if(KEY!=0){if(key_disable==1){second=0;}else{NUM=coding(KEY);{switch(NUM){case ('A'): ; break;case ('B'): ; break;case ('C'): ; break;case ('D'): ResetPassword(); break; //重新设置密码case ('*'): Cancel(); break; //取消当前输入case ('#'): Ensure(); break; //确认键,default:{//DisplayListChar(0,1,Input);write_1602com(er);for(i=0;i<16;i++){write_1602dat(Input[i]);}operation=0;if(N<6) //当输入的密码少于6位时,接受输入并保存,大于6位时则无效。