1. 項(xiàng)目簡(jiǎn)介
這是基于STM32設(shè)計(jì)的一個(gè)指針式電子鐘+萬(wàn)年歷小項(xiàng)目,采用3.5寸的LCD屏顯示時(shí)鐘,日歷、溫度、天氣,支持觸摸屏調(diào)整設(shè)置時(shí)間,設(shè)置鬧鐘,查看日歷等等。整體項(xiàng)目主要是技術(shù)點(diǎn)就是LCD屏的圖形繪制。比如: 時(shí)鐘的時(shí)針繪制、分針、秒針、表盤、日歷繪制等等。
時(shí)鐘的時(shí)間是直接采用STM32本身的RTC時(shí)鐘,室內(nèi)的室溫?cái)?shù)據(jù)采用DS18B20溫度傳感器獲取,STM32芯片的具體型號(hào)是STM32F103ZET6,只要是STM32F1系列的開(kāi)發(fā)板,代碼都是可以通用的。
LCD顯示屏采用的正點(diǎn)原子的3.5寸TFT顯示屏,支持8080時(shí)序,自帶觸摸屏功能,觸摸屏是電阻屏,驅(qū)動(dòng)芯片是XPT2046,SPI接口,通信非常方便。
STM32F103ZET6帶有FSMC功能,可以輸出8080時(shí)序,本項(xiàng)目里驅(qū)動(dòng)LCD屏就采用FSMC控制的,效率比較高。
主界面如下:
項(xiàng)目源碼下載地址: https://download.csdn.net/download/xiaolong1126626497/63897554
項(xiàng)目視頻演示地址: https://live.csdn.net/v/182594
2. 項(xiàng)目功能介紹
下面對(duì)每個(gè)子功能頁(yè)面做詳細(xì)講解。
2.1 實(shí)時(shí)時(shí)鐘頁(yè)面
在LCD屏上方顯示表盤、分針、時(shí)針、 秒針、刻度、更改時(shí)鐘時(shí)間方塊,并實(shí)現(xiàn)分針、時(shí)針、秒針的移動(dòng),在實(shí)時(shí)時(shí)鐘下方同步顯示數(shù)字時(shí)鐘。
運(yùn)用觸摸屏功能實(shí)現(xiàn)時(shí)鐘設(shè)置功能,點(diǎn)擊“+” “-”至設(shè)置時(shí)鐘方塊,跳出設(shè)置時(shí)鐘界面,即可開(kāi)始設(shè)置時(shí)鐘與日期;點(diǎn)擊“+”“-”至設(shè)置鬧鐘方塊,跳出設(shè)置鬧鐘界面,即可開(kāi)始設(shè)置鬧鐘。
2.2 日歷頁(yè)面
在LCD屏中部顯示日期、星期、天氣、實(shí)時(shí)溫度,在LCD屏下方顯示日歷、左右兩邊顯示黃歷,并在日歷上重點(diǎn)突出今天的日期。
3. 項(xiàng)目實(shí)現(xiàn)主要程序講解
3.1 流程圖
3.2 ds18b2.c 代碼
下面列出DS18B20溫度傳感器主要代碼.
#include "ds18b20.h"
#include "delay.h"
?
//復(fù)位DS18B20
void DS18B20_Rst(void)
{
DS18B20_IO_OUT(); //SET PG11 OUTPUT
DS18B20_DQ_OUT=0; //拉低DQ
DelayUs(750); //拉低750us
DS18B20_DQ_OUT=1; //DQ=1
DelayUs(15); //15US
}
//等待DS18B20的回應(yīng)
//返回1:未檢測(cè)到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void)
{
u8 retry=0;
DS18B20_IO_IN(); //SET PG11 INPUT
while (DS18B20_DQ_IN&&retry<200)
{
retry++;
DelayUs(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
DelayUs(1);
};
if(retry>=240)return 1;
return 0;
}
//從DS18B20讀取一個(gè)位
//返回值:1/0
u8 DS18B20_Read_Bit(void)
{
u8 data;
DS18B20_IO_OUT(); //SET PG11 OUTPUT
DS18B20_DQ_OUT=0;
DelayUs(2);
DS18B20_DQ_OUT=1;
DS18B20_IO_IN(); //SET PG11 INPUT
DelayUs(12);
if(DS18B20_DQ_IN)data=1;
else data=0;
DelayUs(50);
return data;
}
//從DS18B20讀取一個(gè)字節(jié)
//返回值:讀到的數(shù)據(jù)
u8 DS18B20_Read_Byte(void)
{
u8 i,j,dat;
dat=0;
for (i=1;i<=8;i++)
{
j=DS18B20_Read_Bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
//寫一個(gè)字節(jié)到DS18B20
//dat:要寫入的字節(jié)
void DS18B20_Write_Byte(u8 dat)
{
u8 j;
u8 testb;
DS18B20_IO_OUT(); //SET PG11 OUTPUT;
for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
DS18B20_DQ_OUT=0; // Write 1
DelayUs(2);
DS18B20_DQ_OUT=1;
DelayUs(60);
}
else
{
DS18B20_DQ_OUT=0; // Write 0
DelayUs(60);
DS18B20_DQ_OUT=1;
DelayUs(2);
}
}
}
//開(kāi)始溫度轉(zhuǎn)換
void DS18B20_Start(void)
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc); // skip rom
DS18B20_Write_Byte(0x44); // convert
}
//初始化DS18B20的IO口 DQ 同時(shí)檢測(cè)DS的存在
//返回1:不存在
//返回0:存在
u8 DS18B20_Init(void)
{
RCC->APB2ENR|=1<<8; //使能PORTG口時(shí)鐘
GPIOG->CRH&=0XFFFF0FFF; //PORTG.11 推挽輸出
GPIOG->CRH|=0X00003000;
GPIOG->ODR|=1<<11; //輸出1
DS18B20_Rst();
return DS18B20_Check();
}
//從ds18b20得到溫度值
//精度:0.1C
//返回值:溫度值 (-550~1250)
short DS18B20_Get_Temp(void)
{
u8 temp;
u8 TL,TH;
short tem;
DS18B20_Start (); // ds1820 start convert
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc); // skip rom
DS18B20_Write_Byte(0xbe); // convert
TL=DS18B20_Read_Byte(); // LSB
TH=DS18B20_Read_Byte(); // MSB
if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0; //溫度為負(fù)
}else temp=1; //溫度為正
tem=TH; //獲得高八位
tem<<=8;
tem+=TL; //獲得底八位
tem=(float)tem*0.625; //轉(zhuǎn)換
if(temp)return tem; //返回溫度值
else return -tem;
}
3.3 lcd屏圖形繪制核心算法
整個(gè)項(xiàng)目的功能都是在LCD顯示屏上,需要繪制線段、繪制圓、繪制矩形、繪制角度線段、繪制中文、繪制數(shù)字等等,下面列出這部分的核心代碼。
/*
函數(shù)功能:畫橫直線
函數(shù)形參:x,y:坐標(biāo)
length:長(zhǎng)度
*/
void LcdDrawThwartLine(u16 x,u16 y,u16 length,u16 color)
{
u16 i;
for(i=0;i0)incx=1; //設(shè)置單步方向
else if(delta_x==0)incx=0;//垂直線
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;//水平線
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x; //選取基本增量坐標(biāo)軸
else distance=delta_y;
for(t=0;t<=distance+1;t++ )//畫線輸出
{
LcdDrawPoint(uRow,uCol,color);//畫點(diǎn)
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
?
?
//在指定位置畫一個(gè)指定大小的圓
//(x,y):中心點(diǎn)
//r :半徑
void LcdDraw_Circle(u16 x0,u16 y0,u8 r,u16 color)
{
int a,b;
int di;
a=0;b=r;
di=3-(r<<1); //判斷下個(gè)點(diǎn)位置的標(biāo)志
while(a<=b)
{
LcdDrawPoint(x0+a,y0-b,color); //5
LcdDrawPoint(x0+b,y0-a,color); //0
LcdDrawPoint(x0+b,y0+a,color); //4
LcdDrawPoint(x0+a,y0+b,color); //6
LcdDrawPoint(x0-a,y0+b,color); //1
LcdDrawPoint(x0-b,y0+a,color);
LcdDrawPoint(x0-a,y0-b,color); //2
LcdDrawPoint(x0-b,y0-a,color); //7
a++;
//使用Bresenham算法畫圓
if(di<0)di +=4*a+6;
else
{
di+=10+4*(a-b);
b--;
}
}
}
?
/*
函數(shù)功能:任意角度畫直線
參 數(shù):
w :以圓心開(kāi)始不要畫的長(zhǎng)度
len:半徑
c :顏色
x,y:坐標(biāo)
實(shí)際長(zhǎng)度=len-w
*/
?
void LcdDrawAngleLine(u32 x,u32 y,float du,u32 len,u32 w,u16 c)
{
int i;
int x0,y0;
float k=du*(3.1415926535/180);
for(i=len-w;i;i++)>;i++)>
審核編輯:湯梓紅
-
STM32
+關(guān)注
關(guān)注
2264文章
10854瀏覽量
354289 -
電子鐘
+關(guān)注
關(guān)注
7文章
189瀏覽量
36888 -
顯示時(shí)鐘
+關(guān)注
關(guān)注
0文章
5瀏覽量
1623
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論