|
本制作僅設計了基本功能,即基于題目所述器件的基本使用,為有興趣的人提供了設計參考雛形和界面UI靈感。如需優化,可以參考如下方面:
1.添加電池供電電路
2.添加藍牙功能和時間修改接口以便于上位機通信
3.低功耗設計,包括延時滅屏、ADC/溫度氣壓觸發更新等
4.可以考慮添加更多功能,例如基于加速度計的計步功能、基于角度傳感器的抬腕顯示功能以及基于心率傳感器的心率監測等。
本設計采用STM8S103F3P6核心板主控。實時時鐘RTC芯片采用DS3231;氣壓和溫度數據來自BMP180;供電電壓測量數據由片內ADC第七通道數值讀取和換算得到;顯示模塊采用SSD1306驅動的OLED12864模塊,通訊接口為IIC。另外,專門對6X8、12X24的數字字體進行重新設計,使之觀看起來更加舒適,字體取模方式見工程中說明。
為了方便讀者各部分分開使用的需求,雖然這幾個器件都是IIC,我卻沒有使用IIC總線連接方式,各個器件都以模擬IIC連接,各個器件的定義都在其C文件中。
如需移植到51,需要做以下更改:
1.引腳定義的函數都刪掉,用sbit定義連接
2.IIC的SDA引腳不分IN/OUT
3.修改頭文件
4.修改_Bool數據類型為bit
另外注意,本程序需要7K左右的Flash。
【整體連接】
因為不想在這個上面浪費時間,所以硬件部分直接使用OK飛線連接的,具體接線方式見下文
幾個部分的連接.jpg (596.48 KB, 下載次數: 132)
下載附件
2019-3-9 15:51 上傳
【顯示屏界面設計】
日期部分原本想放計步功能的,因為有其他事情要忙,就沒做這個功能,用日期占位了。
顯示屏.jpg (576.73 KB, 下載次數: 138)
下載附件
2019-3-9 15:52 上傳
【顯示屏和BMP180】
BMP180和DS3231是用熱熔膠粘在一起了的。
顯示屏和BMP180.jpg (207.75 KB, 下載次數: 140)
下載附件
2019-3-9 15:52 上傳
【顯示屏和DS3231】
顯示屏和DS3231.jpg (318.89 KB, 下載次數: 120)
下載附件
2019-3-9 15:52 上傳
【核心板引腳分配】
這個是用STM8CubeMX做的,因為各個不菲都是用的模塊,所以連線非常方便,也不用什么額外的上拉電阻濾波電容之類的。
引腳連接.png (35.9 KB, 下載次數: 110)
下載附件
2019-3-9 15:54 上傳
【主程序】
- #include"iostm8s103f3.h"
- #include"init.c"
- #include"OLED12864.c"
- #include"OLED12864_6X8.c"
- #include"OLED12864_8X16.c"
- #include"OLED12864_12X24.c"
- #include"DS3231.c"
- #include"BMP180.c"
- #include"ADC.c"
- /************************************************************
- 名稱:基于STM8S103F3P6、OLED12864、BMP180和DS3231的手表設計
- 平臺:STM8S103F3P6,HSI:16MHz不分頻,Flash:8K,RAM:1K
- 簡介:本設計采用STM8S103F3P6核心板主控。
- 實時時鐘RTC芯片采用DS3231;
- 氣壓和溫度數據來自BMP180;
- 供電電壓測量數據由片內ADC第七通道數值讀取和換算得到;
- 顯示模塊采用SSD1306驅動的OLED12864模塊,通訊接口為IIC。
- 另外,專門對6X8、12X24的數字字體進行重新設計,
- 使之觀看起來更加舒適,字體取模方式見工程中說明。
- 注意:本制作僅設計了基本功能,即基于上述器件的基本使用,
- 為有興趣的人提供了設計參考雛形和界面UI靈感。
- 如需優化,可以參考如下方面:
- 1.添加電池供電電路
- 2.添加藍牙功能和時間修改接口以便于上位機通信
- 3.低功耗設計,包括延時滅屏、ADC/溫度氣壓觸發更新等
- 4.可以考慮添加更多功能,例如基于加速度計的計步功能、
- 基于角度傳感器的抬腕顯示功能以及基于心率傳感器的
- 心率監測等。
- 程序編寫:凌凈清河
- 硬件制作:凌凈欣羽
- 文稿排版:凌凈欣羽
- 日期:2019年3月9日
- 聲明:如您直接使用本例程或進行較大程度的借鑒,請注明程序出處,謝謝!
- 所屬:新礦城學習基地#2019
- ************************************************************/
- //運行數組
- unsigned char Display_Time[6]={0};
- unsigned char Display_Date[9]={2,0,1,9,0,3,0,9,6};
- unsigned char Display_Pressure[4]={0};//前3位為整數部分,后1位是小數部分
- unsigned char Display_Temperature[3]={0};//前2位為整數部分,后1位是小數部分
- unsigned char Display_Voltage[3]={0};//前1位為整數部分,后2位是小數部分
- //靜態顯示,上電只運行一次
- void Display_Flash_Fixed()
- {
- OLED12864_6X8_AnyChar(18,0,'.',1);
- OLED12864_6X8_AnyString(30,0,"Kpa",0);
- OLED12864_6X8_AnyChar(69,0,'.',1);
- OLED12864_6X8_AnyChar(87,0,'V',0);
- OLED12864_6X8_AnyChar(110,0,'.',1);
- OLED12864_6X8_AnyChar(122,0,'C',0);
- OLED12864_12X24_MH(40,1);
- OLED12864_12X24_MH(76,1);
- _OLED12864_8X16_AnyChar(40,5,'.',1);
- _OLED12864_8X16_AnyChar(64,5,'.',1);
- OLED12864_6X8_AnyString(1,7," Linyar Lab. Watch ",0);
- }
- //動態掃描,刷新變化的數據
- void Display_Flash_Dynamic()
- {
- //氣壓顯示
- if(Display_Pressure[0]==0)
- {
- OLED12864_6X8_AnyChar(0,0,' ',1);
- }
- else
- {
- OLED12864_6X8_AnyNumber(0,0,Display_Pressure[0],1);
- }
- OLED12864_6X8_AnyNumber(6,0,Display_Pressure[1],1);
- OLED12864_6X8_AnyNumber(12,0,Display_Pressure[2],1);
- OLED12864_6X8_AnyNumber(24,0,Display_Pressure[3],1);
- //電壓顯示
- OLED12864_6X8_AnyNumber(63,0,Display_Voltage[0],1);
- OLED12864_6X8_AnyNumber(75,0,Display_Voltage[1],1);
- OLED12864_6X8_AnyNumber(81,0,Display_Voltage[2],1);
- //溫度顯示
- if(Display_Temperature[0]==0)
- {
- OLED12864_6X8_AnyChar(98,0,' ',1);
- }
- else
- {
- OLED12864_6X8_AnyNumber(98,0,Display_Temperature[0],1);
- }
- OLED12864_6X8_AnyNumber(104,0,Display_Temperature[1],1);
- OLED12864_6X8_AnyNumber(116,0,Display_Temperature[2],1);
- //時間顯示
- OLED12864_12X24_AnyNumber(16,1,Display_Time[0]);
- OLED12864_12X24_AnyNumber(28,1,Display_Time[1]);
- OLED12864_12X24_AnyNumber(52,1,Display_Time[2]);
- OLED12864_12X24_AnyNumber(64,1,Display_Time[3]);
- OLED12864_12X24_AnyNumber(88,1,Display_Time[4]);
- OLED12864_12X24_AnyNumber(100,1,Display_Time[5]);
- //日期顯示
- OLED12864_8X16_AnyNumber(8,5,Display_Date[0]);
- OLED12864_8X16_AnyNumber(16,5,Display_Date[1]);
- OLED12864_8X16_AnyNumber(24,5,Display_Date[2]);
- OLED12864_8X16_AnyNumber(32,5,Display_Date[3]);
- if(Display_Date[4]==0)
- {
- _OLED12864_8X16_AnyChar(48,5,' ',1);
- }
- else
- {
- OLED12864_8X16_AnyNumber(48,5,Display_Date[4]);
- }
- OLED12864_8X16_AnyNumber(56,5,Display_Date[5]);
- if(Display_Date[6]==0)
- {
- _OLED12864_8X16_AnyChar(72,5,' ',1);
- }
- else
- {
- OLED12864_8X16_AnyNumber(72,5,Display_Date[6]);
- }
- OLED12864_8X16_AnyNumber(80,5,Display_Date[7]);
- //星期顯示
- switch(Display_Date[8])
- {
- case 1:OLED12864_8X16_AnyString(96,5,"MON");break;
- case 2:OLED12864_8X16_AnyString(96,5,"TUE");break;
- case 3:OLED12864_8X16_AnyString(96,5,"WED");break;
- case 4:OLED12864_8X16_AnyString(96,5,"THU");break;
- case 5:OLED12864_8X16_AnyString(96,5,"FRI");break;
- case 6:OLED12864_8X16_AnyString(96,5,"SAT");break;
- case 7:OLED12864_8X16_AnyString(96,5,"SUN");break;
- default:OLED12864_8X16_AnyString(96,5,"ERR");break;
- }
- }
- void Get_Time()
- {
- DS3231_Get_Time();
- //時間取顯示位
- Display_Time[0]=DS3231_Time_Buffer[2]>>4;
- Display_Time[1]=DS3231_Time_Buffer[2]&0x0f;
- Display_Time[2]=DS3231_Time_Buffer[1]>>4;
- Display_Time[3]=DS3231_Time_Buffer[1]&0x0f;
- Display_Time[4]=DS3231_Time_Buffer[0]>>4;
- Display_Time[5]=DS3231_Time_Buffer[0]&0x0f;
- //日期取顯示位
- Display_Date[2]=DS3231_Time_Buffer[6]>>4;
- Display_Date[3]=DS3231_Time_Buffer[6]&0x0f;
- Display_Date[4]=DS3231_Time_Buffer[5]>>4;
- Display_Date[5]=DS3231_Time_Buffer[5]&0x0f;
- Display_Date[6]=DS3231_Time_Buffer[4]>>4;
- Display_Date[7]=DS3231_Time_Buffer[4]&0x0f;
- Display_Date[8]=DS3231_Time_Buffer[3]&0x0f;
- }
- void Get_Temp()
- {
- BMP180_Calculate();
- Display_Temperature[0]=BMP180_Temperature/100;
- Display_Temperature[1]=BMP180_Temperature%100/10;
- Display_Temperature[2]=BMP180_Temperature%10;
- Display_Pressure[0]=BMP180_Pressure/100000;
- Display_Pressure[1]=BMP180_Pressure%100000/10000;
- Display_Pressure[2]=BMP180_Pressure%10000/1000;
- Display_Pressure[3]=BMP180_Pressure%1000/100;
- }
- void Get_VCC()
- {
- unsigned int ADC_Value=0;//ADC轉換結果值
- unsigned int Voltage_VCC=0;//推算出的VCC電壓值,單位毫伏
- ADC_Value=Get_ADC1_Value();
- Voltage_VCC=(unsigned int)((1250.4799/(float)ADC_Value)*1000);
- Display_Voltage[0]=(Voltage_VCC)/1000;
- Display_Voltage[1]=(Voltage_VCC%1000)/100;
- Display_Voltage[2]=(Voltage_VCC%100)/10;
- }
- void sys_init()
- {
- CLK_init();
- ADC1_Init();
- OLED12864_IIC_OUT();
- OLED_Init();
- DS3231_IIC_OUT();
- BMP180_IIC_OUT();
- Init_BMP180();
- Display_Flash_Fixed();
- DS3231_Set_Time(DS3231_Time_Buffer);
- }
- void main()
- {
- sys_init();
- while(1)
- {
- Get_Time();//日期時間獲取和轉換
- Get_Temp();//氣壓溫度獲取和轉換
- Get_VCC();//電源電壓獲取和轉換
- Display_Flash_Dynamic();//動態掃描,刷新變化的數據
- }
- }
復制代碼
【程序下載】
基于STM8S103的手表設計 發布版 凌凈清河.zip
(2.95 MB, 下載次數: 258)
2019-3-9 16:04 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
【DS3231中文手冊】
DS3231中文手冊.pdf
(449.27 KB, 下載次數: 98)
2019-3-9 16:05 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
【BMP180淘寶資料】
GY68BMP180.zip
(3.27 MB, 下載次數: 119)
2019-3-9 16:05 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
如果你喜歡這個設計,或者對本設計有任何不明白之處,或者在51的路上有些孤獨,就來QQ群找我吧~!群號:873434536
|
評分
-
查看全部評分
|