单片机
返回首页

PIC16F877A DS1302芯片驱动

2016-11-04 来源:eefocus

  1. #include  
  2. typedef unsigned char uchar;  
  3. typedef unsigned int uint;  
  4. #define rs_h PORTC|=0x01  
  5. #define rs_l PORTC&=0xfe  
  6. #define rw_h PORTC|=0x02  
  7. #define rw_l PORTC&=0xfd  
  8. #define en_h PORTC|=0x04   
  9. #define en_l PORTC&=0xfb  
  10. #define rst_h PORTC|=0x08  
  11. #define rst_l PORTC&=0xf7  
  12. #define sck_h PORTC|=0x10  
  13. #define sck_l PORTC&=0xef  
  14. #define io_h PORTC|=0x20  
  15. #define io_l PORTC&=0xdf  
  16. #define SECADD 0X80//秒寄存器地址  
  17. #define MINADD 0x82  
  18. #define HRADD 0x84  
  19. #define DATEADD 0x86  
  20. #define MONTHADD 0x88  
  21. #define DAYADD 0x8a  
  22. #define YEARADD 0x8c  
  23. #define CONTROLADD 0x8e  
  24. #define PORT (PORTB)  
  25. void delayms(uint x);  
  26. void lcd_com(uchar com);  
  27. void lcd_dat(uchar dat);  
  28. void lcd_write(uchar c,uchar r,uchar dat);  
  29. void lcd_init(void);  
  30. void Ds1302Init(void);  
  31. void WriteByte(uchar dat);  
  32. uchar ReadByte(void);  
  33. uchar BCDtoDex(uchar dat);  
  34. uchar DextoBCD(uchar dat);  
  35. uchar ReadByte(void);  
  36. void Ds1302Write(uchar add,uchar dat);  
  37. uchar Ds1302Read(uchar add);  
  38.   
  39. void main(void)  
  40. {  
  41.     uchar sec,min,hr,date,month,day,year;  
  42.     TRISB=0x00;  
  43.     TRISC&=0xc0;  
  44.     lcd_init();  
  45.     Ds1302Init();  
  46.     while(1)  
  47.     {  
  48.         sec=Ds1302Read(SECADD);  
  49.         min=Ds1302Read(MINADD);  
  50.         hr=Ds1302Read(HRADD);  
  51.         date=Ds1302Read(DATEADD);  
  52.         month=Ds1302Read(MONTHADD);  
  53.         day=Ds1302Read(DAYADD);  
  54.         year=Ds1302Read(YEARADD);  
  55.   
  56.         sec=BCDtoDex(sec);  
  57.         min=BCDtoDex(min);  
  58.         hr=BCDtoDex(hr);  
  59.         date=BCDtoDex(date);  
  60.         month=BCDtoDex(month);  
  61.         day=BCDtoDex(day);  
  62.         year=BCDtoDex(year);  
  63.   
  64.         lcd_write(0,1,0x32);  
  65.         lcd_write(0,2,0x30);  
  66.         lcd_write(0,3,0x30+year/10);  
  67.         lcd_write(0,4,0x30+year%10);  
  68.         lcd_write(0,6,0x30+month/10);  
  69.         lcd_write(0,7,0x30+month%10);  
  70.         lcd_write(0,9,0x30+date/10);  
  71.         lcd_write(0,10,0x30+date%10);  
  72.         lcd_write(0,14,0x30+day);  
  73.         lcd_write(1,4,0x30+hr/10);  
  74.         lcd_write(1,5,0x30+hr%10);  
  75.         lcd_write(1,7,0x30+min/10);  
  76.         lcd_write(1,8,0x30+min%10);  
  77.         lcd_write(1,10,0x30+sec/10);  
  78.         lcd_write(1,11,0x30+sec%10);  
  79.         delayms(1005);//1ms  
  80.     }  
  81.   
  82. }  
  83. void Ds1302Init(void)  
  84. {  
  85.     rst_l;  
  86.     sck_l;  
  87.     Ds1302Write(CONTROLADD,0);//关闭写保护  
  88.     Ds1302Write(MINADD,DextoBCD(06));  
  89.     Ds1302Write(HRADD,DextoBCD(19));  
  90.     Ds1302Write(DATEADD,DextoBCD(20));  
  91.     Ds1302Write(MONTHADD,DextoBCD(5));  
  92.     Ds1302Write(DAYADD,DextoBCD(7));  
  93.     Ds1302Write(YEARADD,DextoBCD(12));  
  94.     Ds1302Write(SECADD,DextoBCD(30));//写秒,同时启动时钟  
  95. }  
  96. void WriteByte(uchar dat)//上升沿输出  
  97. {  
  98.     uchar i;  
  99.     TRISC&=0xdf;  
  100.     for(i=8;i>0;i--)  
  101.     {  
  102.         sck_l;//低电平时数据线可变  
  103.         if(dat&0x01)  
  104.             io_h;  
  105.         else  
  106.             io_l;  
  107.         sck_h;  
  108.         dat>>=1;  
  109.     }  
  110. }  
  111. uchar BCDtoDex(uchar dat)//BCD码转十进制  
  112. {  
  113.     uchar i;  
  114.     i=dat/16;  
  115.     dat%=16;  
  116.     i=i*10+dat;  
  117.     return i;  
  118. }  
  119. uchar DextoBCD(uchar dat)//十进制转BCD码  
  120. {  
  121.     uchar i;  
  122.     i=dat/10;  
  123.     dat%=10;  
  124.     i=i*16+dat;  
  125.     return i;  
  126. }  
  127. uchar ReadByte(void)//下降沿输出  
  128. {  
  129.     uchar i;  
  130.     uchar dat;  
  131.     TRISC|=0x20;  
  132.     for(i=8;i>0;i--)//要考虑之前写完后的状态,第一次进入此循环体即有下降沿  
  133.     {  
  134.         dat>>=1;  
  135.         sck_l;  
  136.         if(PORTC&0x20)  
  137.             dat|=0x80;  
  138.         sck_h;    
  139.     }  
  140.     return dat;  
  141. }  
  142. void Ds1302Write(uchar add,uchar dat)  
  143. {  
  144.     rst_l;  
  145.     sck_l;  
  146.     rst_h;  
  147.     WriteByte(add);//最低位置0表示写  
  148.     WriteByte(dat);  
  149.     rst_l;  
  150. }  
  151. uchar Ds1302Read(uchar add)  
  152. {  
  153.     uchar dat;  
  154.     rst_l;  
  155.     sck_l;  
  156.     rst_h;  
  157.     WriteByte(add+1);//地址最低位置1表示读  
  158.     dat=ReadByte();  
  159.     rst_l;  
  160.     return dat;  
  161. }  
  162. void delayms(uint x) //8M晶振下,延时1ms  
  163. {  
  164.     uint y,z;  
  165.     for(y=x;y>0;y--)  
  166.         for(z=220;z>0;z--);  
  167. }  
  168. void lcd_init(void)//LCD1602初始化  
  169. {  
  170.     lcd_com(0x38);  
  171.     lcd_com(0x0c);  
  172.     lcd_com(0x06);  
  173.     lcd_write(0,5,0xb0);  
  174.     lcd_write(0,8,0xb0);  
  175.     lcd_write(1,6,0x3a);  
  176.     lcd_write(1,9,0x3a);  
  177. }  
  178. void lcd_com(uchar com)//向LCD1602写命令  
  179. {  
  180.     rs_l;  
  181.     rw_l;  
  182.     PORT=com;  
  183.     delayms(1);  
  184.     en_h;  
  185.     delayms(1);   
  186.     en_l;  
  187. }  
  188. void lcd_dat(uchar dat)//向LCD1602写数据  
  189. {  
  190.     rs_h;  
  191.     rw_l;  
  192.     PORT=dat;  
  193.     delayms(1);  
  194.     en_h;  
  195.     delayms(1);  
  196.     en_l;  
  197. }  
  198. void lcd_write(uchar c,uchar r,uchar dat)//向LCD1602指定行、指定列、写数据  
  199. {  
  200.     lcd_com(0x80+0x40*c+r);  
  201.     lcd_dat(dat);  
  202.     delayms(1);  
  203. }  

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • CCD图像传感器在微光电视系统中的应用

  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 离子检测器电路分析

  • 一个简单的警笛电路图

  • 分享一个电网倾角计电路

  • 一种构建12V和230V双直流电源的简单方法

    相关电子头条文章