[问答] 基于avr单片机做的万年历的proteus仿真及源码 原理图

vywyefswer ( 楼主 ) 2018-6-26 04:19:58  显示全部楼层
本帖最后由 一只耳朵怪 于 2018-6-26 10:49 编辑

发一个基于avr单片机做的万年历的proteus仿真,下面是原理图:
  
  


所有资料下载:    DS1302.zip  


源程序:
  • /********************************
  • FILE  NAME:           DS1302.c
  • CHIP  TYPE:           ATMEGA16
  • CLOCK  FREQUENCY:         8MHZ
  • IDE:  AVR Studio 4.15
  • COMPILER:  GCC  4.3.2  avr-libc 1.6.6
  • TIME: 2009/5
  • AUTHOR:         WINDWAY ELECTRONICS GUANGZHOU LIMITED
  • ********************************/
  • #include <avr/io.h>
  • #include <avr/pgmspace.h>
  • #include <util/delay.h>
  • #define uchar unsigned char
  • #define uint unsigned int
  • /**********位操作定义******************/
  • #define sbit(x,PORT) (PORT) |= (1<<x)
  • #define cbit(x,PORT) (PORT) &= ~(1<<x)
  • #define pin(x,PIN) (PIN)&(1<<x)
  • /**********端口定义*******************/
  • /********LCD控制端口********/
  • #define S_RS sbit(0,PORTD)
  • #define C_RS cbit(0,PORTD)
  • #define S_RW sbit(1,PORTD)
  • #define C_RW cbit(1,PORTD)
  • #define S_E  sbit(2,PORTD)
  • #define C_E  cbit(2,PORTD)
  • #define out  PORTC
  • #define check_busy_bit pin(7,PINC)
  • /********DS1302控制端口********/
  • #define S_RST sbit(0,PORTB)
  • #define C_RST cbit(0,PORTB)
  • #define S_SCLK sbit(1,PORTB)
  • #define C_SCLK cbit(1,PORTB)
  • #define S_IO  sbit(2,PORTB)
  • #define C_IO  cbit(2,PORTB)
  • #define IO  pin(2,PINB)
  • #define IO_IN  DDRB&=~(1<<2)
  • #define IO_OUT  DDRB|=(1<<2)
  • /**********函数申明*******************/
  • /********LCD操作函数********/
  • void lcd_initial(void);
  • void write_data(uchar);
  • void write_command(uchar);
  • void check_busy(void);
  • void string(uchar ad,uchar *s);
  • void display(void);
  • /********DS1302操作函数********/
  • void write_byte(uchar);
  • uchar read_byte(void);
  • void wr1302(uchar,uchar);
  • uchar re1302(uchar);
  • void set1302(void);
  • void get1302(uchar curtime[]) ;
  • /**********数据初始化*******************/
  • uchar PROGMEM clock[7]={0x50,0x59,0x23,0x08,0x08,0x04,0x08};
  • uchar time[8];
  • /**********主函数*******************/
  • int main(void)
  • {
  • SPL=0X5F;//堆栈初始化
  • SPH=0X04;
  • DDRB=0XFF;//设PB口输出
  • DDRC=0XFF;//设PC口输出
  • DDRD=0XFF;//设PD口输出
  • out=0xff;
  • PORTB=0XFF;
  • PORTD=0XFF;
  • lcd_initial();
  • set1302( );
  • while(1)
  •         {
  •         get1302(time);
  •         display();
  •         }
  • }
  • /**********LCD控制函数*******************/
  • //LCD初始化
  • void lcd_initial(void)
  • {
  •         _delay_ms(10);
  •         write_command(0x38);//8位总线,双行显示,5X7的点阵字符
  •         write_command(0x0C);//开整体显示,光标关,无黑块
  •         write_command(0x06);//光标右移
  •         write_command(0x01);//清屏
  • }
  • //查忙程序
  • void check_busy(void)
  • {
  • DDRC=0X00;
  • do{
  •         C_E;
  •         C_RS;
  •         S_RW;
  •         S_E;
  •         _delay_us(1);
  •   }while(check_busy_bit);
  • C_E;
  • DDRC=0XFF;
  • _delay_ms(1);
  • }
  • //向LCD写指令
  • void write_command(uchar command)
  • {
  • check_busy();
  • out=command;
  • C_RS;
  • C_RW;
  • S_E;
  • _delay_us(40);
  • C_E;
  • }
  • //向LCD写数据
  • void write_data(uchar dat)
  • {
  • check_busy();
  • out=dat;
  • S_RS;
  • C_RW;
  • S_E;
  • _delay_us(40);
  • C_E;
  • }
  • //显示字符串
  • void string(uchar ad,uchar *s)
  • {
  • write_command(ad);
  • while(*s>0)
  •    {  write_data(*s++);
  •       _delay_ms(100);
  •    }
  • }
  • /**********DS1302控制函数*******************/
  • //八位数据写入函数
  • void write_byte(uchar dat)
  • {
  • uchar i;
  • IO_OUT;
  • for(i=8; i>0; i--)
  •         {
  •         if(dat&0x01)S_IO;else C_IO;
  •         S_SCLK;
  •         C_SCLK;
  •         dat=dat>>1;
  •         }
  • }
  • //八位数据读出函数
  • uchar read_byte(void)
  • {
  • uchar i,temp=0;
  • IO_IN;
  • for(i=8; i>0; i--)
  •         {
  •         temp=temp>>1;
  •         if(IO)temp|=0X80;
  •         S_SCLK;
  •         C_SCLK;
  •         }
  •         return(temp);
  • }
  • //写寄存器函数
  • void wr1302(uchar add,uchar date)
  •   {
  •   C_RST;
  •   C_SCLK;
  •   S_RST;
  •   write_byte(add);
  •   write_byte(date);
  •   S_SCLK;
  •   C_RST;
  •   }
  • //读寄存器函数
  • uchar re1302(uchar add)
  • {
  •   uchar dat;
  •   C_RST;
  •   C_SCLK;
  •   S_RST;
  •   write_byte(add);
  •   dat=read_byte();
  •   S_SCLK;
  •   C_RST;
  •   return(dat);
  •   }
  • //设置时间初值函数
  • void set1302(void)
  •   {
  • uchar i,add=0x80;
  • wr1302(0x8e,0x00);
  • for(i=0;i<8;i++)
  •          {
  •          wr1302(add,pgm_read_byte(&clock));
  •          _delay_us(2);
  •          add+=2;
  •      }
  • wr1302(0x8e,0x00);
  •   }
  • //读当前时间值函数
  • void get1302(uchar curtime[])
  • {
  •     uchar i,add=0x81;
  •     for (i=0;i<7;i++)
  •             {
  •         curtime=re1302(add);
  •         add+=2;         
  •             }
  • }
  • //写显示屏
  • void display(void)
  • {
  •         write_command(0x84);//写年
  •         write_data(time[6]/16+0x30);
  •         write_data(time[6]%16+0x30);
  •         write_data(0x2D); //写“-”
  •         write_command(0x87);//写月
  •         write_data(time[4]/16+0x30);
  •         write_data(time[4]%16+0x30);
  •         write_data(0x2D); //写“-”        
  •         write_command(0x8a);//写日
  •         write_data(time[3]/16+0x30);
  •         write_data(time[3]%16+0x30);
  •         write_command(0xc1);//写星期
  •         write_data(time[5]%16+0x30);
  •         write_command(0xc4);//写时
  •         write_data(time[2]/16+0x30);
  •         write_data(time[2]%16+0x30);
  •         write_data(0x2D); //写“-”
  •         write_command(0xc7);//写分
  •         write_data(time[1]/16+0x30);
  •         write_data(time[1]%16+0x30);
  •         write_data(0x2D); //写“-”
  •         write_command(0xca);//写秒
  •         write_data(time[0]/16+0x30);
  •         write_data(time[0]%16+0x30);                                
  • }

0个回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则


关闭

站长推荐上一条 /9 下一条

小黑屋|手机版|Archiver|电子发烧友 ( 粤ICP备14022951号-2 )

GMT+8, 2018-7-19 10:07 , Processed in 0.342086 second(s), 23 queries , Memcache On.

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表