找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1519|回复: 6
收起左侧

想自制单片机小手表,求思路

[复制链接]
ID:884042 发表于 2021-2-12 21:09 | 显示全部楼层 |阅读模式
由于本论坛禁止直接求程序,禁止伸手党,所以向大家请教一下大致的实现方法与思路,理清头绪后我自己来写程序去实现

自制小手表   最近要参加学校科技比赛,就萌发出做一个简单的小手表的想法,只要能看时间就行。
   但后来又想搞的更复杂点,于是就继续搞这个产品了。以下使用到的材料(包括各种功能IC):
   1  0.96寸OLED屏 1个
   2  3.7V电池 1个
   3  自己从手机上拆下的无源喇叭1个
   4  DS1302时钟芯片 1个
   5  STC15W408S 8K 芯片1个
   6  按键2个
   以下是详细资料:
    3_小手表.zip (16.82 MB, 下载次数: 11)
回复

使用道具 举报

ID:871393 发表于 2021-2-13 18:15 | 显示全部楼层
用直线插补确定线上点的坐标,画点lcd更方便,毕竟oled是8个点一起写的
回复

使用道具 举报

ID:390416 发表于 2021-2-13 20:22 | 显示全部楼层
STC8单片机+DS1302+DS18B20+74HC595的LED16x32点阵温度万年历源代码分享 http://www.51hei.com/bbs/dpj-200968-1.html
回复

使用道具 举报

ID:420836 发表于 2021-2-15 01:57 | 显示全部楼层
很好,这是添加更多功能的良好开端。
回复

使用道具 举报

ID:884042 发表于 2021-2-18 17:05 | 显示全部楼层
TTQ001 发表于 2021-2-15 01:57
很好,这是添加更多功能的良好开端。

现在我要 解决画竖线的函数,画横线函数及画点函数
  1. /************************************************************************************
  2. *  Copyright (c), 2013, HelTec Automatic Technology co.,LTD.
  3. *            All rights reserved.
  4. *
  5. *
  6. * File name: LQ12864.h
  7. * Project  : OLED
  8. * Processor: STC89C52
  9. * Compiler : Keil C51 Compiler
  10. *
  11. * Author : 小林
  12. * Version: 1.00
  13. * Date   : 2013.8.8
  14. * Modification: none
  15. *
  16. * Description:128*64点整OLED模块驱动文件
  17. *
  18. * Others: none;
  19. *
  20. * Function List:
  21. *
  22. * 1. void delay(unsigned int z) -- 延时函数,毫秒
  23. * 2. void IIC_Start() -- 开启I2C总线
  24. * 3. void IIC_Stop() -- 关闭I2C总线
  25. * 4. void Write_IIC_Byte(unsigned char IIC_Byte) -- 通过I2C总线写一个byte的数据
  26. * 5. void OLED_WrDat(unsigned char dat) -- 向OLED屏写数据
  27. * 6. void OLED_WrCmd(unsigned char cmd) -- 向OLED屏写命令
  28. * 7. void OLED_Set_Pos(unsigned char x, unsigned char y) -- 设置显示坐标
  29. * 8. void OLED_Fill(unsigned char bmp_dat) -- 全屏显示(显示BMP图片时才会用到此功能)
  30. * 9. void OLED_CLS(void) -- 复位/清屏
  31. * 10. void OLED_Init(void) -- OLED屏初始化程序,此函数应在操作屏幕之前最先调用
  32. * 11. void OLED_P6x8Str(unsigned char x, y,unsigned char ch[]) -- 6x8点整,用于显示ASCII码的最小阵列,不太清晰
  33. * 12. void OLED_P8x16Str(unsigned char x, y,unsigned char ch[]) -- 8x16点整,用于显示ASCII码,非常清晰
  34. * 13.void OLED_P16x16Ch(unsigned char x, y, N) -- 16x16点整,用于显示汉字的最小阵列,可设置各种字体、加粗、倾斜、下划线等
  35. * 14.void Draw_BMP(unsigned char x0, y0,x1, y1,unsigned char BMP[]) -- 将128x64像素的BMP位图在取字软件中算出字表,然后复制到codetab中,此函数调用即可
  36. *
  37. * History: none;
  38. *
  39. *************************************************************************************/

  40. #include "reg52.h"

  41. // ------------------------------------------------------------
  42. // IO口模拟I2C通信
  43. // SCL接P1^3
  44. // SDA接P1^2
  45. // ------------------------------------------------------------
  46. sbit SCL=P1^4; //串行时钟
  47. sbit SDA=P1^3; //串行数据

  48. #define high 1
  49. #define low 0

  50. #define        Brightness        0xCF
  51. #define X_WIDTH         128
  52. #define Y_WIDTH         64
  53. /*********************OLED驱动程序用的延时程序************************************/
  54. void delay(unsigned int z)
  55. {
  56.         unsigned int x,y;
  57.         for(x=z;x>0;x--)
  58.                 for(y=110;y>0;y--);
  59. }

  60. /**********************************************
  61. //IIC Start
  62. **********************************************/
  63. void IIC_Start()
  64. {
  65.    SCL = high;               
  66.    SDA = high;
  67.    SDA = low;
  68.    SCL = low;
  69. }

  70. /**********************************************
  71. //IIC Stop
  72. **********************************************/
  73. void IIC_Stop()
  74. {
  75.    SCL = low;
  76.    SDA = low;
  77.    SCL = high;
  78.    SDA = high;
  79. }

  80. /**********************************************
  81. // 通过I2C总线写一个字节
  82. **********************************************/
  83. void Write_IIC_Byte(unsigned char IIC_Byte)
  84. {
  85.         unsigned char i;
  86.         for(i=0;i<8;i++)
  87.         {
  88.                 if(IIC_Byte & 0x80)
  89.                         SDA=high;
  90.                 else
  91.                         SDA=low;
  92.                 SCL=high;
  93.                 SCL=low;
  94.                 IIC_Byte<<=1;
  95.         }
  96.         SDA=1;
  97.         SCL=1;
  98.         SCL=0;
  99. }

  100. /*********************OLED写数据************************************/
  101. void OLED_WrDat(unsigned char IIC_Data)
  102. {
  103.         IIC_Start();
  104.         Write_IIC_Byte(0x78);
  105.         Write_IIC_Byte(0x40);                        //write data
  106.         Write_IIC_Byte(IIC_Data);
  107.         IIC_Stop();
  108. }
  109. /*********************OLED写命令************************************/
  110. void OLED_WrCmd(unsigned char IIC_Command)
  111. {
  112.         IIC_Start();
  113.         Write_IIC_Byte(0x78);            //Slave address,SA0=0
  114.         Write_IIC_Byte(0x00);                        //write command
  115.         Write_IIC_Byte(IIC_Command);
  116.         IIC_Stop();
  117. }
  118. /*********************OLED 设置坐标************************************/
  119. void OLED_Set_Pos(unsigned char x, unsigned char y)
  120. {
  121.         OLED_WrCmd(0xb0+y);
  122.         OLED_WrCmd(((x&0xf0)>>4)|0x10);
  123.         OLED_WrCmd((x&0x0f)|0x01);
  124. }
  125. /*********************OLED全屏************************************/
  126. void OLED_Fill(unsigned char bmp_dat)
  127. {
  128.         unsigned char y,x;
  129.         for(y=0;y<8;y++)
  130.         {
  131.                 OLED_WrCmd(0xb0+y);
  132.                 OLED_WrCmd(0x01);
  133.                 OLED_WrCmd(0x10);
  134.                 for(x=0;x<X_WIDTH;x++)
  135.                 OLED_WrDat(bmp_dat);
  136.         }
  137. }
  138. /*********************OLED复位************************************/
  139. void OLED_CLS(void)
  140. {
  141.         unsigned char y,x;
  142.         for(y=0;y<8;y++)
  143.         {
  144.                 OLED_WrCmd(0xb0+y);
  145.                 OLED_WrCmd(0x01);
  146.                 OLED_WrCmd(0x10);
  147.                 for(x=0;x<X_WIDTH;x++)
  148.                 OLED_WrDat(0);
  149.         }
  150. }
  151. /*********************OLED初始化************************************/
  152. void OLED_Init(void)
  153. {
  154.         delay(500);//初始化之前的延时很重要!
  155.         OLED_WrCmd(0xae);//--turn off oled panel
  156.         OLED_WrCmd(0x00);//---set low column address
  157.         OLED_WrCmd(0x10);//---set high column address
  158.         OLED_WrCmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
  159.         OLED_WrCmd(0x81);//--set contrast control register
  160.         OLED_WrCmd(Brightness); // Set SEG Output Current Brightness
  161.         OLED_WrCmd(0xa1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
  162.         OLED_WrCmd(0xc8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
  163.         OLED_WrCmd(0xa6);//--set normal display
  164.         OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
  165.         OLED_WrCmd(0x3f);//--1/64 duty
  166.         OLED_WrCmd(0xd3);//-set display offset        Shift Mapping RAM Counter (0x00~0x3F)
  167.         OLED_WrCmd(0x00);//-not offset
  168.         OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
  169.         OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
  170.         OLED_WrCmd(0xd9);//--set pre-charge period
  171.         OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  172.         OLED_WrCmd(0xda);//--set com pins hardware configuration
  173.         OLED_WrCmd(0x12);
  174.         OLED_WrCmd(0xdb);//--set vcomh
  175.         OLED_WrCmd(0x40);//Set VCOM Deselect Level
  176.         OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
  177.         OLED_WrCmd(0x02);//
  178.         OLED_WrCmd(0x8d);//--set Charge Pump enable/disable
  179.         OLED_WrCmd(0x14);//--set(0x10) disable
  180.         OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
  181.         OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
  182.         OLED_WrCmd(0xaf);//--turn on oled panel
  183.         OLED_Fill(0x00); //初始清屏
  184.         OLED_Set_Pos(0,0);
  185. }
  186. /***************功能描述:显示6*8一组标准ASCII字符串        显示的坐标(x,y),y为页范围0~7****************/
  187. void OLED_P6x8Str(unsigned char x, y,unsigned char ch[])
  188. {
  189.         unsigned char c=0,i=0,j=0;
  190.         while (ch[j]!='\0')
  191.         {
  192.                 c =ch[j]-32;
  193.                 if(x>126){x=0;y++;}
  194.                 OLED_Set_Pos(x,y);
  195.                 for(i=0;i<6;i++)
  196.                 OLED_WrDat(F6x8[c][i]);
  197.                 x+=6;
  198.                 j++;
  199.         }
  200. }
  201. /*******************功能描述:显示8*16一组标准ASCII字符串         显示的坐标(x,y),y为页范围0~7****************/
  202. void OLED_P8x16Str(unsigned char x, y,unsigned char ch[])
  203. {
  204.         unsigned char c=0,i=0,j=0;
  205.         while (ch[j]!='\0')
  206.         {
  207.                 c =ch[j]-32;
  208.                 if(x>120){x=0;y++;}
  209.                 OLED_Set_Pos(x,y);
  210.                 for(i=0;i<8;i++)
  211.                 OLED_WrDat(F8X16[c*16+i]);
  212.                 OLED_Set_Pos(x,y+1);
  213.                 for(i=0;i<8;i++)
  214.                 OLED_WrDat(F8X16[c*16+i+8]);
  215.                 x+=8;
  216.                 j++;
  217.         }
  218. }
  219. /*****************功能描述:显示16*16点阵  显示的坐标(x,y),y为页范围0~7****************************/
  220. void OLED_P16x16Ch(unsigned char x, y, N)
  221. {
  222.         unsigned char wm=0;
  223.         unsigned int adder=32*N;
  224.         OLED_Set_Pos(x , y);
  225.         for(wm = 0;wm < 16;wm++)
  226.         {
  227.                 OLED_WrDat(F16x16[adder]);
  228.                 adder += 1;
  229.         }
  230.         OLED_Set_Pos(x,y + 1);
  231.         for(wm = 0;wm < 16;wm++)
  232.         {
  233.                 OLED_WrDat(F16x16[adder]);
  234.                 adder += 1;
  235.         }                  
  236. }
  237. /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
  238. void Draw_BMP(unsigned char x0, y0,x1, y1,unsigned char BMP[])
  239. {
  240.         unsigned int j=0;
  241.         unsigned char x,y;

  242.   if(y1%8==0) y=y1/8;      
  243.   else y=y1/8+1;
  244.         for(y=y0;y<y1;y++)
  245.         {
  246.                 OLED_Set_Pos(x0,y);
  247.     for(x=x0;x<x1;x++)
  248.             {      
  249.                     OLED_WrDat(BMP[j++]);
  250.             }
  251.         }
  252. }
  253. void OLED_Point(unsigned char x, y)
  254. {        
  255.         switch(y)
  256.         {
  257.                 case(0):OLED_Set_Pos(x,0);OLED_WrDat(0x01);break;
  258.                 case(1):OLED_Set_Pos(x,0);OLED_WrDat(0x02);break;
  259.                 case(2):OLED_Set_Pos(x,0);OLED_WrDat(0x04);break;
  260.                 case(3):OLED_Set_Pos(x,0);OLED_WrDat(0x08);break;
  261.                 case(4):OLED_Set_Pos(x,0);OLED_WrDat(0x10);break;
  262.                 case(5):OLED_Set_Pos(x,0);OLED_WrDat(0x20);break;
  263.                 case(6):OLED_Set_Pos(x,0);OLED_WrDat(0x40);break;
  264.                 case(7):OLED_Set_Pos(x,0);OLED_WrDat(0x80);break;
  265.                 case(8):OLED_Set_Pos(x,1);OLED_WrDat(0x01);break;
  266.                 case(9):OLED_Set_Pos(x,1);OLED_WrDat(0x02);break;
  267.                 case(10):OLED_Set_Pos(x,1);OLED_WrDat(0x04);break;
  268.                 case(11):OLED_Set_Pos(x,1);OLED_WrDat(0x08);break;
  269.                 case(12):OLED_Set_Pos(x,1);OLED_WrDat(0x10);break;
  270.                 case(13):OLED_Set_Pos(x,1);OLED_WrDat(0x20);break;
  271.                 case(14):OLED_Set_Pos(x,1);OLED_WrDat(0x40);break;
  272.                 case(15):OLED_Set_Pos(x,1);OLED_WrDat(0x80);break;
  273.                 case(16):OLED_Set_Pos(x,2);OLED_WrDat(0x01);break;
  274.                 case(17):OLED_Set_Pos(x,2);OLED_WrDat(0x02);break;
  275.                 case(18):OLED_Set_Pos(x,2);OLED_WrDat(0x04);break;
  276.                 case(19):OLED_Set_Pos(x,2);OLED_WrDat(0x08);break;
  277.                 case(20):OLED_Set_Pos(x,2);OLED_WrDat(0x10);break;
  278.                 case(21):OLED_Set_Pos(x,2);OLED_WrDat(0x20);break;
  279.                 case(22):OLED_Set_Pos(x,2);OLED_WrDat(0x40);break;
  280.                 case(23):OLED_Set_Pos(x,2);OLED_WrDat(0x80);break;
  281.                 case(24):OLED_Set_Pos(x,3);OLED_WrDat(0x01);break;
  282.                 case(25):OLED_Set_Pos(x,3);OLED_WrDat(0x02);break;
  283.                 case(26):OLED_Set_Pos(x,3);OLED_WrDat(0x04);break;
  284.                 case(27):OLED_Set_Pos(x,3);OLED_WrDat(0x08);break;
  285.                 case(28):OLED_Set_Pos(x,3);OLED_WrDat(0x10);break;
  286.                 case(29):OLED_Set_Pos(x,3);OLED_WrDat(0x20);break;
  287.                 case(30):OLED_Set_Pos(x,3);OLED_WrDat(0x40);break;
  288.                 case(31):OLED_Set_Pos(x,3);OLED_WrDat(0x80);break;
  289.                 case(32):OLED_Set_Pos(x,4);OLED_WrDat(0x01);break;
  290.                 case(33):OLED_Set_Pos(x,4);OLED_WrDat(0x02);break;
  291.                 case(34):OLED_Set_Pos(x,4);OLED_WrDat(0x04);break;
  292.                 case(35):OLED_Set_Pos(x,4);OLED_WrDat(0x08);break;
  293.                 case(36):OLED_Set_Pos(x,4);OLED_WrDat(0x10);break;
  294.                 case(37):OLED_Set_Pos(x,4);OLED_WrDat(0x20);break;
  295.                 case(38):OLED_Set_Pos(x,4);OLED_WrDat(0x40);break;
  296.                 case(39):OLED_Set_Pos(x,4);OLED_WrDat(0x80);break;
  297.                 case(40):OLED_Set_Pos(x,5);OLED_WrDat(0x01);break;
  298.                 case(41):OLED_Set_Pos(x,5);OLED_WrDat(0x02);break;
  299.                 case(42):OLED_Set_Pos(x,5);OLED_WrDat(0x04);break;
  300.                 case(43):OLED_Set_Pos(x,5);OLED_WrDat(0x08);break;
  301.                 case(44):OLED_Set_Pos(x,5);OLED_WrDat(0x10);break;
  302.                 case(45):OLED_Set_Pos(x,5);OLED_WrDat(0x20);break;
  303.                 case(46):OLED_Set_Pos(x,5);OLED_WrDat(0x40);break;
  304.                 case(47):OLED_Set_Pos(x,5);OLED_WrDat(0x80);break;
  305.                 case(48):OLED_Set_Pos(x,6);OLED_WrDat(0x01);break;
  306.                 case(49):OLED_Set_Pos(x,6);OLED_WrDat(0x02);break;
  307.                 case(50):OLED_Set_Pos(x,6);OLED_WrDat(0x04);break;
  308.                 case(51):OLED_Set_Pos(x,6);OLED_WrDat(0x08);break;
  309.                 case(52):OLED_Set_Pos(x,6);OLED_WrDat(0x10);break;
  310.                 case(53):OLED_Set_Pos(x,6);OLED_WrDat(0x20);break;
  311.                 case(54):OLED_Set_Pos(x,6);OLED_WrDat(0x40);break;
  312.                 case(55):OLED_Set_Pos(x,6);OLED_WrDat(0x80);break;
  313.                 case(56):OLED_Set_Pos(x,7);OLED_WrDat(0x01);break;
  314.                 case(57):OLED_Set_Pos(x,7);OLED_WrDat(0x02);break;
  315.                 case(58):OLED_Set_Pos(x,7);OLED_WrDat(0x04);break;
  316.                 case(59):OLED_Set_Pos(x,7);OLED_WrDat(0x08);break;
  317.                 case(60):OLED_Set_Pos(x,7);OLED_WrDat(0x10);break;
  318.                 case(61):OLED_Set_Pos(x,7);OLED_WrDat(0x20);break;
  319.                 case(62):OLED_Set_Pos(x,7);OLED_WrDat(0x40);break;
  320.                 case(63):OLED_Set_Pos(x,7);OLED_WrDat(0x80);break;
  321.         }                  
  322. }
  323. void OLED_XLine(unsigned char x0, y0,x1)
  324. {        
  325.     unsigned char z;        
  326.         if(x0<=x1)
  327.         {
  328.                 OLED_Point(x0, y0);
  329.                 for(z=x0;z<x1;z++)
  330.             {
  331.                     OLED_Point(z, y0);
  332.             }
  333.         }
  334.         if(x0>=x1)
  335.         {
  336.                 OLED_Point(x0, y0);
  337.                 for(z=x0;z<=x1;z--)          //z=16 z=0 z--
  338.             {
  339.                     OLED_Point(z, y0);
  340.             }
  341.         }                          
  342. }
  343. void OLED_YLine(unsigned char y0, x0,y1)
  344. {        
  345.     unsigned char z;        
  346.         if(y0<=y1)
  347.         {
  348.                 OLED_Point(x0, y0);
  349.                 for(z=y0;z<y1;z++)
  350.             {
  351.                     OLED_Point(x0, z);
  352.             }
  353.         }                          
  354. }
复制代码
以编好

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:372579 发表于 2021-2-19 10:21 | 显示全部楼层
好东西,可以收藏下,有空研究下
回复

使用道具 举报

ID:72088 发表于 2024-3-11 09:47 | 显示全部楼层
我想法是节能为主,LED0.28寸数码管,DS3231+15W408(16脚),按键唤醒,3秒掉电模式,充电用半月
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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