找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10618|回復(fù): 22
收起左側(cè)

基于STM8S103F3P6、OLED12864、BMP180和DS3231的手表設(shè)計

  [復(fù)制鏈接]
ID:362076 發(fā)表于 2019-3-9 16:08 | 顯示全部樓層 |閱讀模式
本制作僅設(shè)計了基本功能,即基于題目所述器件的基本使用,為有興趣的人提供了設(shè)計參考雛形和界面UI靈感。如需優(yōu)化,可以參考如下方面:
1.添加電池供電電路
2.添加藍牙功能和時間修改接口以便于上位機通信
3.低功耗設(shè)計,包括延時滅屏、ADC/溫度氣壓觸發(fā)更新等
4.可以考慮添加更多功能,例如基于加速度計的計步功能、基于角度傳感器的抬腕顯示功能以及基于心率傳感器的心率監(jiān)測等。


本設(shè)計采用STM8S103F3P6核心板主控。實時時鐘RTC芯片采用DS3231;氣壓和溫度數(shù)據(jù)來自BMP180;供電電壓測量數(shù)據(jù)由片內(nèi)ADC第七通道數(shù)值讀取和換算得到;顯示模塊采用SSD1306驅(qū)動的OLED12864模塊,通訊接口為IIC。另外,專門對6X8、12X24的數(shù)字字體進行重新設(shè)計,使之觀看起來更加舒適,字體取模方式見工程中說明。

為了方便讀者各部分分開使用的需求,雖然這幾個器件都是IIC,我卻沒有使用IIC總線連接方式,各個器件都以模擬IIC連接,各個器件的定義都在其C文件中。

如需移植到51,需要做以下更改:
1.引腳定義的函數(shù)都刪掉,用sbit定義連接
2.IIC的SDA引腳不分IN/OUT
3.修改頭文件
4.修改_Bool數(shù)據(jù)類型為bit
另外注意,本程序需要7K左右的Flash。


【整體連接】
因為不想在這個上面浪費時間,所以硬件部分直接使用OK飛線連接的,具體接線方式見下文

幾個部分的連接.jpg
【顯示屏界面設(shè)計】
日期部分原本想放計步功能的,因為有其他事情要忙,就沒做這個功能,用日期占位了。

顯示屏.jpg
【顯示屏和BMP180】
BMP180和DS3231是用熱熔膠粘在一起了的。

顯示屏和BMP180.jpg
【顯示屏和DS3231】

顯示屏和DS3231.jpg

【核心板引腳分配】
這個是用STM8CubeMX做的,因為各個不菲都是用的模塊,所以連線非常方便,也不用什么額外的上拉電阻濾波電容之類的。

引腳連接.png

【主程序】
  1. #include"iostm8s103f3.h"
  2. #include"init.c"
  3. #include"OLED12864.c"
  4. #include"OLED12864_6X8.c"
  5. #include"OLED12864_8X16.c"
  6. #include"OLED12864_12X24.c"
  7. #include"DS3231.c"
  8. #include"BMP180.c"
  9. #include"ADC.c"

  10. /************************************************************
  11. 名稱:基于STM8S103F3P6、OLED12864、BMP180和DS3231的手表設(shè)計
  12. 平臺:STM8S103F3P6,HSI:16MHz不分頻,F(xiàn)lash:8K,RAM:1K
  13. 簡介:本設(shè)計采用STM8S103F3P6核心板主控。
  14.         實時時鐘RTC芯片采用DS3231;
  15.         氣壓和溫度數(shù)據(jù)來自BMP180;
  16.         供電電壓測量數(shù)據(jù)由片內(nèi)ADC第七通道數(shù)值讀取和換算得到;
  17.         顯示模塊采用SSD1306驅(qū)動的OLED12864模塊,通訊接口為IIC。

  18.         另外,專門對6X8、12X24的數(shù)字字體進行重新設(shè)計,
  19.         使之觀看起來更加舒適,字體取模方式見工程中說明。

  20. 注意:本制作僅設(shè)計了基本功能,即基于上述器件的基本使用,
  21.         為有興趣的人提供了設(shè)計參考雛形和界面UI靈感。
  22.         如需優(yōu)化,可以參考如下方面:
  23.         1.添加電池供電電路
  24.         2.添加藍牙功能和時間修改接口以便于上位機通信
  25.         3.低功耗設(shè)計,包括延時滅屏、ADC/溫度氣壓觸發(fā)更新等
  26.         4.可以考慮添加更多功能,例如基于加速度計的計步功能、
  27.                 基于角度傳感器的抬腕顯示功能以及基于心率傳感器的
  28.                 心率監(jiān)測等。

  29. 程序編寫:凌凈清河
  30. 硬件制作:凌凈欣羽
  31. 文稿排版:凌凈欣羽

  32. 日期:2019年3月9日
  33. 聲明:如您直接使用本例程或進行較大程度的借鑒,請注明程序出處,謝謝!
  34. 所屬:新礦城學(xué)習基地#2019
  35. ************************************************************/

  36. //運行數(shù)組
  37. unsigned char Display_Time[6]={0};
  38. unsigned char Display_Date[9]={2,0,1,9,0,3,0,9,6};
  39. unsigned char Display_Pressure[4]={0};//前3位為整數(shù)部分,后1位是小數(shù)部分
  40. unsigned char Display_Temperature[3]={0};//前2位為整數(shù)部分,后1位是小數(shù)部分
  41. unsigned char Display_Voltage[3]={0};//前1位為整數(shù)部分,后2位是小數(shù)部分

  42. //靜態(tài)顯示,上電只運行一次
  43. void Display_Flash_Fixed()
  44. {
  45.         OLED12864_6X8_AnyChar(18,0,'.',1);
  46.         OLED12864_6X8_AnyString(30,0,"Kpa",0);
  47.         OLED12864_6X8_AnyChar(69,0,'.',1);
  48.         OLED12864_6X8_AnyChar(87,0,'V',0);
  49.         OLED12864_6X8_AnyChar(110,0,'.',1);
  50.         OLED12864_6X8_AnyChar(122,0,'C',0);
  51.         OLED12864_12X24_MH(40,1);
  52.         OLED12864_12X24_MH(76,1);
  53.         _OLED12864_8X16_AnyChar(40,5,'.',1);
  54.         _OLED12864_8X16_AnyChar(64,5,'.',1);
  55.         OLED12864_6X8_AnyString(1,7,"  Linyar Lab. Watch  ",0);
  56. }

  57. //動態(tài)掃描,刷新變化的數(shù)據(jù)
  58. void Display_Flash_Dynamic()
  59. {
  60.         //氣壓顯示
  61.         if(Display_Pressure[0]==0)
  62.         {
  63.                 OLED12864_6X8_AnyChar(0,0,' ',1);
  64.         }
  65.         else
  66.         {
  67.                 OLED12864_6X8_AnyNumber(0,0,Display_Pressure[0],1);
  68.         }
  69.         OLED12864_6X8_AnyNumber(6,0,Display_Pressure[1],1);
  70.         OLED12864_6X8_AnyNumber(12,0,Display_Pressure[2],1);
  71.         OLED12864_6X8_AnyNumber(24,0,Display_Pressure[3],1);
  72.         //電壓顯示
  73.         OLED12864_6X8_AnyNumber(63,0,Display_Voltage[0],1);
  74.         OLED12864_6X8_AnyNumber(75,0,Display_Voltage[1],1);
  75.         OLED12864_6X8_AnyNumber(81,0,Display_Voltage[2],1);
  76.         //溫度顯示
  77.         if(Display_Temperature[0]==0)
  78.         {
  79.                 OLED12864_6X8_AnyChar(98,0,' ',1);
  80.         }
  81.         else
  82.         {
  83.                 OLED12864_6X8_AnyNumber(98,0,Display_Temperature[0],1);
  84.         }
  85.         OLED12864_6X8_AnyNumber(104,0,Display_Temperature[1],1);
  86.         OLED12864_6X8_AnyNumber(116,0,Display_Temperature[2],1);
  87.         //時間顯示
  88.         OLED12864_12X24_AnyNumber(16,1,Display_Time[0]);
  89.         OLED12864_12X24_AnyNumber(28,1,Display_Time[1]);
  90.         OLED12864_12X24_AnyNumber(52,1,Display_Time[2]);
  91.         OLED12864_12X24_AnyNumber(64,1,Display_Time[3]);
  92.         OLED12864_12X24_AnyNumber(88,1,Display_Time[4]);
  93.         OLED12864_12X24_AnyNumber(100,1,Display_Time[5]);
  94.         //日期顯示
  95.         OLED12864_8X16_AnyNumber(8,5,Display_Date[0]);
  96.         OLED12864_8X16_AnyNumber(16,5,Display_Date[1]);
  97.         OLED12864_8X16_AnyNumber(24,5,Display_Date[2]);
  98.         OLED12864_8X16_AnyNumber(32,5,Display_Date[3]);
  99.         if(Display_Date[4]==0)
  100.         {
  101.                 _OLED12864_8X16_AnyChar(48,5,' ',1);
  102.         }
  103.         else
  104.         {
  105.                 OLED12864_8X16_AnyNumber(48,5,Display_Date[4]);
  106.         }
  107.         OLED12864_8X16_AnyNumber(56,5,Display_Date[5]);
  108.         if(Display_Date[6]==0)
  109.         {
  110.                 _OLED12864_8X16_AnyChar(72,5,' ',1);
  111.         }
  112.         else
  113.         {
  114.                 OLED12864_8X16_AnyNumber(72,5,Display_Date[6]);
  115.         }
  116.         OLED12864_8X16_AnyNumber(80,5,Display_Date[7]);
  117.         //星期顯示
  118.         switch(Display_Date[8])
  119.         {
  120.                 case 1:OLED12864_8X16_AnyString(96,5,"MON");break;
  121.                 case 2:OLED12864_8X16_AnyString(96,5,"TUE");break;
  122.                 case 3:OLED12864_8X16_AnyString(96,5,"WED");break;
  123.                 case 4:OLED12864_8X16_AnyString(96,5,"THU");break;
  124.                 case 5:OLED12864_8X16_AnyString(96,5,"FRI");break;
  125.                 case 6:OLED12864_8X16_AnyString(96,5,"SAT");break;
  126.                 case 7:OLED12864_8X16_AnyString(96,5,"SUN");break;
  127.                 default:OLED12864_8X16_AnyString(96,5,"ERR");break;
  128.         }
  129. }

  130. void Get_Time()
  131. {
  132.         DS3231_Get_Time();
  133.         //時間取顯示位
  134.         Display_Time[0]=DS3231_Time_Buffer[2]>>4;
  135.         Display_Time[1]=DS3231_Time_Buffer[2]&0x0f;
  136.         Display_Time[2]=DS3231_Time_Buffer[1]>>4;
  137.         Display_Time[3]=DS3231_Time_Buffer[1]&0x0f;
  138.         Display_Time[4]=DS3231_Time_Buffer[0]>>4;
  139.         Display_Time[5]=DS3231_Time_Buffer[0]&0x0f;
  140.         //日期取顯示位
  141.         Display_Date[2]=DS3231_Time_Buffer[6]>>4;
  142.         Display_Date[3]=DS3231_Time_Buffer[6]&0x0f;
  143.         Display_Date[4]=DS3231_Time_Buffer[5]>>4;
  144.         Display_Date[5]=DS3231_Time_Buffer[5]&0x0f;
  145.         Display_Date[6]=DS3231_Time_Buffer[4]>>4;
  146.         Display_Date[7]=DS3231_Time_Buffer[4]&0x0f;
  147.         Display_Date[8]=DS3231_Time_Buffer[3]&0x0f;
  148. }

  149. void Get_Temp()
  150. {
  151.         BMP180_Calculate();
  152.         Display_Temperature[0]=BMP180_Temperature/100;
  153.         Display_Temperature[1]=BMP180_Temperature%100/10;
  154.         Display_Temperature[2]=BMP180_Temperature%10;
  155.         Display_Pressure[0]=BMP180_Pressure/100000;
  156.         Display_Pressure[1]=BMP180_Pressure%100000/10000;
  157.         Display_Pressure[2]=BMP180_Pressure%10000/1000;
  158.         Display_Pressure[3]=BMP180_Pressure%1000/100;
  159. }

  160. void Get_VCC()
  161. {
  162.         unsigned int ADC_Value=0;//ADC轉(zhuǎn)換結(jié)果值
  163.         unsigned int Voltage_VCC=0;//推算出的VCC電壓值,單位毫伏
  164.         ADC_Value=Get_ADC1_Value();
  165.         Voltage_VCC=(unsigned int)((1250.4799/(float)ADC_Value)*1000);
  166.         Display_Voltage[0]=(Voltage_VCC)/1000;
  167.         Display_Voltage[1]=(Voltage_VCC%1000)/100;
  168.         Display_Voltage[2]=(Voltage_VCC%100)/10;
  169. }

  170. void sys_init()
  171. {
  172.         CLK_init();
  173.         ADC1_Init();
  174.         OLED12864_IIC_OUT();
  175.         OLED_Init();
  176.         DS3231_IIC_OUT();
  177.         BMP180_IIC_OUT();
  178.         Init_BMP180();
  179.         Display_Flash_Fixed();
  180.         DS3231_Set_Time(DS3231_Time_Buffer);
  181. }

  182. void main()
  183. {
  184.         sys_init();
  185.         while(1)
  186.         {
  187.                 Get_Time();//日期時間獲取和轉(zhuǎn)換
  188.                 Get_Temp();//氣壓溫度獲取和轉(zhuǎn)換
  189.                 Get_VCC();//電源電壓獲取和轉(zhuǎn)換
  190.                 Display_Flash_Dynamic();//動態(tài)掃描,刷新變化的數(shù)據(jù)
  191.         }
  192. }
復(fù)制代碼

【程序下載】
基于STM8S103的手表設(shè)計 發(fā)布版 凌凈清河.zip (2.95 MB, 下載次數(shù): 258)
【DS3231中文手冊】
DS3231中文手冊.pdf (449.27 KB, 下載次數(shù): 98)
【BMP180淘寶資料】

GY68BMP180.zip (3.27 MB, 下載次數(shù): 119)


如果你喜歡這個設(shè)計,或者對本設(shè)計有任何不明白之處,或者在51的路上有些孤獨,就來QQ群找我吧~!群號:873434536

評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

ID:251455 發(fā)表于 2019-3-19 17:13 | 顯示全部樓層
正好在學(xué)習STM8,謝謝樓主了

評分

參與人數(shù) 1黑幣 +16 收起 理由
凌凈清河 + 16 黑幣補貼

查看全部評分

回復(fù)

使用道具 舉報

ID:284488 發(fā)表于 2019-3-25 10:12 | 顯示全部樓層
正好需要了解,下載學(xué)習了,感謝樓主分享。不了解之處還要跟樓主多多請教。

評分

參與人數(shù) 1黑幣 +16 收起 理由
凌凈清河 + 16 黑幣補貼

查看全部評分

回復(fù)

使用道具 舉報

ID:333807 發(fā)表于 2019-4-4 09:54 | 顯示全部樓層
正好需要了解,下載學(xué)習了,感謝樓主分享。不了解之處還要跟樓主多多請教。

評分

參與人數(shù) 1黑幣 +16 收起 理由
凌凈清河 + 16 黑幣補貼

查看全部評分

回復(fù)

使用道具 舉報

ID:236621 發(fā)表于 2019-5-20 20:48 | 顯示全部樓層
學(xué)習學(xué)習
回復(fù)

使用道具 舉報

ID:326044 發(fā)表于 2019-5-20 21:46 | 顯示全部樓層
正好在學(xué)習STM8,謝謝樓主了
回復(fù)

使用道具 舉報

ID:124851 發(fā)表于 2019-6-10 05:08 | 顯示全部樓層
如何增加按鍵,對時間和日期進行修改?
回復(fù)

使用道具 舉報

ID:555941 發(fā)表于 2019-6-11 23:23 來自手機 | 顯示全部樓層
感謝樓主分享,抱拳
回復(fù)

使用道具 舉報

ID:334781 發(fā)表于 2019-7-28 12:17 | 顯示全部樓層
51hei 論壇真的很好,感謝大師們的無私奉獻,謝謝,收下了。
回復(fù)

使用道具 舉報

ID:362076 發(fā)表于 2019-7-29 14:25 | 顯示全部樓層
wjnnlove 發(fā)表于 2019-6-10 05:08
如何增加按鍵,對時間和日期進行修改?

這個嘛,實現(xiàn)方式還是很多的,后續(xù)我會發(fā)一個手表設(shè)計的改進版,那個有無線調(diào)時功能,期待一下吧~
回復(fù)

使用道具 舉報

ID:257024 發(fā)表于 2019-10-12 12:52 | 顯示全部樓層
剛好想做一個DS3231時鐘時找到這篇。感謝大師的無私奉獻。謝謝。

評分

參與人數(shù) 1黑幣 +5 收起 理由
凌凈清河 + 5 不用謝

查看全部評分

回復(fù)

使用道具 舉報

ID:230666 發(fā)表于 2020-1-16 11:56 | 顯示全部樓層
感謝大師的無私奉獻。謝謝。 研究研究bmp180

評分

參與人數(shù) 1黑幣 +5 收起 理由
凌凈清河 + 5 不用謝

查看全部評分

回復(fù)

使用道具 舉報

ID:230666 發(fā)表于 2020-1-18 16:40 | 顯示全部樓層
已經(jīng)成功驅(qū)動bmp180  使用f103c8t6

評分

參與人數(shù) 1黑幣 +5 收起 理由
凌凈清河 + 5 good

查看全部評分

回復(fù)

使用道具 舉報

ID:334781 發(fā)表于 2020-1-31 18:47 | 顯示全部樓層
正好需要呢,用STM32F0 搞了一天,時間 就是不走,謝謝了
回復(fù)

使用道具 舉報

ID:579587 發(fā)表于 2020-3-24 09:35 | 顯示全部樓層
本帖最后由 hdhgsdhuers 于 2020-3-24 09:47 編輯



感謝提供源碼正好搞ds3231和oled,可能是oled型號不同樓主提供的代碼無法顯示,花了點時間替換成可以用的,ds3231正常時間可以走 WIN_20200324_09_45_50_Pro.jpg

WIN_20200324_09_45_45_Pro.jpg

。

評分

參與人數(shù) 1黑幣 +5 收起 理由
凌凈清河 + 5 斯國一!!

查看全部評分

回復(fù)

使用道具 舉報

ID:696971 發(fā)表于 2020-4-16 14:25 | 顯示全部樓層


感謝,學(xué)習學(xué)習,要轉(zhuǎn)戰(zhàn)stm了~
回復(fù)

使用道具 舉報

ID:548321 發(fā)表于 2020-9-16 16:57 | 顯示全部樓層
正在學(xué)習STM8S103P如何讀取BMP180的數(shù)據(jù),好不容易找到這篇質(zhì)量比較高的帖子,想下載程序好好學(xué)習一下,正在努力賺黑幣
回復(fù)

使用道具 舉報

ID:496706 發(fā)表于 2020-9-25 15:19 | 顯示全部樓層
有辦法顯示圖片嗎,小白請示
回復(fù)

使用道具 舉報

ID:362076 發(fā)表于 2020-9-27 13:55 | 顯示全部樓層
buxy 發(fā)表于 2020-9-25 15:19
有辦法顯示圖片嗎,小白請示

可以,例如全圖顯示,可以對128*64的圖像二值化并取模,而后使用相應(yīng)的寫函數(shù)去刷圖像就可以了。如果是任意像素的圖像,建議使用幀緩沖區(qū)。
回復(fù)

使用道具 舉報

ID:337139 發(fā)表于 2020-11-7 13:55 | 顯示全部樓層
現(xiàn)在正在做這個設(shè)計!
回復(fù)

使用道具 舉報

ID:884042 發(fā)表于 2022-4-3 22:26 | 顯示全部樓層
建議樓主加上按鍵,把它改成可以調(diào)時間,然后過段時間就會自動熄屏的
回復(fù)

使用道具 舉報

ID:14106 發(fā)表于 2025-1-12 22:10 | 顯示全部樓層
學(xué)習了
回復(fù)

使用道具 舉報

ID:14106 發(fā)表于 2025-1-12 22:11 | 顯示全部樓層
正好需要這個參考,學(xué)習了
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表