单片机源程序如下:
/****************************************************
电路图说明:
将单片机P2.7和P1.0分别与RTC(实时时钟)的时钟信号SCL端
和数据信号SDA端相连, RTC的sout引脚与单片机P3.2相连,RTC的
地址是11010000.独立键盘k0~K3接P1.1~P1.3
程序功能:
使用时钟芯片ds1307制作一个实时时钟
******************************************************/
#include #include #define uchar unsigned char #define uint unsigned int //实时时钟两信号线 sbit scl=P2^7; sbit sda=P1^0; //独立键盘扫描位 sbit k0=P1^1; sbit k1=P1^2; sbit k2=P1^3; //液晶显示器控制位 sbit lcd_rs=P3^4; sbit lcd_e=P3^5; //数码管和led锁存器选通位 sbit duan=P2^0; sbit wei=P2^1; sbit led=P2^2; void init();//初始化IIC总线,使总线处于备用状态, //初始化lcd并显示上面table1和table2的值,初始化定时器0,初始化变量时分秒 /****************IIC总线控制函数***************************/ void IIC_start();//IIC通信开始信号 void IIC_stop();//IIC通信停止信号 void IIC_un_ack();//单片机发送非应答位 //void IIC_ack();//单片机发送应答位 void IIC_check_ack();//单片机检查应答位 void IIC_write_byte(uchar);//发送一字节数据 uchar IIC_read_byte();//接收一字节数据 void nop();//5us空操作延迟 /**********************************/ /**********ds1307读写函数*******************/ void ds1307_write_date(uchar ,uchar ,uchar);//向指定器件写一字节数据 //参数1器件地址,参数2要存的数据存放位置8位地址 //参数3要写的数据 uchar ds1307_read_date(uchar ,uchar );//从指定器件读一字节数据, //参数1被通信器件地址,参数2要读的数据存放位置8位地址 //函数返回读取的数据。 void delay(uint);//基数1ms延迟程序 /***********************************/ /**************LCD操作函数**************************/ uchar hour,minute,second,k0_num;//时分秒变量,菜单键k0第几次按下计数,ds1307跟新标志 //时钟初显示 uchar code table1[]="2017-11-16 THUR"; uchar code table2[]=" 23:59:55 "; void lcd_write_com(uchar);//向液晶显示器写指令设置其显示的格式 void lcd_write_date(uchar);//向液晶显示器写显示的数据 /**********************************************/ /**************时钟函数*******************/ void lcd_write_second(uchar);//向lcd写秒 void lcd_write_minute(uchar);//向lcd写分 void lcd_write_hour(uchar);//向lcd写时 void run_time();//时钟走动显示 void keyscan();//菜单键扫描 /****************************************/ /*********十进值与BCD码之间互换**********/ uchar b_second,b_minute,b_hour; uchar dectobcd(uchar);//十进值转bcd码 uchar bcdtodec(uchar);//bcd码转十进值 /****************************************/ void main() { init(); while(1) { keyscan(); } } void nop() { _nop_();_nop_();_nop_(); _nop_();_nop_();_nop_(); } void init() { uchar i; //将数据线和时钟线拉高,处于备用状态即非忙 sda=1; nop(); scl=1; nop(); //关数码管显示和8个LED显示 duan=0; wei=0; led=0; lcd_e=0; //初始化写入LCD的时分秒 second=55; minute=59; hour=23; //初始化ds1307 ds1307_write_date(0xd0,0x07,0x10);//初始化1307的控制字,使其SOUT引脚输出1Hz的方波。 //初始化1307的时间 ds1307_write_date(0xd0,6,0x14); ds1307_write_date(0xd0,5,0x06); ds1307_write_date(0xd0,4,0x09); ds1307_write_date(0xd0,3,0x00); ds1307_write_date(0xd0,2,0x23); ds1307_write_date(0xd0,1,0x59); ds1307_write_date(0xd0,0,0x55); //初始化液晶显示器 lcd_write_com(0x38);//设置16*2行,5*7点阵,8位数据接口 lcd_write_com(0x06);//写字符指针和光标自动向右移动 lcd_write_com(0x0c);//开显示,不显示光标,光标不闪烁 lcd_write_com(0x01);//显示清屏 for(i=0;i<15;i++) { lcd_write_date(table1[i]); } lcd_write_com(0x80+0x40); for(i=0;i<10;i++) { lcd_write_date(table2[i]); } //开启外部中断0 EA=1; EX0=1; IT0=1; } void IIC_start() { //在时钟信号有效scl=1时,数据线负跳变 sda=1; nop(); scl=1; nop(); sda=0; nop(); scl=0;//拉低为下个时钟数据作准备 nop(); } void IIC_stop() { //在时钟信号有效scl=1时,数据线正跳变,释放总线,使总线处于备用状态即非忙 sda=0; nop(); scl=1; nop(); sda=1; nop(); nop(); nop(); } void IIC_un_ack() { //时钟信号有效时,sda给1,给出非应答 sda=1; nop(); scl=1; nop(); scl=0;//拉低为下个时钟数据作准备 nop(); } /* void IIC_ack() { //时钟信号有效时,sda给0,给出应答 sda=0; nop(); scl=1; nop(); scl=0;//拉低为下个时钟数据作准备 nop(); } */ void IIC_check_ack() { //uchar i; //时钟信号有效时,检测数据信号sda是否为0,给0说明有应答信号 scl=1; //while((sda==1)&&(i<255)) i++; nop(); scl=0;//拉低为下个时钟数据作准备 nop(); } uchar IIC_read_byte( ) { uchar i,temp;//temp用于存放从数据线读到的数据 for(i=0;i<8;i++)//从数据线读取一个字节(8位) { scl=1; nop(); temp=(temp<<1)|sda;//temp左移,腾出第0位,然后将数据线上的一位数用或 //运算存放到temp的第0位 scl=0;//拉低为下个时钟数据作准备 nop(); } return temp; } void IIC_write_byte(uchar byte) { uchar i; for(i=0;i<8;i++)//向数据线写一个字节(8位) { byte=byte<<1;//左移位,将byte第7位移到PSW中的进位标志位CY中 sda=CY; nop(); scl=1; nop(); scl=0;//拉低为下个时钟数据作准备 nop(); } sda=1;//释放总线,准备接收被控设备应答信号 nop(); } void ds1307_write_date(uchar d_address,uchar r_address,uchar date) { IIC_start(); IIC_write_byte(d_address & (~0x01));//写器件地址,方向是写,所以或上0x00 IIC_check_ack();//等待应答 IIC_write_byte(r_address);//写存储器数据存放的8位地址 IIC_check_ack();//等待应答 IIC_write_byte(date);//写一字节数据 IIC_check_ack();//等待应答 IIC_stop(); } uchar ds1307_read_date(uchar d_address,uchar r_address) { uchar r; IIC_start(); IIC_write_byte(d_address & (~0x01));//写器件地址,方向是写 IIC_check_ack();//等待应答 IIC_write_byte(r_address);//写存储器数据存放的8位地址 IIC_check_ack();//等待应答 //换方向 IIC_start(); IIC_write_byte(d_address|0x01);//写器件地址,方向是读,所以或上1 IIC_check_ack(); r=IIC_read_byte();//读取一个字节数据
上一篇:一个不用中断可立即跳出当前单片机程序运行状态的操作
下一篇:基于STC15F2K60S2的内部AD转换程序(1602显示)
设计资源 培训 开发板 精华推荐
- USB转JTAG+UART下载器
- 消费类电子产品PIC16 MCU开发系统
- LT6656BCDC-2.5、2.5V 扩展电源范围电压基准的典型应用
- sakana-project
- 套件STDES-IDS003V1和STDES-IDS002V1的电源监控板
- PlainDAQ:用于 Raspberry Pi Pico 的简单开源 DAQ 模块(原理图、源码等)
- TDA7388/7850 41w*4 四声道功放模块 车载功放
- 使用 NXP Semiconductors 的 TDA8559 的参考设计
- LTC3803,小巧高效的电信 DC/DC 转换器
- MC78M12ACDTG 12V 电流调节器的典型应用