AVR实验mega16多功能电子钟

合集下载

ATMEGA16单片机实验

ATMEGA16单片机实验

ATMEGA16单⽚机实验实验⼀软件和硬件的认识⼀、实验⽬的:1、掌握硬件原理。

2、初步掌握实验板的使⽤⽅法。

3、熟悉软件⼯作界⾯。

⼆、实验仪器:ATmage16实验板⼀块PC机⼀台三、实验内容及步骤:1、插上电源,按下开关。

观察批⽰灯是否点亮。

电源(可输⼊7~12V)ATmega16管脚图2、由原理可知I/O⼝的批⽰灯为低电平亮,在实验板上取地与I/O⼝相接,观察是否点亮。

I/O⼝LED显⽰与接⼝3、打开编程界⾯,点击各栏,认识各栏的⽤途。

A VRICC IDE 软件的⼯作界⾯4、输⼊以下程序:#includeint main(void){DDRA = 0xff;/* all outputs */DDRB = 0xff;/* all outputs */DDRC = 0xff; /*all outputs */DDRD = 0xff; /*all outputs */PORTA = 0x00; /* 输出低电平*/PORTB = 0x00; /* 输出低电平*/PORTC = 0x00; /* 输出低电平*/PORTD = 0x00; /* 输出低电平*/while(1);}观察I/O⼝的灯是否被点亮。

实验⼆I/O⼝的输⼊与输出⼀、实验⽬的:1、了解IO⼝的结构;2、熟悉IO⼝的特性;3、掌握IO⼝的控制。

⼆、实验仪器:ATmage16实验板⼀块PC机⼀台三、实验原理:作为通⽤数字I/O 使⽤时,A VR 所有的I/O 端⼝都具有真正的读-修改-写功能。

这意味着⽤SBI 或CBI 指令改变某些管脚的⽅向( 或者是端⼝电平、禁⽌/ 使能上拉电阻) 时不会改变其他管脚的⽅向( 或者是端⼝电平、禁⽌/ 使能上拉电阻)。

输出缓冲器具有对称的驱动能⼒,可以输出或吸收⼤电流,直接驱动LED。

所有的端⼝引脚都具有与电压⽆关的上拉电阻。

并有保护⼆极管与VCC 和地相连,如Figure23 所⽰。

在控制I/O时,分别由⽅向寄存器DDRX与数据寄存器PORTX控制I/O的状态,如下表。

多功能六位电子钟说明书

多功能六位电子钟说明书

多功能六位电子钟说明书一、原理说明:1、显示原理:显示部分主要器件为3只两位一体共阳极数码管,驱动采用 PNP 型三极管驱动,各端口配有限流电阻,驱动方式为动态扫描,占用 P3.0~P3.5 端口,段码由P1.0~P1.6输出。

冒号部分采用 4 个Φ3.0的红色发光二极管,驱动方式为独立端口P1.7驱动。

2、键盘原理:按键 S1~S3 采用复用的方式与显示部分的 P3.5、P3.4、P3.2 口复用。

其工作方式为,在相应端口输出高电平时读取按键的状态并由单片机消除抖动并赋予相应的键值。

3、迅响电路及输入、输出电路原理:迅响电路由有源蜂鸣器和 PNP 型三极管组成。

其工作原理是当 PNP 型三极管导通后有源蜂鸣器立即发出定频声响。

驱动方式为独立端口驱动,占用P3.7端口。

输出电路是与迅响电路复合作用的,其电路结构为有源蜂鸣器,5.1K定值电阻R6,排针J3并联。

当有源蜂鸣器无迅响时J3输出低电平,当有源蜂鸣器发出声响时J3输出高电平,J3可接入数字电路等各种需要。

驱动方式为迅响复合输出,不占端口。

输入电路是与迅响电路复合作用的,其电路结构是在迅响电路的 PNP 型三极管的基极电路中接入排针J2。

引脚排针可改变单片机I/O口的电平状态,从而达到输入的目的。

驱动方式为复合端口驱动,占用P3.7端口。

4、单片机系统:本产品采用了单片机AT89C2051为核心器件,并配合所有的外围电路,具有上电复位的功能,无手动复位功能。

二、使用说明:1、功能按键说明:S1为功能选择按键,S2为功能扩展按键,S3为数值加一按键。

2、功能及操作说明:操作时,连续短时间(小于1秒)按动S1,即可在以上的6个功能中连续循环。

中途如果长按(大于2秒)S1,则立即回到时钟功能的状态。

1)时钟功能:上电后即显示10:10:00 ,寓意十全十美。

2)校时功能:短按一次 S1,即当前时间和冒号为闪烁状态,按动 S2 则小时位加 1,按动 S3则分钟位加1,秒时不可调。

PCF8563在电子时钟设计中的应用

PCF8563在电子时钟设计中的应用

PCF8563在电子时钟设计中的应用引言数字时钟已成为时钟设计的主导方向,广泛应用于实时控制系统。

数字时钟实质是一个对标准频率计数的计数电路,通常由晶体振荡电路、分频电路、时间计数电路、译码驱动电路等组成。

这里提出一种电子时钟系统设计方案,是以avr 单片机mega16作为控制核心,采用PCF8563时钟/日历器件以及数码管显示,通过硬件设计及软件编程实现的。

1 mega16简介ATmega16是基于增强的AVR RISC结构的低功耗8位CMOS微控制器。

由于其先进的指令集以及单时钟周期指令执行时间,ATmega16 的数据吞吐率高达1MIPS/MHz,从而可以缓减系统在功耗和处理速度之间的矛盾。

AVR 内核具有丰富的指令集和 32 个通用工作寄存器。

所有的寄存器都直接与算逻单元(ALU) 相连接,使得一条指令可以在一个时钟周期内同时访问两个独立的寄存器。

这种结构大大提高了代码效率,并且具有比普通的 CISC微控制器最高至 10倍的数据吞吐率。

ATmega16 有如下特点:16K字节的系统内可编程Flash(具有同时读写的能力,即RWW),512 字节 EEPROM,1K字节 SRAM,32 个通用I/O 口线,32 个通用工作寄存器,用于边界扫描的 JTAG 接口,支持片内调试与编程,三个具有比较模式的灵活的定时器/计数器(T/C),片内/外中断,可编程串行USART,有起始条件检测器的通用串行接口,8路10 位具有可选差分输入级可编程增益 (TQFP 封装 ) 的 ADC ,具有片内振荡器的可编程看门狗定时器,一个 SPI串行端口,以及六个可以通过软件进行选择的省电模式。

工作于空闲模式时 CPU 停止工作,而 USART、两线接口、A/D 转换器、SRAM、T/C、SPI 端口以及中断系统继续工作;掉电模式时晶体振荡器停止振荡,所有功能除了中断和硬件复位之外都停止工作;在省电模式下,异步定时器继续运行,允许用户保持一个时间基准,而其余功能模块处于休眠状态;ADC噪声抑制模式时终止CPU 和除了异步定时器与ADC以外所有 I/O 模块的工作,以降低 ADC 转换时的开关噪声; Standby 模式下只有晶体或谐振振荡器运行,其余功能模块处于休眠状态,使得器件只消耗极少的电流,同时具有快速启动能力;扩展 Standby 模式下则允许振荡器和异步定时器继续工作。

用AVRMEGA16单片机控制实现的数据采集系统

用AVRMEGA16单片机控制实现的数据采集系统


3 6・
化 工 自 动 化 及 仪 表
第3 3卷
调整电阻调 整放大倍数 1 5 第 二级 通过 O:7的 和 , 1 ' 0
增益调整电阻调整放 大倍数 0 2 ,. , , ,0 . 5 0 5 15 1 。调 整过程通过继 电器组 来完成 , 即通过继 电器控 制增
片 6 17进行隔离 。 N3
口实现对仪器设备 的双 向控制与数 据传送 的一 种解
决方案 。
2 系统 总体设计方案
系统 总框 图设计如 图 1 所示 。
放大电路如 图 2所示 。
圆鱼
图 1 采集系统 总框 图

耗_ ⅥR8 nv +



- — -

- -
_ ‘
4翌
— - - —
A 60来调节增益作为一级放大 ; D2 使用放 大器 O 0 P7 作为二 级放 大 ; 之后用 A 7 3 D 85进行数模转换 , 最后 采用 隔离芯片 6 17作为隔离 。 N3
系统 的量程 选 择 包 括 :0m 2 V 5 V, 1 V,0m ,0m
1 0 mV , 0 0 2 0 mV, 0 5 0 mV , , , , 0 V , 0 V 。 1V 2 V 5 V 1 2
AD7 3 8 5 G ND 0N C
R5 l K 0
13 0 3
+5VI
30 3 ] 6 1 N 37
I U
l几 厂1 8
位高速低功耗 芯片 , 的采样速 度可 高达 50k z 它 0 H , 远远高于 1 H , 0k z满足 了 A D采样速率。 / 由于所采集信 号为化学 反应参 数 , 要求 采样 信 号之间彼此完 全独立而 无任何 相关 , 采样环境 要 且 求抗干扰能力 强 , 以在信号转换 成数 字信号后 经 所

基于AVR单片机Mega16的电子时钟设计

基于AVR单片机Mega16的电子时钟设计

t e Ba i , C, a d o h rh g ~ e e a g a e p o r mmi gT e ee t n c co k w ih i d ig e y Me a 6 i n to l h sc n t e ih lv ll n u g r g a n . h l cr i l c h c s es n d b g l s o n y o lw— o t smp e h r w r , b t a y t c i v y tm g a inT e d sg t o f l er i lc a e n t e AVR o c s, i l a d a e u s o a h e e s se mi r t .h e in me h d o e ti c co k b s d o h e o e o Me a 6 al h r c e CD1 0 s ito u e n t i p p r n h o r s o d n i u te e t o i n o a g a d c d i h S a e , d t e c re p n i g cr i l cr n c a d s me ln u g a c i
中 图分 类 号 : P 7 T 23
文献 标 识 码 : A
文 章 编 号 :0 6 6 7 (0 80 = 0 80 10 - 9 720 )7 0 1 - 2
De i n o n l c r ni l c b s d n AVR e a1 sg fa e e t o c co k a e o M g 6
摘 要 : g1 Mea 6是 一 款 采 用先 进 R S IC精 简指 令 , 内置 A D 的 8 单 片机 , 支 持 低 电压 联 机 Fah和 E P O 写入 功 / 位 可 ls ER M 能 : 时还 支持 B s 同 ai C 等 高级 语 言编 程 。 c和 用它 设 计 电子 时 钟 不 仅 成 本 低 , 件 简单 , 且 很 容 易实 现 系统 移 植 。 硬 而 介

增强版AVRmega16与mega32开发板 说明书

增强版AVRmega16与mega32开发板 说明书

增强版A VRmega16与mega32开发板使用手册Vision 0.7板载资源简介:增强版A VR mega16/32开发板是A VR与虚拟仪器全新开发的一款A VR开发板,适应芯片A T90S8535,ATmega16,A Tmega32,开发板最新版本V3.2。

本开发版拥有如下资源:(1)电源部分:在12V 输入电压,开发板上提供高稳定的3.3V、5V 和12V 的电源,配有电源指示灯、极性保护电路及开关。

同时板上有多个高频和低频的电源滤波电容。

(2) ISP下载接口:标准的10PIN 的ISP 下载接口,用于AVR 程序的下载。

(3) JTAG仿真接口:JTAG在线仿真调试接口,使用JTAGICE 进行在线调试。

(4)芯片插座:PORTA、PORTB、PORTC、PORTD分别引出32 个插座,JTAG&ISP、复位、晶振、电源引脚都直接链接与芯片连接。

部分只能使用固定引脚的外部功能通过跳线连接,如串口,I2C,AT45DB041。

(5)晶振复位电路:开发板提供一个7.3728M 晶振以及一个晶振插槽,可由实验者自己选用。

(6)扩展插槽:板上预留三条扩展槽,按照Power、Control、Port、NC的格式进行预定义,其中Power提供3.3V、5V 和12V 两种。

扩展槽与扩展功能板兼容,可以实现其他的特殊功能扩展,完全兼容ATmega128 功能板。

(7)串口:使用MAX232 芯片作串口通讯控制,标准RS232接口。

(8) USB:采用CP2102 实现USB转串口的功能。

(9) 4 位独立按键(10) 4*4 矩阵键盘:16个按键可以接成4×4的矩阵键盘,Int中断接口,完全实现键盘中断扫描的要求。

(11) 18B20:温度传感器芯片。

(12) 24C01:外部扩展EEPROM ,通过I2C 方式与单片机通讯。

(13) ADC:模数转换电路,其中接有多个可调电阻用于分压及测试。

ATMEGA16定时器0

ATMEGA16定时器0

ATMEGA16定时器0(2013-04-09 21:51:35)转载▼分类:AVR标签:avr定时器0MEGA16定时器0T/C0 是一个八位定时器,主要有定时、外部事件计数、产生PWM 波形这几个功能,我们在使用这些功能之前,首先要设置T/C0 工作在合适的工作模式下。

T/C0 有四种工作模式,分别是普通模式、CTC 模式、快速PWM、相位可调的PWM 模式四种。

模式设置通过T/C0 的控制寄存器TCCR0 来完成。

1.普通模式在此模式下,T/C0 的计数寄存器TCNT0 在时钟的驱动下不停累加。

当计满后(计数值达到最大,8 位寄存器最大计数值为0xff),由于数值的溢出寄存器清零重新开始累加。

当计数器溢出后,TIFR 中的溢出标志位TOV0 会置位,也可触发中断。

所以我们可以通过查询或中断的方式得知定时器的溢出从而进行相关处理。

此模式适合定时与计数。

关于定时和计数,这里的定时功能是T/C0 在对时钟计数达到一定的值后引发中断,达到了定时功能,然而本质的过程是计数工作。

那么这里所说的计数功能是外部事件计数。

实例:T/C0 定时实验,将T/C0 设置为普通模式,对1024 分频的系统时钟进行计数,计满发生中断,40 次中断递增一个计数用的变量,主函数则不停显示这个变量。

第一步:开总中断,SREG |= 0X80;第二步:开T/C0 溢出中断第三步:模式设置、分频设置、匹配输出模式设置T/C0 控制寄存器用于设置工作模式,时钟分频和波形输出模式。

这里T/C0 设置为普通模式,WGM00-WGM01设置为00。

此模式下定时器的TOP 值,也就是能够达到的最大计数值为0xFF。

TOV0 在计数器计满后置位,也就是计到MAX,八位的定时器计数达到255 为计满。

低三位设置定时器时钟。

T/C0 在系统时钟的分频或外部时钟的驱动下递增或递减。

系统时钟也就是晶振的大小是11.0592MHZ。

此实验中,设置为1024 分频。

avrMEGA16单片机控制DS1302时钟芯片1602液晶显示

avrMEGA16单片机控制DS1302时钟芯片1602液晶显示

avr MEGA16单片机控制DS1302时钟芯片1602液晶显示/*程序名(program name) : 时钟芯片控制程序;概述 : 基于本程序的开发板是本人自主研发的YF-A1 AVR MEGA16单片机芯片开发板,信号辅助硬件工具有一部8通道的24兆赫兹的逻辑分析仪和一部万用表,通俗的讲,此程序就是开发板的操作系统,以MEGA16A为中央控制芯片,来控制DS1302时钟芯片,使其时间数据显示在1602液晶屏上;我用业余时间大概写了三天左右....得以完善,这次我写的比较顺利,错误只有两点,一是将写好的程序下载入芯片后,时间不走,错误在于写错了时序,用逻辑分析仪捕捉信号后,修正,KO! 二是时间可以走,但是跑秒区并非从0走到59,问题在于显示时,直接显示BCD码,并未将BCD码转换为十进制数,修正后OK!此程序还用到了定时器模块,定时每100毫秒读一次时间数据,并显示在液晶屏上;心得: 此次又突破了以往的程序量,这是我写的目前最大的一个程序,由于AVR芯片IO口控制比较复杂,所以程序语句比较多,但是此程序还有精简的空间,IO口的初始化很重要!finish time: 2014年3月7日13:16:14 作者: 肖邦;QQ: 14-545-07665 ;TEL: SORRY 保密;地址: 新疆昌吉回族自治州昌吉市;梦想: 将托尼*斯塔克成为现实;*/#include ;#include ;//此头文件用于中断服务,本程序中可以省略; typedef unsigned char uint8;typedef unsigned int uint16;void init_io(void) //====初始化所有io口;{DDRA=0XFF;PORTA=0XFF;DDRB=0XFF;PORTB=0X00;DDRC=0XFF;PORTC=0X00;DDRD=0XFF;PORTD=0X00;}//================IO口的位操作================== void rs(uint8 a) //指令/数据位/ ===========DS1302时钟位;{if(a) { PORTB|=1;>;=1;}}uint8 ds_read(void) // DS1302读取函数;{uint8 j=0,temp=0;DDRB&=~(1;>;=1;if((PINB&0X10)==0X10)//如果PB4口读到1;{temp|=0x80;//装载数据;}rs(1); //下降沿有效;delay2(); //时钟脉宽延时;rs(0);}DDRB|=1<<4; // rw引脚输出状态;PORTB|=1<<4; //rw引脚输出1;rs(0);rw(0);return (temp);}void w_1302(uint8 addr,uint8 dat) //写一个地址,写一个数据;{ds_write(addr);ds_write(dat);}void ds_wp(uint8 j) //j==1:不能够写入数据,j==0:可以写入数据;{reset_1302(); //初始化时钟,数据,片选线;ds(1);w_1302(0x8e,j?0x80:0); //三目运算;ds(0);void set_time(uint8 * dat) //设置时间;{uint8 r=0 ,t=0, ad=0x80;for(r=0;r<7;r++) //BCD码的转换.{t=dat[r]%10;dat[r]=dat[r]/10;dat[r]=(dat[r]*16)+t;}ds_wp(0);//可以写入数据;for(r=0;r<7;r++){reset_1302(); //初始化1302;ds(1); //传输使能开;ds_write(ad); //写入&quot;写&quot;操作地址; ds_write(dat[r]);//写入时间数据;ds(0);ad+=2;//地址加2;}ds_wp(1);//禁止写入数据;void read_time(uint8 * dat){uint8 j=0,addr=0x81 ;for(j=0;j<7;j++){reset_1302();ds(1); //传输使能开;ds_write(addr); //发送读取地址; dat[j]=ds_read(); //接收读到的数据; ds(0); //传输使能关;addr+=2; //读取地址加2;}}void timer0(void) //定时器模块函数; {TCNT0=22; //每5毫秒溢出一次;TCCR0=0X04; //256分频;}int main(void){uint8 j=0;uint8 sj[]={20,23,13,7,3,5,14}; init_io(); //初始化所有io口;init_lcd(); //初始化1602液晶屏; play(0x82,'2');delay1(3,2);play(0x83,'0');delay1(3,2);play(0x86,'-');delay1(3,2);play(0x89,'-');delay1(3,2);play(0x8d,'(');delay1(3,2);play(0x8f,')');delay1(3,2);play(0xc4,':');delay1(3,2);play(0xc7,':');delay1(3,2);buzz(); //蜂鸣器叫;delay1(3,2);set_time(sj); //设置时间;timer0(); //运行定时器;while(1){if(TIFR&0X01) //定时器溢出了;{j++;TCNT0=22;TIFR|=0X01;//溢出位置一清零;}if(j==20){j=0;read_time(sj);play(0xc9,sj[0]%16+'0'); //秒个位; play(0xc8,sj[0]/16+'0'); //秒十位;play(0xc6,sj[1]%16+'0'); //分个位; play(0xc5,sj[1]/16+'0'); //分十位; play(0xc3,sj[2]%16+'0'); //时个位; play(0xc2,sj[2]/16+'0'); //时十位;play(0x8b,sj[3]%16+'0'); //号个位; play(0x8a,sj[3]/16+'0'); //号十位; play(0x88,sj[4]%16+'0'); //月个位; play(0x87,sj[4]/16+'0'); //月十位;play(0x8e,sj[5]+'0'); //星期;play(0x85,sj[6]%16+'0'); //秒个位; play(0x84,sj[6]/16+'0'); //秒十位;}}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

A VR课程设计数字时钟物联网专业一、课程目的通过课程设计,充分利用所学知识,将知识整合,实现最基本的数字时钟。

二、课程要求1、时间显示、日历、并且显示屏可以切换2、秒表,可以记录多个时间,可以加入时间3、叫醒闹钟设置,闹钟等4、温度显示5、记事提醒子模块:液晶,按键,DS1302时钟,温度传感器,其他等三、功能设计1、时间显示:通过调用ds1302时间函数,实现时间的显示。

通过按键二的控制,显示四行数据,第二行显示时间,其余三行可自由添加;按键零实现调制时间的分钟数和时钟数,按键一为加一控制,按键二为减一控制,按键七为跳回主界面控制。

2、日历设置:同样是通过调用ds1302日历函数,实现日历的显示。

通过按键二的控制,跳入日历显示界面,第二行显示日历,其余三行可自由发挥;按键零实现调制天、月和年,按键一为加一控制,按键二为减一控制,按键七为跳回主界面。

3、闹钟显示:实现蜂鸣器和时间函数的同时调用,在当前时间等于闹钟时间时,可以自行跳出闹钟界面,按键七可返回之前界面;在主菜单项,可以通过按键三实现闹钟界面显示,按键零可实现闹钟时间的小时和分钟的调制,按键一为加一,按键二为减一,按键七跳回主界面。

闹钟自动跳出提醒,按键七可以退出闹钟响应。

4、显示屏显示:整个显示屏的显示直接调用DS12864显示,菜单六栏,分别为时钟显示,日历显示,闹钟显示,温度显示,记事本及秒表,通过按键控制相应的区域。

四、课程器材A VR实验箱一台五、课程连线1、按键JP37接PB口,实现按键控制2、ds12864的D口,接PD口,实现显示屏显示3、RS,RW,E分别接PA5,PA6,PA74、ds1302的SCK,I/C,RST口分别接PA0,PA1,PA2,实现时钟显示5、ds1820的JP39接PA3,实现温度传感器6、ds1820的JP16接PA4,实现蜂鸣器六、课程代码DS1302#include <mega16.h>#define PA0 0#define PA1 1#define PA2 2/*复位脚*/#define RST_CLR PORTA &= ~(1 << PA2)/*电平置低*/#define RST_SET PORTA |= (1 << PA2)/*电平置高*/#define RST_IN DDRA &= ~(1 << PA2)/*方向输入*/#define RST_OUT DDRA |= (1 << PA2)/*方向输出*//*双向数据*/#define IO_CLR PORTA &= ~(1 << PA1)/*电平置低*/#define IO_SET PORTA |= (1 << PA1)/*电平置高*/#define IO_R PINA & (1 << PA1)/*电平读取*/#define IO_IN DDRA &= ~(1 << PA1)/*方向输入*/#define IO_OUT DDRA |= (1 << PA1)/*方向输出*//*时钟信号*/#define SCK_CLR PORTA &= ~(1 << PA0)/*时钟信号*/#define SCK_SET PORTA |= (1 << PA0)/*电平置高*/#define SCK_IN DDRA &= ~(1 << PA0)/*方向输入*/#define SCK_OUT DDRA |= (1 << PA0)/*方向输出*/#define ds1302_sec_add 0x80 //秒数据地址#define ds1302_min_add 0x82 //分数据地址#define ds1302_hr_add 0x84 //时数据地址#define ds1302_date_add 0x86 //日数据地址#define ds1302_month_add 0x88 //月数据地址#define ds1302_day_add 0x8a //星期数据地址#define ds1302_year_add 0x8c //年数据地址#define ds1302_control_add 0x8e //控制数据地址#define ds1302_charger_add 0x90#define ds1302_clkburst_add 0xbeunsigned char time_buf[8] = {0x20,0x14,0x05,0x14,0x23,0x59,0x00,0x02};/*向DS1302写入一字节数据*/void ds1302_write_byte(unsigned char addr, unsigned char d) {unsigned char i;RST_SET; /*启动DS1302总线*//*写入目标地址:addr*/IO_OUT;addr = addr & 0xFE;/*最低位置零*/for (i = 0; i < 8; i ++) {if (addr & 0x01) {IO_SET;}else {IO_CLR;}SCK_SET;SCK_CLR;addr = addr >> 1;}/*写入数据:d*/IO_OUT;for (i = 0; i < 8; i ++) {if (d & 0x01) {IO_SET;}else {IO_CLR;}SCK_SET;SCK_CLR;d = d >> 1;}RST_CLR; /*停止DS1302总线*/ }/*从DS1302读出一字节数据*/unsigned char ds1302_read_byte(unsigned char addr) {unsigned char i;unsigned char temp;RST_SET; /*启动DS1302总线*//*写入目标地址:addr*/IO_OUT;addr = addr | 0x01;/*最低位置高*/for (i = 0; i < 8; i ++) {if (addr & 0x01) {IO_SET;}else {IO_CLR;}SCK_SET;SCK_CLR;addr = addr >> 1;}/*输出数据:temp*/IO_IN;for (i = 0; i < 8; i ++) {temp = temp >> 1;if (IO_R) {temp |= 0x80;}else {temp &= 0x7F;}SCK_SET;SCK_CLR;}RST_CLR; /*停止DS1302总线*/return temp;}/*向DS302写入时钟数据*/void ds1302_write_time(void) {ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护ds1302_write_byte(ds1302_sec_add,0x80); //暂停//ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电ds1302_write_byte(ds1302_year_add,time_buf[1]); //年ds1302_write_byte(ds1302_month_add,time_buf[2]); //月ds1302_write_byte(ds1302_date_add,time_buf[3]); //日ds1302_write_byte(ds1302_day_add,time_buf[7]); //周ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时ds1302_write_byte(ds1302_min_add,time_buf[5]); //分ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒ds1302_write_byte(ds1302_control_add,0x80); //打开写保护}/*从DS302读出时钟数据*/void ds1302_read_time(void) {time_buf[1]=ds1302_read_byte(ds1302_year_add); //年time_buf[2]=ds1302_read_byte(ds1302_month_add); //月time_buf[3]=ds1302_read_byte(ds1302_date_add); //日time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时time_buf[5]=ds1302_read_byte(ds1302_min_add); //分time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7F;//秒time_buf[7]=ds1302_read_byte(ds1302_day_add); //周}/*DS302初始化函数*/void ds1302_init(void) {RST_CLR; /*RST脚置低*/SCK_CLR; /*SCK脚置低*/RST_OUT; /*RST脚设置为输出*/SCK_OUT; /*SCK脚设置为输出*/}DS18B20#include <mega16.h>#include <delay.h>#define PA3 PORTA3#define DQ_IN DDRA &= ~(1 << PA3) /*设置输入*/#define DQ_OUT DDRA |= (1 << PA3) /*设置输出*/#define DQ_CLR PORTA &= ~(1 << PA3) /*置低电平*/#define DQ_SET PORTA |= (1 << PA3) /*置高电平*/#define DQ_R PINA & (1 << PA3) /*读了电平*/unsigned char flag; /*中断标志缓存*//*延时函数延时时间:i X 10 + 16uS。

CPU频率为:1MHz。

*/void delay_10us(unsigned char i) {if (i == 0) {return ;}while (i--) {delay_us(1);// NOP();delay_us(1);// NOP();delay_us(1);// NOP();delay_us(1);// NOP();}}/*DS18B20复位函数*/unsigned char ds1820_reset(void) {unsigned char i;flag = SREG; /*中断保护*/SREG&=0x7F;//CLI(); /*关中断*/DQ_OUT;DQ_CLR;delay_10us(49); /*延时500uS(480-960)*/DQ_SET;DQ_IN;delay_10us(7); /*延时80uS*/i = DQ_R;delay_10us(49); /*延时500uS(保持>480uS)*/ if (flag & 0x80) { /*恢复中断状态*/SREG|=0x80;//SEI();}if (i) {return 0x00;}else {return 0x01;}}/*DS18B20字节读取函数*/unsigned char ds1820_read_byte(void) {unsigned char i;unsigned char value = 0;flag = SREG; /*中断保护*/SREG&=0x7F;//CLI(); /*关中断*/for (i = 8; i != 0; i--) {value >>= 1;DQ_OUT;DQ_CLR;delay_us(4);DQ_SET;DQ_IN;delay_us(10);if (DQ_R) {value|=0x80;}delay_10us(5); /*延时60uS*/}if (flag & 0x80) { /*恢复中断状态*/SREG|=0x80;//SEI();}return(value);}/*DS18B20字节写入函数*/void ds1820_write_byte(unsigned char value) {unsigned char i;flag = SREG; /*中断保护*/SREG&=0x7F;//CLI(); /*关中断*/ for (i = 8; i != 0; i--) {DQ_OUT;DQ_CLR;delay_us(4);// NOP(); /*延时4uS*/// NOP();// NOP();// NOP();if (value & 0x01) {DQ_SET;}delay_10us(7); /*延时80uS*/DQ_SET; /*位结束*/value >>= 1;}if (flag & 0x80) { /*恢复中断状态*/SREG|=0x80;//SEI();}}/*启动ds1820转换*/void ds1820_start(void) {ds1820_reset();ds1820_write_byte(0xCC); /*勿略地址*/ds1820_write_byte(0x44); /*启动转换*/}/*DS8B20读取温度信息*/unsigned int ds1820_read_temp(void) {unsigned int i;unsigned char buf[9],pp;pp=ds1820_reset();if(pp==0x01){//有传感器ds1820_write_byte(0xCC); /*勿略地址*/ds1820_write_byte(0xBE); /*读取温度*/for (i = 0; i < 9; i++) {buf[i] = ds1820_read_byte();}i = buf[1];i <<= 8;i |= buf[0];return i;}elsereturn(0x07D0);}DS12864#include <mega16.h>#include <string.h>#define uchar unsigned char#define uint unsigned int#define RS (1<<5)//0010 0000#define RW (1<<6)//0100 0000#define EN (1<<7)//1000 0000void time_ms(uint ms){for(;ms>1;ms--);}//写数据void WriteData(unsigned char WDLCM)//101{//ReadStatusLCM(); //检测忙//time_ms(100);PORTA|=RS; //RS=1 PORTA=0000 0001time_ms(100);PORTA&=~RW; //RW=0 PORTA=0000 0001time_ms(100);PORTA|=EN; //EN=1 PORTA=0000 0001 time_ms(100);PORTD=WDLCM; //输出数据time_ms(100);PORTA&=~EN; //EN=0time_ms(100);}//写指令void WriteCommand(unsigned char WCLCM) //001 {//ReadStatusLCM(); //根据需要检测忙PORTA&=~RS; //RS=0time_ms(100);PORTA&=~RW; //RW=0time_ms(100);PORTA|=EN; //EN=1time_ms(100);PORTD=WCLCM; //输出指令time_ms(100);PORTA&=~EN; //EN=0time_ms(100);}//读状态:检测忙void ReadStatus()//011{uchar temp;uchar flag = 1;while(flag==1){DDRD=0x00; //端口D改为输入PORTD=0xff;time_ms(100);PORTA&=~RS; //RS=0time_ms(100);PORTA|=RW; //RW=1time_ms(100);PORTA|=EN; //EN=1time_ms(1000);temp = PIND; //读端口Dtime_ms(1000);DDRD=0xff; //端口D改为输入time_ms(100);PORTA&=~EN; //EN=0time_ms(100);if(temp>>7==0)flag = 0;}}//LCM初始化void LCMInit(void){WriteCommand(0x38); //三次显示模式设置,不检测忙信号0011 1000功能设置WriteCommand(0x38);WriteCommand(0x38);WriteCommand(0x38); //显示模式设置,开始要求每次检测忙信号WriteCommand(0x08); //关闭显示0000 1000WriteCommand(0x01); //显示清屏0000 0001WriteCommand(0x06); //显示光标移动设置0000 0110 脱离睡眠模式WriteCommand(0x0C); //显示开及光标设置0000 1100}void LCMClear(){WriteCommand(0x01);delay_ms(5);}void DisplayList(unsigned char X,char *DData){unsigned char length;unsigned char i=0;char *p;p = DData;length = strlen(p);//WriteCommand(0x08);//关闭显示0000 1000WriteCommand(X);//10000000 10010000 10001000 10011000WriteCommand(0x06);//显示光标移动设置0000 0110 脱离睡眠模式WriteCommand(0x0C);//显示开及光标设置0000 1100WriteCommand(X);for(i=0;i<length;i++){WriteData(DData[i]);i++;WriteData(DData[i]);}}BELL//PA7口用一条1pin线连接到小喇叭的jp16#include <mega16.h> //包含型号头文件#include <stdio.h> //标准输入输出头文件#include "bell.h" //包含自定义常量头文件#define uchar unsigned char#define uint unsigned int#pragma interrupt_handler Timer1_Ov:10/*-------------两只老虎-------------*/unsigned char MusicTable2[77]={13,2, 15,2, 17,2, 13,1, 0,1,13,2, 15,2, 17,2, 13,1, 0,1,17,2, 18,2, 20,2, 0,2,17,2, 18,2, 20,2, 0,2,20,1, 22,1, 20,1, 18,1, 17,2, 13,2,20,1, 22,1, 20,1, 18,1, 17,2, 13,2,15,2, 8,2, 13,2, 0,2,15,2, 8,2, 13,2, 0,2,0xff};/*-----------------新年好------------------*/unsigned char MusicTable1[129]={ 13,1, 13,1, 13,2, 8,2,//音符,拍数,17,1, 17,1, 17,2, 13,2,13,1, 17,1, 20,2, 20,2,18,1, 17,1, 15,2, 0,2,15,1, 17,1, 18,2, 18,2,17,1, 15,1, 17,2, 13,2,13,1, 17,1, 15,2, 8,2,12,1, 15,1, 13,2, 0,2,13,1, 13,1, 13,2, 8,2, //音符,拍数,17,1, 17,1, 17,2, 13,2,13,1, 17,1, 20,2, 20,2,18,1, 17,1, 15,2, 0,2,15,1, 17,1, 18,2, 18,2,17,1, 15,1, 17,2, 13,2,13,1, 17,1, 15,2, 8,2,12,1, 15,1, 13,2, 0,2,0xff};//0, 1, #1, 2, #2, 3, 4, #4, 5, #5, 6, #6, 7,uintToneTable[37]={ZERO,DO_L,DOA_L,RE_L,REA_L,MI_L,FA_L,FAA_L,SO_L,SOA_L,LA_L, LAA_L,TI_L,DO ,DOA ,RE ,REA ,MI ,FA ,FAA ,SO ,SOA ,LA ,LAA ,TI ,DO_H,DOA_H,RE_H,REA_H,MI_H,FA_H,FAA_H,SO_H,SOA_H,LA_H,LAA_H,TI_H};uint tone;/*******************************************函数名称: Timer1_Ov功能: 定时器1溢出中断服务函数(完成单个音的产生)参数: 无返回值: 无********************************************/void Timer1_Ov(void){if(tone)//若不是休止符,则发声{TCNT1=tone; //计数值装入寄存器PORTA^=BIT(BEEP);//蜂鸣器接口电平翻转}}/*******************************************函数名称: Timer1_init功能: Timer1的初始化参数: 无返回值: 无********************************************/void Timer1_init(void){TCCR1A=0x00; //普通端口操作TCCR1B=0x01; //8分频SREG|=0x80; //开放全局中断}/*******************************************函数名称: Music功能: 完成整曲的音乐演奏参数: pmusic--曲谱数组指针返回值: 无********************************************/void Music(unsigned char *pMusic){while(*pMusic!=0xFF) //0xFF为音乐结尾符{TIMSK=0x04; //Timer1溢出中断使能tone=ToneTable[*pMusic]; //取音调频率TCNT1=tone; //将频率值对应的计数值写入计时器,开始发声pMusic++; //乐谱音符指针+1 ,取拍数Delayms((*pMusic)*10); //按拍数延时Delayms((*pMusic)*10);TIMSK=0x00; //发声结束,屏蔽Timer1溢出中断pMusic++; //乐谱音符指针+1 ,取下一音符}Delayms(1000); //曲谱结束,等待}主函数#include <mega16.h>#include <delay.h>#include "12864.c"#include "ds1302.c"#include "ds1820.c"#include "bell.c"#define uchar unsigned char#define uint unsigned intuchar x[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x 29,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x60,0x6 1,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x7 8,0x79,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x90,0x91,0x92,0x93,0x94,0x9 5,0x96,0x97,0x98,0x99};uchar led_buf[5],y[3]={0x00,0x00,0x10};char char_1[]={"闹钟:09:00:00"};char char_2[]={"2014年05月05日"};char char_3[]={"时间:00:00:00"};char char_4[]={"温度:20.1℃"};char char_5[]={"00: 00: 00"};char char1[]={" 课程设计"};char char2[]={" 1.时钟显示"};char char3[]={" 2.日历显示"};char char4[]={" 3.闹钟信号"};char char5[]={" 4.温度显示"};char char6[]={" 5.记事本"};char char7[]={" 6.秒表"};void clock(){ds1302_read_time();if(y[0]==time_buf[4]&&y[1]==time_buf[5]&&y[2]==time_buf[6]) {LCMInit();Board_init( ); //初始化开发板/Timer1_init(); //Timer1初始化while(1){ds1302_read_time();DisplayList(0x80,"闹钟时间到~");DisplayList(0x88,char_1);//DisplayList(0x98,"按键七可退出闹钟");PORTA.4=0;delay_ms(500);PORTA.4=1;delay_ms(500);if((PINB&(1<<7))==0){PORTA.4=1;LCMInit();break;}}}}void timedisplay(){int a,b,count=0;while(1){clock();//DisplayList(0x80,"可调时钟");//DisplayList(0x88,"按键一:加");//DisplayList(0x98,"按键二:减");ds1302_read_time();char_3[6] = (time_buf[4] >> 4) + '0';/*时*/char_3[7] = (time_buf[4] & 0x0F) + '0';char_3[10] = (time_buf[5] >> 4) + '0';/*分*/char_3[11] = (time_buf[5] & 0x0F) + '0';char_3[14] = (time_buf[6] >> 4) + '0';/*秒*/char_3[15] = (time_buf[6] & 0x0F) + '0'; DisplayList(0x90,char_3);for(a=0;a<60;a++) //分if(x[a]==time_buf[5])break;for(b=0;b<24;b++) //时if(x[b]==time_buf[4])break;if((PINB&(1<<0))==0){count++;}if(count==1){delay_ms(30);DisplayList(0x95," ");delay_ms(20);if((PINB&(1<<1))==0){a++;if(a==60)a=0;time_buf[5]=x[a];ds1302_write_byte(0x82,time_buf[5]);delay_ms(5);ds1302_write_time();}if((PINB&(1<<2))==0){a--;if(a<0)a=59;time_buf[5]=x[a];ds1302_write_byte(0x82,time_buf[5]);delay_ms(5);ds1302_write_time();}}if(count==2){delay_ms(30);DisplayList(0x93," ");delay_ms(20);if((PINB&(1<<1))==0){b++;if(b==24)b=0;time_buf[4]=x[b];ds1302_write_byte(0x84,time_buf[4]);delay_ms(5);ds1302_write_time();}if((PINB&(1<<2))==0){b--;if(b<0)b=23;time_buf[4]=x[b];ds1302_write_byte(0x84,time_buf[4]);delay_ms(5);ds1302_write_time();}}if(count==3){count=0;}if((PINB&(1<<7))==0){break;LCMInit();}}}void setclock(){int i=0,j=0,account=0;ds1302_read_time();char_1[6] = (y[0] >> 4) + '0';/*时*/char_1[7] = (y[0] & 0x0F) + '0';char_1[10] = (y[1] >> 4) + '0';/*分*/char_1[11] = (y[1] & 0x0F) + '0';char_1[14] = (y[2] >> 4) + '0';/*秒*/char_1[15] = (y[2] & 0x0F) + '0';for(i=0;i<60;i++) //分if(x[i]==y[1])break;for(j=0;j<24;j++) //时if(x[j]==y[0])break;while(1){clock();//DisplayList(0x80,"闹钟设定");//DisplayList(0x88,"按键一:加");//DisplayList(0x98,"按键二:减");DisplayList(0x90,char_1);ds1302_read_time();if((PINB&(1<<0))==0){account++;}if(account==1){delay_ms(30);DisplayList(0x95," ");delay_ms(20);if((PINB&(1<<1))==0){i++;if(i==60)i=0;y[1]=x[i];char_1[10] = (y[1] >> 4) + '0';/*分*/char_1[11] = (y[1] & 0x0F) + '0';ds1302_write_byte(0x82,y[1]);delay_ms(5);ds1302_write_time();}if((PINB&(1<<2))==0){i--;if(i<0)i=59;y[1]=x[i];char_1[10] = (y[1] >> 4) + '0';/*分*/char_1[11] = (y[1] & 0x0F) + '0';ds1302_write_byte(0x82,y[1]);delay_ms(5);ds1302_write_time();}}if(account==2){delay_ms(30);DisplayList(0x93," ");delay_ms(20);if((PINB&(1<<1))==0){j++;if(j==24)j=0;y[0]=x[j];char_1[6] = (y[0] >> 4) + '0';/*时*/char_1[7] = (y[0] & 0x0F) + '0';ds1302_write_byte(0x84,y[0]);delay_ms(5);ds1302_write_time();}if((PINB&(1<<2))==0){j--;if(j<0)j=23;y[0]=x[j];char_1[6] = (y[0] >> 4) + '0';/*时*/char_1[7] = (y[0] & 0x0F) + '0';ds1302_write_byte(0x84,y[0]);delay_ms(5);ds1302_write_time();}}if(account==3){account=0;}if((PINB&(1<<7))==0){break;LCMInit();}}}void datedisplay(){int c,d,e,f,count=0;while(1){clock();//DisplayList(0x80,"可调日历");//DisplayList(0x88,"按键一:加");//DisplayList(0x98,"按键二:减");ds1302_read_time();char_2[0] = (time_buf[0] >> 4) + '0';/*年*/char_2[1] = (time_buf[0] & 0x0F) + '0';char_2[2] = (time_buf[1] >> 4) + '0';char_2[3] = (time_buf[1] & 0x0F) + '0';char_2[6] = (time_buf[2] >> 4) + '0';/*月*/char_2[7] = (time_buf[2] & 0x0F) + '0';char_2[10] = (time_buf[3] >> 4) + '0';/*日*/char_2[11] = (time_buf[3] & 0x0F) + '0';DisplayList(0x90,char_2);for(c=0;c<32;c++) //天if(x[c]==time_buf[3])break;for(d=0;d<13;d++) //月if(x[d]==time_buf[2])break;for(e=0;e<99;e++) //年if(x[e]==time_buf[1])break;for(f=0;f<21;f++)if(x[f]==time_buf[0])break;if((PINB&(1<<0))==0){count++;}if(count==1){delay_ms(30);DisplayList(0x95," ");delay_ms(20);if((PINB&(1<<1))==0){c++;if(c==31)c=0;time_buf[3]=x[c];ds1302_write_byte(0x86,time_buf[3]);delay_ms(5);ds1302_write_time();}if((PINB&(1<<2))==0){c--;if(c<0)c=31;time_buf[3]=x[c];ds1302_write_byte(0x86,time_buf[3]);delay_ms(5);ds1302_write_time();}}if(count==2){delay_ms(30);DisplayList(0x93," ");delay_ms(20);if((PINB&(1<<1))==0){d++;if(d==13)d=1;time_buf[2]=x[d];ds1302_write_byte(0x88,time_buf[2]);delay_ms(5);ds1302_write_time();}if((PINB&(1<<2))==0){d--;if(d<1)d=12;time_buf[2]=x[d];ds1302_write_byte(0x88,time_buf[2]);delay_ms(5);ds1302_write_time();}}if(count==3){delay_ms(30);DisplayList(0x91," ");delay_ms(20);if((PINB&(1<<1))==0){e++;if(e==100){e=0;if(++f==22)f=0;time_buf[0]=x[f];}time_buf[1]=x[e];ds1302_write_byte(0x8c,time_buf[1]);delay_ms(5);ds1302_write_time();}if((PINB&(1<<2))==0){e--;if(e<0){e=99;if(--f<0)f=21;time_buf[0]=x[f];}time_buf[1]=x[e];ds1302_write_byte(0x8c,time_buf[1]);delay_ms(5);ds1302_write_time();}}if(count==6){delay_ms(30);DisplayList(0x90," ");delay_ms(20);}if(count==4){count=0;}if((PINB&(1<<7))==0){break;LCMInit();}}}void templedisplay(){char i;while(1){clock();ds1820_start(); /*启动一次转换*/i = ds1820_read_temp(); /*读取温度数值*/i = (i * 10) / 16; /*数值处理*/i = i % 1000;led_buf[2] = i / 100;i = i % 100;led_buf[1] = i / 10;led_buf[0] = i % 10;char_4[6] = led_buf[2]+ '0';char_4[7] = led_buf[1]+ '0';char_4[9] = led_buf[0]+ '0';DisplayList(0x90,"天气预测");DisplayList(0x98,char_4);if((PINB&(1<<7))==0){break;LCMClear();}}}void main(void){bit key=0;LCMInit(); //LCM初始化ds1302_init();delay_ms(10);ds1302_write_time();ds1302_read_time();//端口初始化DDRA=0xff;PORTA=0x10;DDRB=0x00;PORTB=0xff;DDRC=0x00;PORTC=0xff;DDRD=0xff;PORTD=0x00;time_ms(5);time_ms(5);LCMInit(); //LCM初始化DisplayList(0x80," A VR 实验");DisplayList(0x90," 2012112151");DisplayList(0x88," 栗雨然");DisplayList(0x98," 神婆设计");delay_ms(900);while(1){if((PINB&(1<<0))==0){key=~key;}if(key==0){DisplayList(0x80,char1); //显示第一行DisplayList(0x90,char2); //显示第二行DisplayList(0x88,char3); //显示第三行DisplayList(0x98,char4);}if(key==1){DisplayList(0x80,char1); //显示第一行DisplayList(0x90,char5); //显示第二行DisplayList(0x88,char6); //显示第三行DisplayList(0x98,char7);}if((PINB&(1<<1))==0){LCMInit();timedisplay();LCMInit();}if((PINB&(1<<2))==0){LCMInit();datedisplay();LCMInit();}if((PINB&(1<<3))==0){LCMInit();setclock();LCMInit();}if((PINB&(1<<4))==0){LCMInit();templedisplay();LCMInit();}if((PINB&(1<<5))==0){LCMInit();DisplayList(0x90,"啦啦啦啦啦啦");DisplayList(0x88,"我不会~");DisplayList(0x98,"哈哈哈哈哈哈");delay_ms(2000);LCMInit();}if((PINB&(1<<6))==0){LCMInit();//miaobiao();LCMInit();}clock();}}七、课程显示八、课程心得通过A VR的课程学习,我们基本了解了A VR的DS1302、DS18B20、DS12864的功能设计,学习了单片机的基本操作功能,知道了A VR跑马灯、继电器、8路指示灯8路开关、数码管的静态显示、数码管的动态显示、端口按键判断技术、矩阵按键识别技术、12864及74LS17的基本操作和功能,依靠先前所学技术,逐步实现数字时钟的功能设计。

相关文档
最新文档