找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5636|回复: 2
打印 上一主题 下一主题
收起左侧

6312 驱动程序 VFD显示屏 时钟

[复制链接]
跳转到指定楼层
楼主
ID:104835 发表于 2016-2-4 03:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


  1. #include<reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. /*
  5. sbit VFD_REM = P1^7;
  6. sbit VFD_CLK = P1^6;
  7. sbit VFD_STB = P1^5;
  8. sbit VFD_DIN = P1^4;

  9. sbit DS1302_IO=P2^6;
  10. sbit DS1302_CLK=P2^5;
  11. sbit DS1302_RST=P2^7;

  12. sbit k1=P3^4;//功能键
  13. sbit k2=P3^5;//增加键
  14. sbit k3=P3^6;//减小键
  15. sbit k4=P3^7;//查看键

  16. */

  17. sbit VFD_CLK = P1^6;
  18. sbit VFD_STB = P1^5;
  19. sbit VFD_DIN = P1^7;

  20. sbit k1=P3^0;//功能键
  21. sbit k2=P3^1;//增加键
  22. sbit k3=P3^2;//减小键
  23. sbit k4=P3^6;//闹钟查看键

  24. sbit DS1302_IO=P1^0;
  25. sbit DS1302_CLK=P3^7;
  26. sbit DS1302_RST=P1^1;


  27. bit r=1; //用来显示秒点

  28. uchar code vfdmap[]={0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6, 0x00};//0-9,-,全灭
  29. uchar code tab[]={0x00,0x10,0x20,0x40,0x80,0x01,0x02,0x04};//用于星期的

  30. uchar sec,min,hour,year,month,day,week,s1num,flag,shu;
  31. unsigned char vfdbuf[]={0,0,0,0,0,0,0};
  32. uchar time[7];


  33. void vfd_cmd (uchar vfd_cmd0); /* 写命令*/
  34. void vfd_wrdata (uchar vfd_wrdata0); /* 写数据 */
  35. void vfd_init (void); /*16312初始化 */


  36. void vfd_cmd (uchar vfd_cmd0) /* VFD 写控制命令子程序 */
  37. {
  38. unsigned char i;
  39. VFD_STB=1;
  40. VFD_CLK=1;
  41. for ( i=0;i<8;i++ )
  42. {
  43. VFD_STB=0;
  44. VFD_CLK=0;
  45. VFD_DIN = vfd_cmd0&0x01;
  46. VFD_CLK=1;
  47. vfd_cmd0>>=1;
  48. }
  49. VFD_STB=1;
  50. VFD_CLK=1;
  51. }

  52. void vfd_wrdata (uchar vfd_wrdata0) /* VFD 写数据子程序 */
  53. {
  54. unsigned char i;
  55. for(i=0;i<8;i++)
  56. {
  57. VFD_CLK=1;
  58. VFD_STB=0;
  59. VFD_CLK=0;
  60. VFD_DIN=vfd_wrdata0&0x01;
  61. VFD_CLK=1;
  62. vfd_wrdata0>>=1;
  63. }
  64. VFD_STB=0;
  65. VFD_CLK=1;
  66. }

  67. void vfd_init(void)
  68. {
  69. vfd_cmd ( 0x02 ); /* 6栅X16段显示模式 */
  70. vfd_cmd ( 0x40 ); /* 显示正常模式,数据地址递增 */
  71. vfd_wrdata ( 0xc0 ); /* 设置地址从00H开始 */
  72. }

  73. void delay_ms(int z)
  74. {
  75. int x,y;
  76. for(x=z;x>0;x--)
  77. for(y=150;y>0;y--);
  78. }


  79. void vfd_time_disp(uchar t_sec,t_min,t_hour,t_week) //显示
  80. {
  81. uchar min_ge,sec_shi,sec_ge,min_shi,hour_ge,hour_shi,week;
  82. sec_shi=(t_sec>>4)&0x0f;
  83. sec_ge=t_sec&0x0f;
  84. min_shi=(t_min>>4)&0x0f;
  85. min_ge=t_min&0x0f;
  86. hour_shi=(t_hour>>4)&0x0f;
  87. hour_ge=t_hour&0x0f;
  88. week=t_week&0x0f;


  89. vfdbuf[0]=vfdmap[hour_shi];
  90. vfdbuf[1]=vfdmap[hour_ge];
  91. vfdbuf[2]=vfdmap[min_shi];
  92. vfdbuf[3]=vfdmap[min_ge];
  93. vfdbuf[4]=vfdmap[sec_shi];
  94. vfdbuf[5]=vfdmap[sec_ge];
  95. vfdbuf[6]=tab[week]; //星期

  96. vfd_init( );
  97. vfd_wrdata (vfdbuf[1]); //C0 第1栅
  98. vfd_wrdata (vfdbuf[0]); //C1
  99. vfd_wrdata (0x08); //C2 第2栅
  100. vfd_wrdata (0); //C3
  101. vfd_wrdata (vfdbuf[3]|r); //C4 第3栅
  102. vfd_wrdata (vfdbuf[2]|0x01); //C5
  103. vfd_wrdata (vfdbuf[5]); //C6 第4栅
  104. vfd_wrdata (vfdbuf[4]|0x01); //C7
  105. vfd_wrdata (0x10); //C8 第5栅
  106. vfd_wrdata (0x10); //C9
  107. vfd_wrdata (0); //CA
  108. vfd_wrdata (vfdbuf[6]);//CB
  109. VFD_STB=1;
  110. delay_ms(10);
  111. vfd_cmd ( 0x8f ); // 显示开,14/16脉宽
  112. delay_ms(1);
  113. }

  114. void vfd_date_disp(uchar t_day,t_month,t_year,t_week) //显示
  115. {
  116. uchar day_shi,day_ge,month_shi,month_ge,year_ge,year_shi,week;
  117. day_shi=(t_day>>4)&0x0f;
  118. day_ge=t_day&0x0f;
  119. month_shi=(t_month>>4)&0x0f;
  120. month_ge=t_month&0x0f;
  121. year_shi=(t_year>>4)&0x0f;
  122. year_ge=t_year&0x0f;
  123. week=t_week&0x0f;


  124. vfdbuf[0]=vfdmap[year_shi];
  125. vfdbuf[1]=vfdmap[year_ge];
  126. vfdbuf[2]=vfdmap[month_shi];
  127. vfdbuf[3]=vfdmap[month_ge];
  128. vfdbuf[4]=vfdmap[day_shi];
  129. vfdbuf[5]=vfdmap[day_ge];
  130. vfdbuf[6]=tab[week]; //星期

  131. vfd_init( );
  132. vfd_wrdata (vfdbuf[1]); //C0 第1栅
  133. vfd_wrdata (vfdbuf[0]); //C1
  134. vfd_wrdata (0x08); //C2 第2栅
  135. vfd_wrdata (0); //C3
  136. vfd_wrdata (vfdbuf[3]); //C4 第3栅
  137. vfd_wrdata (vfdbuf[2]); //C5
  138. vfd_wrdata (vfdbuf[5]); //C6 第4栅
  139. vfd_wrdata (vfdbuf[4]); //C7
  140. vfd_wrdata (0x10); //C8 第5栅
  141. vfd_wrdata (0x10); //C9
  142. vfd_wrdata (0); //CA
  143. vfd_wrdata (vfdbuf[6]);//CB
  144. VFD_STB=1;
  145. delay_ms(10);
  146. vfd_cmd ( 0x8f ); // 显示开,14/16脉宽
  147. delay_ms(1);
  148. }



  149. void wdayte_byte(uchar dat) //写1字节数据到1302,低位在前。
  150. {
  151. uchar i;
  152. for(i=0;i<8;i++)
  153. {
  154. DS1302_IO=0;
  155. if(dat&0x01)
  156. DS1302_IO=1;
  157. else
  158. DS1302_IO=0;
  159. dat=dat>>1;
  160. DS1302_CLK=0;
  161. DS1302_CLK=1;
  162. }
  163. DS1302_CLK=0;
  164. }

  165. uchar read_byte() //从DS1302中读1字节数据,读出时高位在前。
  166. {
  167. uchar i,dat;
  168. for(i=0;i<8;i++)
  169. {
  170. dat=dat>>1;
  171. if(DS1302_IO)
  172. dat=dat|0x80;
  173. DS1302_CLK=1;
  174. DS1302_CLK=0;
  175. }
  176. DS1302_CLK=0;
  177. return(dat);
  178. }

  179. void wdayte_ds1302(uchar add,uchar dat) //向DS1302的add地址中写入dat数据
  180. {
  181. DS1302_RST=0;
  182. DS1302_CLK=0;
  183. DS1302_RST=1;
  184. wdayte_byte(add);
  185. wdayte_byte(dat);
  186. DS1302_CLK=0;
  187. DS1302_RST=0;
  188. }

  189. uchar read_ds1302(uchar add) //从DS1302的add地址中读出数据
  190. {
  191. uchar time ;
  192. DS1302_RST=0;
  193. DS1302_CLK=0;
  194. DS1302_RST=1;
  195. wdayte_byte(add);
  196. time=read_byte();
  197. DS1302_CLK=0;
  198. DS1302_RST=0;
  199. return(time);
  200. }

  201. void init_ds1302() //时间初始化函数,不进行初始化DS1302不能正常工作
  202. {
  203. wdayte_ds1302(0x8e,0x00);
  204. wdayte_ds1302(0x8c,time[0]); //写入年数据
  205. wdayte_ds1302(0x88,time[1]); //写入月数据
  206. wdayte_ds1302(0x86,time[2]); //写入日数据
  207. wdayte_ds1302(0x84,time[3]); //写入时数据
  208. wdayte_ds1302(0x82,time[4]); //写入分数据
  209. wdayte_ds1302(0x80,time[5]); //写入秒数据
  210. wdayte_ds1302(0x8a,time[6]); //写入星期数据
  211. wdayte_ds1302(0x90,0xa5); //充电(因用的是法拉电容,所以选一个二极管,2K电阻)
  212. wdayte_ds1302(0x8e,0x80);
  213. }

  214. void read_time() //时间读取函数
  215. {
  216. sec=read_ds1302(0x81);
  217. min=read_ds1302(0x83);
  218. hour=read_ds1302(0x85);
  219. week=read_ds1302(0x8b);
  220. day=read_ds1302(0x87);
  221. month=read_ds1302(0x89);
  222. year=read_ds1302(0x8d);
  223. time[0]=year;
  224. time[1]=month;
  225. time[2]=day;
  226. time[3]=hour;
  227. time[4]=min;
  228. time[5]=sec;
  229. time[6]=week;
  230. }


  231. void keyscan() //键盘检测函数,用于时间的调节
  232. {
  233. if(k4==0) //K4在没有调整时间时按下显示日期,有调时按下先保存退出再显示日期
  234. {

  235. delay_ms(1);
  236. if(k4==0)

  237. {
  238. if(flag==1)
  239. {
  240. init_ds1302();

  241. }
  242. vfd_date_disp(day,month,year,week);
  243. delay_ms(2000);
  244. flag=0;
  245. s1num=0;
  246. }

  247. }

  248. if(k1==0)
  249. {
  250. delay_ms(1);
  251. if(k1==0)
  252. {
  253. while(!k1);
  254. s1num++;
  255. flag=1;
  256. if(s1num==7)
  257. {
  258. init_ds1302();
  259. flag=0;
  260. s1num=0;
  261. }
  262. }
  263. }
  264. if(s1num!=0)
  265. {
  266. if(k2==0)//加键按下
  267. {
  268. delay_ms(1);
  269. if(k2==0)
  270. {
  271. switch(s1num)
  272. {
  273. case 1: min=((min/16)*10)+(min%16);
  274. min++;
  275. if(min==60)
  276. min=0;
  277. time[4]=(((min/10)<<4)&0xf0)|((min%10)&0x0f);
  278. time[5]=0x00;
  279. wdayte_ds1302(0x8e,0x00);
  280. wdayte_ds1302(0x80,time[5]);
  281. wdayte_ds1302(0x82,time[4]);
  282. wdayte_ds1302(0x8e,0x80);
  283. break;
  284. case 2: hour=((hour/16)*10)+(hour%16);
  285. hour++;
  286. if(hour==24)
  287. hour=0;
  288. time[3]=(((hour/10)<<4)&0xf0)|((hour%10)&0x0f);
  289. wdayte_ds1302(0x8e,0x00);
  290. wdayte_ds1302(0x84,time[3]);
  291. wdayte_ds1302(0x8e,0x80);
  292. break;
  293. case 3: day=((day/16)*10)+(day%16);
  294. day++;
  295. if(day==32)
  296. day=1;
  297. time[2]=(((day/10)<<4)&0xf0)|((day%10)&0x0f);
  298. wdayte_ds1302(0x8e,0x00);
  299. wdayte_ds1302(0x86,time[2]);
  300. wdayte_ds1302(0x8e,0x80);
  301. break;
  302. case 4: month=((month/16)*10)+(month%16);
  303. month++;
  304. if(month==13)
  305. month=1;
  306. time[1]=(((month/10)<<4)&0xf0)|((month%10)&0x0f);
  307. wdayte_ds1302(0x8e,0x00);
  308. wdayte_ds1302(0x88,time[1]);
  309. wdayte_ds1302(0x8e,0x80);
  310. break;

  311. case 5: year=((year/16)*10)+(year%16);
  312. year++;
  313. if(year>99)
  314. year=0;
  315. time[0]=(((year/10)<<4)&0xf0)|((year%10)&0x0f);
  316. wdayte_ds1302(0x8e,0x00);
  317. wdayte_ds1302(0x8c,time[0]);
  318. wdayte_ds1302(0x8e,0x80);
  319. break;
  320. case 6: week=week%16;
  321. week++;
  322. if(week>7)
  323. week=1;
  324. time[6]=((week%10)&0x0f);
  325. wdayte_ds1302(0x8e,0x00);
  326. wdayte_ds1302(0x8a,time[6]);
  327. wdayte_ds1302(0x8e,0x80);
  328. break;
  329. }
  330. }
  331. }

  332. if(k3==0)//减键按下
  333. {
  334. delay_ms(1);
  335. if(k3==0)
  336. {
  337. switch(s1num)
  338. {
  339. case 1: min=((min/16)*10)+(min%16);
  340. min--;
  341. if(min==-1)
  342. min=59;
  343. time[4]=(((min/10)<<4)&0xf0)|((min%10)&0x0f);
  344. time[5]=0x00;
  345. wdayte_ds1302(0x8e,0x00);
  346. wdayte_ds1302(0x80,time[5]);
  347. wdayte_ds1302(0x82,time[4]);
  348. wdayte_ds1302(0x8e,0x80);
  349. break;
  350. case 2: hour=((hour/16)*10)+(hour%16);
  351. hour--;
  352. if(hour==-1)
  353. hour=23;
  354. time[3]=(((hour/10)<<4)&0xf0)|((hour%10)&0x0f);
  355. wdayte_ds1302(0x8e,0x00);
  356. wdayte_ds1302(0x84,time[3]);
  357. wdayte_ds1302(0x8e,0x80);
  358. break;
  359. case 3: day=((day/16)*10)+(day%16);
  360. day--;
  361. if(day==0)
  362. day=31;
  363. time[2]=(((day/10)<<4)&0xf0)|((day%10)&0x0f);
  364. wdayte_ds1302(0x8e,0x00);
  365. wdayte_ds1302(0x86,time[2]);
  366. wdayte_ds1302(0x8e,0x80);
  367. break;
  368. case 4: month=((month/16)*10)+(month%16);
  369. month--;
  370. if(month==-1)
  371. month=12;
  372. time[1]=(((month/10)<<4)&0xf0)|((month%10)&0x0f);
  373. wdayte_ds1302(0x8e,0x00);
  374. wdayte_ds1302(0x88,time[1]);
  375. wdayte_ds1302(0x8e,0x80);
  376. break;

  377. case 5: year=((year/16)*10)+(year%16);
  378. year--;
  379. if(year==-1)
  380. year=99;
  381. time[0]=(((year/10)<<4)&0xf0)|((year%10)&0x0f);
  382. wdayte_ds1302(0x8e,0x00);
  383. wdayte_ds1302(0x8c,time[0]);
  384. wdayte_ds1302(0x8e,0x80);
  385. break;
  386. case 6: week=week%16;
  387. week--;
  388. if(week==0)
  389. week=7;
  390. time[6]=((week%10)&0x0f);
  391. wdayte_ds1302(0x8e,0x00);
  392. wdayte_ds1302(0x8a,time[6]);
  393. wdayte_ds1302(0x8e,0x80);
  394. break;
  395. }
  396. }
  397. }


  398. }


  399. }



  400. void set_time_disp(s1num,flag) //时间调节显示函数
  401. {
  402. uchar i;
  403. if((s1num==1)&&(flag==1))
  404. {
  405. read_time();
  406. for(i=0;i<10;i++)
  407. vfd_time_disp(sec,min,hour,week);
  408. for(i=0;i<10;i++)
  409. vfd_time_disp(sec,0xaa,hour,week);
  410. }
  411. if((s1num==2)&&(flag==1))
  412. {
  413. read_time();
  414. for(i=0;i<10;i++)
  415. vfd_time_disp(sec,min,hour,week);
  416. for(i=0;i<10;i++)
  417. vfd_time_disp(sec,min,0xaa,week);
  418. }
  419. if((s1num==3)&&(flag==1))
  420. {
  421. read_time();
  422. for(i=0;i<10;i++)
  423. vfd_date_disp(day,month,year,week);
  424. for(i=0;i<10;i++)
  425. vfd_date_disp(0xaa,month,year,week);
  426. }
  427. if((s1num==4)&&(flag==1))
  428. {
  429. read_time();
  430. for(i=0;i<10;i++)
  431. vfd_date_disp(day,month,year,week);
  432. for(i=0;i<10;i++)
  433. vfd_date_disp(day,0xaa,year,week);
  434. }
  435. if((s1num==5)&&(flag==1))
  436. {
  437. read_time();
  438. for(i=0;i<10;i++)
  439. vfd_date_disp(day,month,year,week);
  440. for(i=0;i<10;i++)
  441. vfd_date_disp(day,month,0xaa,week);
  442. }
  443. if((s1num==6)&&(flag==1))
  444. {
  445. read_time();
  446. for(i=0;i<10;i++)
  447. vfd_date_disp(day,month,year,week);
  448. for(i=0;i<10;i++)
  449. vfd_date_disp(day,month,year,0x00);
  450. }
  451. }

  452. void main()
  453. {
  454. TMOD=0x01; //设定定时器0为方式1
  455. TH0=(65536-50000)/256; //定时时间设置,时间设为50毫秒
  456. TL0=(65536-50000)%256;
  457. EA=1; //开总中断
  458. ET0=1; //开定时器0中断
  459. TR0=1; //启动定时器0
  460. while(1)
  461. {
  462. keyscan();
  463. read_time(); //按键检测
  464. if(flag==0) //如果没有按键进入这里
  465. {
  466. vfd_time_disp(sec,min,hour,week);
  467. }
  468. if(flag==1) //如果有按键进入这里
  469. {
  470. set_time_disp(s1num,flag);
  471. }
  472. }
  473. }

  474. void T0_time() interrupt 1 //中断函数用于秒点的闪烁,周期1秒
  475. {

  476. TH0=(65536-50000)/256;
  477. TL0=(65536-50000)%256;
  478. shu++; //用于时间的计数10次500MS
  479. if(shu==10)
  480. {
  481. shu=0;
  482. r=~r; //每500毫秒led取反一次
  483. }
  484. }
复制代码



评分

参与人数 1黑币 +5 收起 理由
capacitance_1 + 5 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:60515 发表于 2016-2-6 13:01 来自触屏版 | 只看该作者
可以发一下电路??控制是什么形号的VDF屏??
回复

使用道具 举报

板凳
ID:149451 发表于 2020-1-26 09:08 | 只看该作者
求教各位走过路过的朋友,这个程序如何改成PT6311的?知道显存地址不同,可是不会改
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表