发一个基于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
- #include
- #include
- #define uchar unsigned char
- #define uint unsigned int
- /**********位操作定义******************/
- #define ***it(x,PORT) (PORT) |= (1<#define cbit(x,PORT) (PORT) &= ~(1<#define pin(x,PIN) (PIN)&(1</**********端口定义*******************/
- /********LCD控制端口********/
- #define S_RS ***it(0,PORTD)
- #define C_RS cbit(0,PORTD)
- #define S_RW ***it(1,PORTD)
- #define C_RW cbit(1,PORTD)
- #define S_E ***it(2,PORTD)
- #define C_E cbit(2,PORTD)
- #define out PORTC
- #define check_busy_bit pin(7,PINC)
- /********DS1302控制端口********/
- #define S_RST ***it(0,PORTB)
- #define C_RST cbit(0,PORTB)
- #define S_SCLK ***it(1,PORTB)
- #define C_SCLK cbit(1,PORTB)
- #define S_IO ***it(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);
- }
|