|
51单片机自动打铃器仿真电路原理图(工程文件清晰版请下载本帖最后的附件),采用实时日历时钟芯片pcf8563提供准确的时钟.
下面是51单片机自动打铃器pcf8563芯片的驱动程序:- #include <AT89X52.h>
- #include <stdio.h>
- bit bclassFlg = 0;
- sbit FMQ = P3 ^ 7;
-
- unsigned char stringtemp[10]="";
- struct time
- {
- unsigned char second;
- unsigned char minute;
- unsigned char hour;
- unsigned char day;
- unsigned char weekday;
- unsigned char month;
- unsigned int year;
- } time;
- sbit tim_sda=P2^6;
- sbit tim_scl=P2^7;
- sbit lcd16rs = P2^0;
- sbit lcd16rw = P2^1;
- sbit lcd16en = P2^2;
- unsigned char lcd16_1[16];
- unsigned char lcd16_2[16] = {"welcome"};
- bit tim_ack; // i2c slave ack.
- bit tim_err;
- unsigned char tim_rd_buffer[16];
- unsigned char tim_wr_buffer[16];
- /*****************11us延时函数*************************/
- void delay11us(unsigned char t)
- {
- for (;t>0;t--);
- }
- void delay(unsigned int x)
- {
- unsigned int a,b;
- for(a=x;a>5;a--);
- for(b=10;b>0;b--);
- }
- //写指令
- void write_com(unsigned char com)
- {
- P1=com;// 将指令值写到数据线上
- lcd16rs=0;//写指令
- lcd16en=0;//给一个LCD 使能脉冲
- delay(10);
- lcd16en=1;
- delay(10);
- lcd16en=0;
-
- }
- //写数据
- void write_date(unsigned char date)
- {
- P1=date; //将数据写到数据线上
- lcd16rs=1; //写数据
- lcd16en=0; //给一个LCD 使能脉冲
- delay(10);
- lcd16en=1;
- delay(10);
- lcd16en=0;
-
- }
- //初始化LCD
- void lcd_init()
- {
- lcd16rw = 0;
- write_com(0x38);//显示模式设置
- delay(20);
- write_com(0x0f);//开显示,显示光标、光标闪烁
- delay(20);
- write_com(0x06);//光标和显示指针加一,屏幕不移动
- delay(20);
- write_com(0x01);//清显示屏
- delay(20);
- }
- //在第N行显示第M个字
- void lcd16_n_line_n_byte(unsigned char n_line,unsigned char n_byte)
- {
- unsigned char j;
- unsigned char com;
- unsigned char *dat1;
- unsigned char *dat2;
- dat1 = lcd16_1;
- dat2 = lcd16_2;
- if(n_line==0) //显示第一行。
- {
- for(j=0;j<n_byte;j++)
- {
- com = 0x80+j;
- write_com(com);
- write_date(*dat1);
- dat1++;
- }
- }
- if(n_line==1) //显示第二行。
- {
- for(j=0;j<n_byte;j++)
- {
- com = 0xc0+j;
- write_com(com);
- write_date(*dat2);
- dat2++;
- }
- }
- }
- // i2c start.
- void PCF8563_start() //start flag is when tim_scl 1, tim_sdafrom 1 to 0.
- {
- tim_sda = 1;
- delay11us(1);
- tim_scl = 1;
- delay11us(1);
- tim_sda = 0;
- delay11us(1);
- }
- // i2c stop.
- void PCF8563_stop() //start flag is when tim_scl 1, tim_sdafrom 0 to 1.
- {
- tim_sda = 0;
- delay11us(1);
- tim_scl = 1;
- delay11us(1);
- tim_sda = 0;
- }
- //i2c slave respons.
- void PCF8563_respons()
- {
- unsigned char i;
- tim_scl = 1;
- delay11us(1);
- while((tim_sda)&&(i<250)) i++;
- if(!tim_sda)
- tim_ack = 1;
- else
- tim_ack = 0;
- tim_scl = 0;
- delay11us(1);
- }
- // i2c master respons.
- void PCF8563_master_respons(bit master_ack)
- {
- tim_scl = 0;
- delay11us(1);
- tim_sda = ~master_ack;
- delay11us(1);
- tim_scl = 1;
- delay11us(1);
- tim_scl = 0;
- delay11us(1);
- }
- //i2c init.
- void PCF8563_init()
- {
- tim_sda = 1;
- delay11us(1);
- tim_scl = 1;
- delay11us(1);
- }
- // i2c write n byte.
- void PCF8563_wr_byte(unsigned char dat)
- {
- unsigned char i , temp;
- temp = dat;
- for(i=0;i<8;i++)
- {
- tim_scl = 0;
- delay11us(1);
-
- if(temp&0x80)
- tim_sda = 1;
- else
- tim_sda = 0;
- temp = temp<<1;
-
- delay11us(1);
- tim_scl = 1;
- delay11us(1);
- }
- tim_scl = 0;
- delay11us(1);
- tim_sda = 1;
- delay11us(1);
- }
- unsigned char PCF8563_rd_byte()
- {
- unsigned char i,k;
- tim_scl = 0;
- delay11us(1);
- tim_sda = 1;
- delay11us(1);
- for(i=0;i<8;i++)
- {
- tim_scl = 1;
- delay11us(1);
- k = (k<<1)|tim_sda;
- tim_scl = 0;
- delay11us(1);
- }
- return k;
- }
- void PCF8563_write_n_byte(unsigned char add,unsigned char com,unsigned char *dat,unsigned char n_byte) //
- {
- unsigned char i = 0;
- unsigned char temp;
- temp = *dat; // send to begin address to 'temp'.
- add = add<<1;
- add = 0xa0+add+0x00;
- PCF8563_start();
- PCF8563_wr_byte(add); //send EEPROM address, bit 0 = 0 is write.
- PCF8563_respons();
- if(!tim_ack) //if i2c respons.
- {
- tim_err = 1;
- return;
- }
-
- PCF8563_wr_byte(com); //send EEPROM beginning address.
- PCF8563_respons();
- if(!tim_ack) //if i2c respons.
- {
- tim_err = 1;
- return;
- }
-
- while(n_byte) //write n byte.
- {
- PCF8563_wr_byte(temp);
- PCF8563_respons();
- if(!tim_ack)
- {
- tim_err = 1;
- PCF8563_stop();
- return;
- }
- temp++;
- n_byte--;
- }
-
- PCF8563_stop();
- }
- void PCF8563_read_n_byte(unsigned char add,unsigned char com,unsigned char n_byte)
- {
- unsigned char *temp;
- temp = tim_rd_buffer;
- add = add<<1;
- add = 0xa0+add+0x00;
- PCF8563_start();
- PCF8563_wr_byte(add); //send address + wr.
- PCF8563_respons();
- PCF8563_wr_byte(com); // first byte address.
- PCF8563_respons();
- add = add+0x01;
- PCF8563_start();
- PCF8563_wr_byte(add); //send address + rd.
- PCF8563_respons();
- while(n_byte) // rd n byte .
- {
- *temp = PCF8563_rd_byte();
- if(n_byte != 1) //if i2c respons.
- {
- PCF8563_master_respons(1); //if the number is not the last one, master send a ack bit.
- }
- temp++;
- n_byte--;
- }
- PCF8563_stop();
- }
- void PCF8563_wr_time()
- {
- tim_wr_buffer[0] = 0x00; //second
- tim_wr_buffer[1] = 0x11; //minute
- tim_wr_buffer[2] = 0x22; //hour
- tim_wr_buffer[3] = 0x15; //day
- tim_wr_buffer[4] = 0x03; //weekday
- tim_wr_buffer[5] = 0x06; //month
- tim_wr_buffer[6] = 0x10; //year
-
- PCF8563_write_n_byte(1,2,tim_wr_buffer,8);
- }
- //延时眼熟
- void DelayFM(unsigned int x)
- {
- unsigned char t;
- while(x--)
- {
- for(t=0;t<120;t++);
- }
- }
- //蜂鸣器驱动函数,参数为发声声调
- void FM(unsigned char x)
- {
- unsigned char i;
- for(i=0;i<100;i++)
- {
- FMQ = ~FMQ;
- DelayFM(x);
- }
- FMQ = 0;
- }
- void PCF8563_rd_time()
- {
- unsigned char temp;
- PCF8563_read_n_byte(1,2,9);
- time.second = ((tim_rd_buffer[1]&0x70)>>4)*10 + (tim_rd_buffer[1]&0x0f); //second
- time.minute = ((tim_rd_buffer[2]&0x70)>>4)*10 + (tim_rd_buffer[2]&0x0f); //minute
- time.hour = ((tim_rd_buffer[3]&0x30)>>4)*10 + (tim_rd_buffer[3]&0x0f); //hour
- time.day = ((tim_rd_buffer[4]&0x30)>>4)*10 + (tim_rd_buffer[4]&0x0f); //day
- time.weekday = tim_rd_buffer[5]&0x07; //weekday
- time.month = ((tim_rd_buffer[6]&0x10)>>4)*10 + (tim_rd_buffer[6]&0x0f); //month
- if(time.second == 0)
- {
- if(bclassFlg == 0 )
- {
- sprintf(stringtemp,"%x%x",time.hour,time.minute);
- // printf("%s\n",stringtemp);
- printf("it's time to have class\n"); //上课
- bclassFlg = 1;
- FM(3);
- }
- }
- else if(time.second == 45) //如果到了45分钟,开始下课铃
- {
- if(bclassFlg == 1)
- {
- sprintf(stringtemp,"%x%x",time.hour,time.minute);
- // printf("%s\n",stringtemp);
- printf("it's time to finish class\n");
- bclassFlg = 0;
- FM(7);
- }
- }
- else
- {
- }
- temp = (tim_rd_buffer[4]&0x80)>>7;
- time.year = (temp+20)*100+((tim_rd_buffer[7]&0x70)>>4)*10 + (tim_rd_buffer[7]&0x0f); //year
- lcd16_1[0] = time.hour/10+0x30; //hour
- lcd16_1[1] = time.hour%10+0x30;
- lcd16_1[2] = '-';
- lcd16_1[3] = time.minute/10+0x30; //minute
- lcd16_1[4] = time.minute%10+0x30;
- lcd16_1[5] = '-';
- lcd16_1[6] = time.second/10+0x30; //second
- lcd16_1[7] = time.second%10+0x30;
- lcd16_2[0] = time.year/1000+0x30; //year
- lcd16_2[1] = (time.year%1000)/100+0x30;
- lcd16_2[2] = (time.year%100)/10+0x30;
- lcd16_2[3] = time.year%10+0x30;
- lcd16_2[4] = '-';
- lcd16_2[5] = time.month/10+0x30; //mon
- lcd16_2[6] = time.month%10+0x30;
- lcd16_2[7] = '-';
- lcd16_2[8] = time.day/10+0x30; //day
- lcd16_2[9] = time.day%10+0x30;
- lcd16_2[10] = 'w';
- lcd16_2[11] = 'e';
- lcd16_2[12] = 'e';
- lcd16_2[13] = 'k';
- lcd16_2[14] = ':';
- lcd16_2[15] = time.weekday+0x30;
- lcd16_n_line_n_byte(0,16);
- lcd16_n_line_n_byte(1,16);
- }
- void DelayMS(unsigned int ms)
- {
- unsigned char i;
- while(ms--)
- {
- for(i=0;i<120;i++);
- }
- }
- void InitUart(void)
- {
- SCON = 0x50; //工作方式1
- TMOD = 0x21;
- PCON = 0x00;
- TH1 = 0xfd; //使用T1作为波特率发生器
- TL1 = 0xfd;
- TI = 1;
- TR1 = 1; //启动T1 //启动T1
- }
- void main()
- {
- PCF8563_init();
- // PCF8563_wr_time();
- lcd_init();
- InitUart();
- while(1)
- {
- PCF8563_rd_time();
- DelayMS(250);
- }
- }
复制代码
51单片机pcf8563自动打铃器仿真的所有资料下载:http://www.51hei.com/bbs/dpj-54940-1.html
|
|