用stm32控制并读取DS1302,外加TFT屏幕显示实时时间

一:DS1302

   1.概述:

        DS1302 是 DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和 31 字节静态RAM 通过简单的串行接口与单片机进行通信。

       
 实时时钟/日历电路提供秒 、分 、时 、日 、日期 、月 、年的信息,而且每月的天 数和闰年的天数可自动调整。

        时钟操作可通过 AM/PM 指示决定采用 24 或 12 小时格式 DS1302 与单片机之

间能简单地采用同步串行的方式进行通信,
通信仅需用到三个口线:  RES(复位 )、I/O (数据线 )、SCLK(串行时钟 )。

        时钟/RAM 的读/写数据以一个字节或多达 31 个字节的字符组方式通信 DS1302 工作时功耗很

低,保持数据和时钟信息时功率小于 1mW 。

       该模块采用双电源供电,当模块连接单片机主板时,由单片机的主电源供电,否则采用备用电源,一般是一个纽扣电池,有助于模块与主电源断开连接时,DS1302芯片内部任然可以进行走时操作。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55m95pel5qKm6ICB5L2Z,size_20,color_FFFFFF,t_70,g_se,x_16watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55m95pel5qKm6ICB5L2Z,size_10,color_FFFFFF,t_70,g_se,x_16

   2.管脚描述:
watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55m95pel5qKm6ICB5L2Z,size_7,color_FFFFFF,t_70,g_se,x_16

        X1 X2 ——32.768KHz 晶振管脚

        GND ——地

        RST ——复位脚

        I/O ——数据输入/输出引脚

        SCLK ——串行时钟

        Vcc1,Vcc2 ——电源供电管脚

二:TFT

  1.概述:

        QD180AR7735模块是1.8“TFTLCD,65K彩色128×160分辨率。该LCD模块的控制器为ST7735,支持4线SPI控制接口。此外,该模块还包括5V-3.3V电源转换电路和IO-电平转换电路,它还包括SD卡插座。

        (我使用的就是8针1.8寸的TFT屏幕)

 2.管脚描述

8针LCD接口针映射
1 VCC 电源输入(3.3V/5V)
2 GND 接地
3 CS 液晶屏片选信号,低电平使能
4 RESET 液晶屏复位信号,低电平复位
5 A0 液晶屏寄存器/数据选择信号,高电平:寄存器,低电平:数据
6 SDA SPI总线写数据信号
7 SCK SPI总线时钟信号
8 LED  背光控制,高电平点亮,如无需控制则接3.3V常亮

三.代码实现:

  DS1302.c文件:

#include "ds1302.h"
#include "delay.h"
 
struct TIMEData TimeData;
char read_time[7];
char DS1302_data_1[10];
char DS1302_data_2[8];

void ds1302_gpio_init()//CE,SCLK端口初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PC.11  CE
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.11
GPIO_ResetBits(GPIOC,GPIO_Pin_0); 
 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PC.12  SCLK
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.12
GPIO_ResetBits(GPIOC,GPIO_Pin_3); 
}
 
void ds1302_DATAOUT_init()//配置双向I/O端口为输出态
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PC.10  DATA
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.10
GPIO_ResetBits(GPIOC,GPIO_Pin_2);
}
 
void ds1302_DATAINPUT_init()//配置双向I/O端口为输入态
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PC.10 DATA
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.10
}
 
 
void ds1302_write_onebyte(unsigned char data)//向DS1302发送一字节数据
{
	unsigned char count=0;
ds1302_DATAOUT_init();
SCLK_L;
for(count=0;count<8;count++)
	{	SCLK_L;
		if(data&0x01)
		{DATA_H;}
		else{DATA_L;}//先准备好数据再发送
		SCLK_H;//拉高时钟线,发送数据
		data>>=1;
	}
}
 
void ds1302_wirte_rig(unsigned char address,unsigned char data)//向指定寄存器地址发送数据
{
unsigned char temp1=address;
unsigned char temp2=data;
CE_L;SCLK_L;delay_us(1);
CE_H;delay_us(2);
ds1302_write_onebyte(temp1);
ds1302_write_onebyte(temp2);
CE_L;SCLK_L;delay_us(2);
}
 
unsigned char ds1302_read_rig(unsigned char address)//从指定地址读取一字节数据
{
unsigned char temp3=address;
unsigned char count=0;
unsigned char return_data=0x00;
CE_L;SCLK_L;delay_us(3);
CE_H;delay_us(3);
ds1302_write_onebyte(temp3);
ds1302_DATAINPUT_init();//配置I/O口为输入
delay_us(2);
for(count=0;count<8;count++)
	{
	delay_us(2);//使电平持续一段时间
	return_data>>=1;
	SCLK_H;delay_us(4);//使高电平持续一段时间
	SCLK_L;delay_us(14);//延时14us后再去读取电压,更加准确
	if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2))
	{return_data=return_data|0x80;}
	
	}
delay_us(2);
CE_L;DATA_L;
return return_data;
}
 
void ds1302_init()
{
ds1302_wirte_rig(0x8e,0x00);//关闭写保护
ds1302_wirte_rig(0x80,0x00);//seconds 0秒
ds1302_wirte_rig(0x82,0x03);//minutes 03分
ds1302_wirte_rig(0x84,0x21);//hours   21时
ds1302_wirte_rig(0x86,0x19);//date    19日
ds1302_wirte_rig(0x88,0x01);//months   1月
ds1302_wirte_rig(0x8a,0x07);//days    星期日
ds1302_wirte_rig(0x8c,0x22);//year    2022年
ds1302_wirte_rig(0x8e,0x80);//关闭写保护
}
 
void ds1302_read_time()
{
read_time[0]=ds1302_read_rig(0x81);//读秒
read_time[1]=ds1302_read_rig(0x83);//读分
read_time[2]=ds1302_read_rig(0x85);//读时
read_time[3]=ds1302_read_rig(0x87);//读日
read_time[4]=ds1302_read_rig(0x89);//读月
read_time[5]=ds1302_read_rig(0x8B);//读星期
read_time[6]=ds1302_read_rig(0x8D);//读年
}
 
void ds1302_read_realTime()
{
ds1302_read_time();  //BCD码转换为10进制
TimeData.second=(read_time[0]>>4)*10+(read_time[0]&0x0f);
TimeData.minute=((read_time[1]>>4)&(0x07))*10+(read_time[1]&0x0f);
TimeData.hour=(read_time[2]>>4)*10+(read_time[2]&0x0f);
TimeData.day=(read_time[3]>>4)*10+(read_time[3]&0x0f);
TimeData.month=(read_time[4]>>4)*10+(read_time[4]&0x0f);
TimeData.week=read_time[5];
TimeData.year=(read_time[6]>>4)*10+(read_time[6]&0x0f)+2000;
	DS1302_data_1[0]='2';
	DS1302_data_1[1]='0';
	DS1302_data_1[2]='0'+(TimeData.year-2000)/10;
	DS1302_data_1[3]='0'+(TimeData.year-2000)%10;
	DS1302_data_1[4]='-';
	DS1302_data_1[5]='0'+TimeData.month/10;
	DS1302_data_1[6]='0'+TimeData.month%10;
	DS1302_data_1[7]='-';
	DS1302_data_1[8]='0'+TimeData.day/10;
	DS1302_data_1[9]='0'+TimeData.day%10;
	
	DS1302_data_2[0]='0'+TimeData.hour/10;
	DS1302_data_2[1]='0'+TimeData.hour%10;
	DS1302_data_2[2]=':';
	DS1302_data_2[3]='0'+TimeData.minute/10;
	DS1302_data_2[4]='0'+TimeData.minute%10;
	DS1302_data_2[5]=':';
	DS1302_data_2[6]='0'+TimeData.second/10;
	DS1302_data_2[7]='0'+TimeData.second%10;
}

  DS1302.h文件:

#ifndef __ds1302_H 
#define __ds1302_H  
 
 
#define CE_L GPIO_ResetBits(GPIOC,GPIO_Pin_0)//拉低使能位
#define CE_H GPIO_SetBits(GPIOC,GPIO_Pin_0)//拉高使能位
#define SCLK_L GPIO_ResetBits(GPIOC,GPIO_Pin_3)//拉低时钟线
#define SCLK_H  GPIO_SetBits(GPIOC,GPIO_Pin_3)//拉高时钟线
#define DATA_L  GPIO_ResetBits(GPIOC,GPIO_Pin_2)//拉低数据线
#define DATA_H  GPIO_SetBits(GPIOC,GPIO_Pin_2)//拉高数据线
 
struct TIMEData
{
	unsigned int year;
	unsigned char month;
	unsigned char  day;
	unsigned char  hour;
	unsigned char  minute;
	unsigned char  second;
	unsigned char  week;
};//创建TIMEData结构体方便存储时间日期数据
extern struct TIMEData TimeData;//全局变量
void ds1302_gpio_init(void);//ds1302端口初始化
void ds1302_write_onebyte(unsigned char data);//向ds1302发送一字节数据
void ds1302_wirte_rig(unsigned char address,unsigned char data);//向指定寄存器写一字节数据
unsigned char ds1302_read_rig(unsigned char address);//从指定寄存器读一字节数据
void ds1302_init(void);//ds1302初始化函数
void ds1302_DATAOUT_init(void);//IO端口配置为输出
void ds1302_DATAINPUT_init(void);//IO端口配置为输入
void ds1302_read_time(void);//从ds1302读取实时时间(BCD码)
void ds1302_read_realTime(void);//将BCD码转化为十进制数据
 
#endif

  Lcd_Driver.c文件:

#include "stm32f10x.h"
#include "Lcd_Driver.h"
#include "LCD_Config.h"
#include "delay.h"



//本测试程序使用的是模拟SPI接口驱动
//可自由更改接口IO配置,使用任意最少4 IO即可完成本款液晶驱动显示
/******************************************************************************
接口定义在Lcd_Driver.h内定义,请根据接线修改并修改相应IO初始化LCD_GPIO_Init()
#define LCD_CTRL   	  	GPIOB		//定义TFT数据端口
#define LCD_LED        	GPIO_Pin_9  //PB9--->>TFT --BL
#define LCD_RS (AO)     GPIO_Pin_10	//PB10--->>TFT --RS/DC
#define LCD_CS        	GPIO_Pin_11  //PB11--->>TFT --CS/CE
#define LCD_RST     		GPIO_Pin_12	//PB12--->>TFT --RST
#define LCD_SCL        	GPIO_Pin_13	//PB13--->>TFT --SCL/SCK
#define LCD_SDA        	GPIO_Pin_15	//PB15 MOSI--->>TFT --SDA/DIN
*******************************************************************************/


//液晶IO初始化配置
void LCD_GPIO_Init(void)
{

	GPIO_InitTypeDef  GPIO_InitStructure;
	      
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB ,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9| GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14| GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
      
}


/****************************************************************************
* 名    称:void ili9320_WriteIndex(u16 idx)
* 功    能:写 ili9320 控制器寄存器地址
* 入口参数:idx   寄存器地址
* 出口参数:无
* 说    明:调用前需先选中控制器,内部函数
* 调用方法:ili9320_WriteIndex(0x0000);
****************************************************************************/
void Lcd_WriteIndex(u8 Index)
{
   u8 i=0;
   //SPI 写命令时序开始
   LCD_CS_CLR;
   LCD_RS_CLR;
   //刷屏100次  32秒   320ms/屏
   for(i=8;i>0;i--)
   {
      if(Index&0x80)	
	  LCD_SDA_SET; //输出数据
      else 
	  LCD_SDA_CLR; 

      LCD_SCL_CLR;      
      LCD_SCL_SET;
      Index<<=1; 
   }
   LCD_CS_SET;
}

/****************************************************************************
* 名    称:void ili9320_WriteData(u16 dat)
* 功    能:写 ili9320 寄存器数据
* 入口参数:dat     寄存器数据
* 出口参数:无
* 说    明:向控制器指定地址写入数据,调用前需先写寄存器地址,内部函数
* 调用方法:ili9320_WriteData(0x1030)
****************************************************************************/
void Lcd_WriteData(u8 Data)
{
   u8 i=0;
   LCD_CS_CLR;
   LCD_RS_SET;
    //刷屏100次  32秒   320ms/屏
   for(i=8;i>0;i--)
   {
      if(Data&0x80)	
	  LCD_SDA_SET; //输出数据
      else LCD_SDA_CLR;
	   
      LCD_SCL_CLR;       
      LCD_SCL_SET;
      Data<<=1; 
   }
   LCD_CS_SET; 
}

void Lcd_WriteReg(u8 Index,u8 Data)
{
	Lcd_WriteIndex(Index);
   	Lcd_WriteData(Data);
}

void Lcd_Reset(void)
{
	LCD_RST_CLR;
	delay_ms(100);
	LCD_RST_SET;
	delay_ms(50);
}


void Lcd_Init(u8 dir)
{	
	LCD_GPIO_Init();
	Lcd_Reset();

if(dir==0)//Init for ST7735R
{
	Lcd_WriteIndex(0x11);//Sleep exit 
	delay_ms (120);
	
	//ST7735R Frame Rate
	Lcd_WriteIndex(0xB1); 
	Lcd_WriteData(0x01); Lcd_WriteData(0x2C); Lcd_WriteData(0x2D); 
	Lcd_WriteIndex(0xB2); 
	Lcd_WriteData(0x01); Lcd_WriteData(0x2C); Lcd_WriteData(0x2D); 
	Lcd_WriteIndex(0xB3); 
	Lcd_WriteData(0x01); Lcd_WriteData(0x2C); Lcd_WriteData(0x2D); 
	Lcd_WriteData(0x01); Lcd_WriteData(0x2C); Lcd_WriteData(0x2D); 
	
	Lcd_WriteIndex(0xB4); //Column inversion 
	Lcd_WriteData(0x07); 
	
	//ST7735R Power Sequence
	Lcd_WriteIndex(0xC0); 
	Lcd_WriteData(0xA2); Lcd_WriteData(0x02); Lcd_WriteData(0x84); 
	Lcd_WriteIndex(0xC1); Lcd_WriteData(0xC5); 
	Lcd_WriteIndex(0xC2); 
	Lcd_WriteData(0x0A); Lcd_WriteData(0x00); 
	Lcd_WriteIndex(0xC3); 
	Lcd_WriteData(0x8A); Lcd_WriteData(0x2A); 
	Lcd_WriteIndex(0xC4); 
	Lcd_WriteData(0x8A); Lcd_WriteData(0xEE); 
	
	Lcd_WriteIndex(0xC5); //VCOM 
	Lcd_WriteData(0x0E); 
	
	Lcd_WriteIndex(0x36); //MX, MY, RGB mode 
	Lcd_WriteData(0xC0); 
	
	//ST7735R Gamma Sequence
	Lcd_WriteIndex(0xe0); 
	Lcd_WriteData(0x0f); Lcd_WriteData(0x1a); 
	Lcd_WriteData(0x0f); Lcd_WriteData(0x18); 
	Lcd_WriteData(0x2f); Lcd_WriteData(0x28); 
	Lcd_WriteData(0x20); Lcd_WriteData(0x22); 
	Lcd_WriteData(0x1f); Lcd_WriteData(0x1b); 
	Lcd_WriteData(0x23); Lcd_WriteData(0x37); Lcd_WriteData(0x00); 
	
	Lcd_WriteData(0x07); 
	Lcd_WriteData(0x02); Lcd_WriteData(0x10); 
	Lcd_WriteIndex(0xe1); 
	Lcd_WriteData(0x0f); Lcd_WriteData(0x1b); 
	Lcd_WriteData(0x0f); Lcd_WriteData(0x17); 
	Lcd_WriteData(0x33); Lcd_WriteData(0x2c); 
	Lcd_WriteData(0x29); Lcd_WriteData(0x2e); 
	Lcd_WriteData(0x30); Lcd_WriteData(0x30); 
	Lcd_WriteData(0x39); Lcd_WriteData(0x3f); 
	Lcd_WriteData(0x00); Lcd_WriteData(0x07); 
	Lcd_WriteData(0x03); Lcd_WriteData(0x10);  
	
	Lcd_WriteIndex(0x2a);
	Lcd_WriteData(0x00);Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);Lcd_WriteData(0x7f);
	Lcd_WriteIndex(0x2b);
	Lcd_WriteData(0x00);Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);Lcd_WriteData(0x9f);
	
	Lcd_WriteIndex(0xF0); //Enable test command  
	Lcd_WriteData(0x01); 
	Lcd_WriteIndex(0xF6); //Disable ram power save mode 
	Lcd_WriteData(0x00); 
	
	Lcd_WriteIndex(0x3A); //65k mode 
	Lcd_WriteData(0x05); 
	
	
	Lcd_WriteIndex(0x29);//Display on
}

else if(dir==1) //Init for ST7735S
{
	Lcd_WriteIndex(0x11);
	delay_ms (120); //Delay 120ms

	Lcd_WriteIndex(0xb1);
	Lcd_WriteData(0x05);
	Lcd_WriteData(0x3c);
	Lcd_WriteData(0x3c);
	Lcd_WriteIndex(0xb2);
	Lcd_WriteData(0x05);
	Lcd_WriteData(0x3c);
	Lcd_WriteData(0x3c);
	Lcd_WriteIndex(0xb3);
	Lcd_WriteData(0x05);
	Lcd_WriteData(0x3c);
	Lcd_WriteData(0x3c);
	Lcd_WriteData(0x05);
	Lcd_WriteData(0x3c);
	Lcd_WriteData(0x3c);

	Lcd_WriteIndex(0xb4);
	Lcd_WriteData(0x03);

	Lcd_WriteIndex(0xc0);
	Lcd_WriteData(0x2e);
	Lcd_WriteData(0x06);
	Lcd_WriteData(0x04);
	Lcd_WriteIndex(0xc1);
	Lcd_WriteData(0xc0);
	Lcd_WriteIndex(0xc2);
	Lcd_WriteData(0x0d);
	Lcd_WriteData(0x00);
	Lcd_WriteIndex(0xc3);
	Lcd_WriteData(0x8d);
	Lcd_WriteData(0xea);
	Lcd_WriteIndex(0xc5);//set vcom  
	Lcd_WriteData(0x03);//VCOM=  

	Lcd_WriteIndex(0xc4);
	Lcd_WriteData(0x8d);
	Lcd_WriteData(0xee);
	//Lcd_WriteIndex(0x21);

	Lcd_WriteIndex(0x36);
	Lcd_WriteData(0xc0);

	Lcd_WriteIndex(0xe0);
	Lcd_WriteData(0x03);
	Lcd_WriteData(0x1f);
	Lcd_WriteData(0x06);
	Lcd_WriteData(0x0b);
	Lcd_WriteData(0x35);
	Lcd_WriteData(0x35);
	Lcd_WriteData(0x30);
	Lcd_WriteData(0x33);
	Lcd_WriteData(0x31);
	Lcd_WriteData(0x2e);
	Lcd_WriteData(0x34);
	Lcd_WriteData(0x3e);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x01);
	Lcd_WriteData(0x03);

	Lcd_WriteIndex(0xe1);
	Lcd_WriteData(0x03);
	Lcd_WriteData(0x1e);
	Lcd_WriteData(0x06);
	Lcd_WriteData(0x0b);
	Lcd_WriteData(0x35);
	Lcd_WriteData(0x34);
	Lcd_WriteData(0x2f);
	Lcd_WriteData(0x33);
	Lcd_WriteData(0x32);
	Lcd_WriteData(0x2e);
	Lcd_WriteData(0x35);
	Lcd_WriteData(0x3e);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x01);
	Lcd_WriteData(0x02);
	Lcd_WriteData(0x04);

	Lcd_WriteIndex(0x21);
	Lcd_WriteIndex(0x29);
	Lcd_WriteIndex(0x2c);
}
else if(dir==2)//Init for ILI9163
{

Lcd_WriteIndex(0x11);       //start OSC
    delay_ms (100);
    
    Lcd_WriteIndex(0x3a);       //start OSC
    Lcd_WriteData(0x05);
   
    Lcd_WriteIndex(0x26);       //start OSC
    Lcd_WriteData(0x04);
	
    Lcd_WriteIndex(0xf2);              //Driver Output Control(1)
    Lcd_WriteData(0x01);
    
    Lcd_WriteIndex(0xe0);              //Driver Output Control(1)
    Lcd_WriteData(0x3f);
    Lcd_WriteData(0x25);
    Lcd_WriteData(0x1c);
    Lcd_WriteData(0x1e);
    Lcd_WriteData(0x20);
    Lcd_WriteData(0x12);
    Lcd_WriteData(0x2a);
    Lcd_WriteData(0x90);
    Lcd_WriteData(0x24);
    Lcd_WriteData(0x11);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x00);
     
    Lcd_WriteIndex(0xe1);              //Driver Output Control(1)
    Lcd_WriteData(0x20);
    Lcd_WriteData(0x20);
    Lcd_WriteData(0x20);
    Lcd_WriteData(0x20);
    Lcd_WriteData(0x05);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x15);
    Lcd_WriteData(0xa7);
    Lcd_WriteData(0x3d);
    Lcd_WriteData(0x18);
    Lcd_WriteData(0x25);
    Lcd_WriteData(0x2a);
    Lcd_WriteData(0x2b);
    Lcd_WriteData(0x2b);  
    Lcd_WriteData(0x3a);  
    
    Lcd_WriteIndex(0xb1);              //LCD Driveing control
    Lcd_WriteData(0x08);
    Lcd_WriteData(0x08);
    
    Lcd_WriteIndex(0xb4);              //LCD Driveing control
    Lcd_WriteData(0x07);
   
   
    Lcd_WriteIndex(0xc0);              //LCD Driveing control
    Lcd_WriteData(0x0a);
    Lcd_WriteData(0x02);
      
    Lcd_WriteIndex(0xc1);              //LCD Driveing control
    Lcd_WriteData(0x02);

    Lcd_WriteIndex(0xc5);              //LCD Driveing control
    Lcd_WriteData(0x4f);
    Lcd_WriteData(0x5a);

    Lcd_WriteIndex(0xc7);              //LCD Driveing control
    Lcd_WriteData(0x40);
    
    Lcd_WriteIndex(0x2a);              //LCD Driveing control
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x7f);
   
    Lcd_WriteIndex(0x2b);              //LCD Driveing control
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x00);
    Lcd_WriteData(0x7f);
    Lcd_WriteIndex(0x36);              //LCD Driveing control
    Lcd_WriteData(0xc8);//横屏0xA8 竖屏0xC8
    Lcd_WriteIndex(0xb7);              //LCD Driveing control
    Lcd_WriteData(0x00);
//    Lcd_WriteIndex(0xb8);              //LCD Driveing control
//    Lcd_WriteData(0x01);
	   
    Lcd_WriteIndex(0x29);   
    Lcd_WriteIndex(0x2c);   

}

	


}


/*************************************************
函数名:LCD_Set_Region
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:xy起点和终点,Y_IncMode表示先自增y再自增x
返回值:无
*************************************************/
void Lcd_SetRegion(u16 x_start,u16 y_start,u16 x_end,u16 y_end)
{		
	Lcd_WriteIndex(0x2a);
	Lcd_WriteData(0x00);
	Lcd_WriteData(x_start);
	Lcd_WriteData(0x00);
	Lcd_WriteData(x_end);

	Lcd_WriteIndex(0x2b);
	Lcd_WriteData(0x00);
	Lcd_WriteData(y_start);
	Lcd_WriteData(0x00);
	Lcd_WriteData(y_end);

	Lcd_WriteIndex(0x2c);

}

/*************************************************
函数名:LCD_Set_XY
功能:设置lcd显示起始点
入口参数:xy坐标
返回值:无
*************************************************/
void Lcd_SetXY(u16 x,u16 y)
{
  	Lcd_SetRegion(x,y,x,y);
}

	
/*************************************************
函数名:LCD_DrawPoint
功能:画一个点
入口参数:无
返回值:无
*************************************************/
void Gui_DrawPoint(u16 x,u16 y,u16 Data)
{
	Lcd_SetRegion(x,y,x+1,y+1);
	Lcd_WriteData(Data>>8);
	Lcd_WriteData(Data);

}    

/*****************************************
 函数功能:读TFT某一点的颜色                          
 出口参数:color  点颜色值                                 
******************************************/
unsigned int Lcd_ReadPoint(u16 x,u16 y)
{
  unsigned int Data;
  Lcd_SetXY(x,y);

  //Lcd_ReadData();//丢掉无用字节
  //Data=Lcd_ReadData();
  Lcd_WriteData(Data);
  return Data;
}
/*************************************************
函数名:Lcd_Clear
功能:全屏清屏函数
入口参数:填充颜色COLOR
返回值:无
*************************************************/
void Lcd_Clear(u16 Color)               
{	
   unsigned int i,m;
   Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
   Lcd_WriteIndex(0x2C);
   for(i=0;i<128;i++)
    for(m=0;m<160;m++)
    {	
	  	Lcd_WriteData(Color>>8);
			Lcd_WriteData(Color);
    }   
}

 Lcd_Driver.h文件:




#define RED  	0xf800
#define GREEN	0x07e0
#define BLUE 	0x001f
#define WHITE	0xffff
#define BLACK	0x0000
#define YELLOW  0xFFE0
#define GRAY0   0xEF7D   	//灰色0 3165 00110 001011 00101
#define GRAY1   0x8410      	//灰色1      00000 000000 00000
#define GRAY2   0x4208      	//灰色2  1111111111011111




#define LCD_CTRL   	  	GPIOB		//定义TFT数据端口
#define LCD_LED        	GPIO_Pin_9  //MCU_PB9--->>TFT --BL
#define LCD_RS         	GPIO_Pin_10	//PB11--->>TFT --RS/DC
#define LCD_CS        	GPIO_Pin_11  //MCU_PB11--->>TFT --CS/CE
#define LCD_RST     		GPIO_Pin_12	//PB10--->>TFT --RST
#define LCD_SCL        	GPIO_Pin_13	//PB13--->>TFT --SCL/SCK
#define LCD_SDA        	GPIO_Pin_15	//PB15 MOSI--->>TFT --SDA/DIN


//#define LCD_CS_SET(x) LCD_CTRL->ODR=(LCD_CTRL->ODR&~LCD_CS)|(x ? LCD_CS:0)

//液晶控制口置1操作语句宏定义
#define	LCD_CS_SET  	LCD_CTRL->BSRR=LCD_CS    
#define	LCD_RS_SET  	LCD_CTRL->BSRR=LCD_RS    
#define	LCD_SDA_SET  	LCD_CTRL->BSRR=LCD_SDA    
#define	LCD_SCL_SET  	LCD_CTRL->BSRR=LCD_SCL    
#define	LCD_RST_SET  	LCD_CTRL->BSRR=LCD_RST    
#define	LCD_LED_SET  	LCD_CTRL->BSRR=LCD_LED   

//液晶控制口置0操作语句宏定义
#define	LCD_CS_CLR  	LCD_CTRL->BRR=LCD_CS    
#define	LCD_RS_CLR  	LCD_CTRL->BRR=LCD_RS    
#define	LCD_SDA_CLR  	LCD_CTRL->BRR=LCD_SDA    
#define	LCD_SCL_CLR  	LCD_CTRL->BRR=LCD_SCL    
#define	LCD_RST_CLR  	LCD_CTRL->BRR=LCD_RST    
#define	LCD_LED_CLR  	LCD_CTRL->BRR=LCD_LED 


#define LCD_DATAOUT(x) LCD_DATA->ODR=x; //数据输出
#define LCD_DATAIN     LCD_DATA->IDR;   //数据输入

#define LCD_WR_DATA(data){\
LCD_RS_SET;\
LCD_CS_CLR;\
LCD_DATAOUT(data);\
LCD_WR_CLR;\
LCD_WR_SET;\
LCD_CS_SET;\
} 



void LCD_GPIO_Init(void);
void Lcd_WriteIndex(u8 Index);
void Lcd_WriteData(u8 Data);
void Lcd_WriteReg(u8 Index,u8 Data);
u16 Lcd_ReadReg(u8 LCD_Reg);
void Lcd_Reset(void);
void Lcd_Init(u8 dir);
void Lcd_Clear(u16 Color);
void Lcd_SetXY(u16 x,u16 y);
void Gui_DrawPoint(u16 x,u16 y,u16 Data);
unsigned int Lcd_ReadPoint(u16 x,u16 y);

 Lcd_Config.h文件:


#define X_MAX_PIXEL	        128
#define Y_MAX_PIXEL	        160


 GUI.c文件:(这是TFT在Lcd_Driver.c文件在基础上已经封装好的UI操作函数)

#include "stm32f10x.h"
#include "Lcd_Driver.h"
#include "GUI.h"
#include "delay.h"
#include "font.h"
#include "Picture.h"
unsigned char Num[10]={0,1,2,3,4,5,6,7,8,9};

//从ILI93xx读出的数据为GBR格式,而我们写入的时候为RGB格式。
//通过该函数转换
//c:GBR格式的颜色值
//返回值:RGB格式的颜色值
u16 LCD_BGR2RGB(u16 c)
{
  u16  r,g,b,rgb;   
  b=(c>>0)&0x1f;
  g=(c>>5)&0x3f;
  r=(c>>11)&0x1f;	 
  rgb=(b<<11)+(g<<5)+(r<<0);		 
  return(rgb);

}




void Gui_Circle(u16 X,u16 Y,u16 R,u16 fc) 
{//Bresenham算法 
    unsigned short  a,b; 
    int c; 
    a=0; 
    b=R; 
    c=3-2*R; 
    while (a<b) 
    { 
        Gui_DrawPoint(X+a,Y+b,fc);     //        7 
        Gui_DrawPoint(X-a,Y+b,fc);     //        6 
        Gui_DrawPoint(X+a,Y-b,fc);     //        2 
        Gui_DrawPoint(X-a,Y-b,fc);     //        3 
        Gui_DrawPoint(X+b,Y+a,fc);     //        8 
        Gui_DrawPoint(X-b,Y+a,fc);     //        5 
        Gui_DrawPoint(X+b,Y-a,fc);     //        1 
        Gui_DrawPoint(X-b,Y-a,fc);     //        4 

        if(c<0) c=c+4*a+6; 
        else 
        { 
            c=c+4*(a-b)+10; 
            b-=1; 
        } 
       a+=1; 
    } 
    if (a==b) 
    { 
        Gui_DrawPoint(X+a,Y+b,fc); 
        Gui_DrawPoint(X+a,Y+b,fc); 
        Gui_DrawPoint(X+a,Y-b,fc); 
        Gui_DrawPoint(X-a,Y-b,fc); 
        Gui_DrawPoint(X+b,Y+a,fc); 
        Gui_DrawPoint(X-b,Y+a,fc); 
        Gui_DrawPoint(X+b,Y-a,fc); 
        Gui_DrawPoint(X-b,Y-a,fc); 
    } 
	
} 
//画线函数,使用Bresenham 画线算法
void Gui_DrawLine(u16 x0, u16 y0,u16 x1, u16 y1,u16 Color)   
{
int dx,             // difference in x's
    dy,             // difference in y's
    dx2,            // dx,dy * 2
    dy2, 
    x_inc,          // amount in pixel space to move during drawing
    y_inc,          // amount in pixel space to move during drawing
    error,          // the discriminant i.e. error i.e. decision variable
    index;          // used for looping	


	Lcd_SetXY(x0,y0);
	dx = x1-x0;//计算x距离
	dy = y1-y0;//计算y距离

	if (dx>=0)
	{
		x_inc = 1;
	}
	else
	{
		x_inc = -1;
		dx    = -dx;  
	} 
	
	if (dy>=0)
	{
		y_inc = 1;
	} 
	else
	{
		y_inc = -1;
		dy    = -dy; 
	} 

	dx2 = dx << 1;
	dy2 = dy << 1;

	if (dx > dy)//x距离大于y距离,那么每个x轴上只有一个点,每个y轴上有若干个点
	{//且线的点数等于x距离,以x轴递增画点
		// initialize error term
		error = dy2 - dx; 

		// draw the line
		for (index=0; index <= dx; index++)//要画的点数不会超过x距离
		{
			//画点
			Gui_DrawPoint(x0,y0,Color);
			
			// test if error has overflowed
			if (error >= 0) //是否需要增加y坐标值
			{
				error-=dx2;

				// move to next line
				y0+=y_inc;//增加y坐标值
			} // end if error overflowed

			// adjust the error term
			error+=dy2;

			// move to the next pixel
			x0+=x_inc;//x坐标值每次画点后都递增1
		} // end for
	} // end if |slope| <= 1
	else//y轴大于x轴,则每个y轴上只有一个点,x轴若干个点
	{//以y轴为递增画点
		// initialize error term
		error = dx2 - dy; 

		// draw the line
		for (index=0; index <= dy; index++)
		{
			// set the pixel
			Gui_DrawPoint(x0,y0,Color);

			// test if error overflowed
			if (error >= 0)
			{
				error-=dy2;

				// move to next line
				x0+=x_inc;
			} // end if error overflowed

			// adjust the error term
			error+=dx2;

			// move to the next pixel
			y0+=y_inc;
		} // end for
	} // end else |slope| > 1
}



void Gui_box(u16 x, u16 y, u16 w, u16 h,u16 bc)
{
	Gui_DrawLine(x,y,x+w,y,0xEF7D);
	Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965);
	Gui_DrawLine(x,y+h,x+w,y+h,0x2965);
	Gui_DrawLine(x,y,x,y+h,0xEF7D);
    Gui_DrawLine(x+1,y+1,x+1+w-2,y+1+h-2,bc);
}
void Gui_box2(u16 x,u16 y,u16 w,u16 h, u8 mode)
{
	if (mode==0)	{
		Gui_DrawLine(x,y,x+w,y,0xEF7D);
		Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965);
		Gui_DrawLine(x,y+h,x+w,y+h,0x2965);
		Gui_DrawLine(x,y,x,y+h,0xEF7D);
		}
	if (mode==1)	{
		Gui_DrawLine(x,y,x+w,y,0x2965);
		Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xEF7D);
		Gui_DrawLine(x,y+h,x+w,y+h,0xEF7D);
		Gui_DrawLine(x,y,x,y+h,0x2965);
	}
	if (mode==2)	{
		Gui_DrawLine(x,y,x+w,y,0xffff);
		Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xffff);
		Gui_DrawLine(x,y+h,x+w,y+h,0xffff);
		Gui_DrawLine(x,y,x,y+h,0xffff);
	}
}


/**************************************************************************************
功能描述: 在屏幕显示一凸起的按钮框
输    入: u16 x1,y1,x2,y2 按钮框左上角和右下角坐标
输    出: 无
**************************************************************************************/
void DisplayButtonDown(u16 x1,u16 y1,u16 x2,u16 y2)
{
	Gui_DrawLine(x1,  y1,  x2,y1, GRAY2);  //H
	Gui_DrawLine(x1+1,y1+1,x2,y1+1, GRAY1);  //H
	Gui_DrawLine(x1,  y1,  x1,y2, GRAY2);  //V
	Gui_DrawLine(x1+1,y1+1,x1+1,y2, GRAY1);  //V
	Gui_DrawLine(x1,  y2,  x2,y2, WHITE);  //H
	Gui_DrawLine(x2,  y1,  x2,y2, WHITE);  //V
}

/**************************************************************************************
功能描述: 在屏幕显示一凹下的按钮框
输    入: u16 x1,y1,x2,y2 按钮框左上角和右下角坐标
输    出: 无
**************************************************************************************/
void DisplayButtonUp(u16 x1,u16 y1,u16 x2,u16 y2)
{
	Gui_DrawLine(x1,  y1,  x2,y1, WHITE); //H
	Gui_DrawLine(x1,  y1,  x1,y2, WHITE); //V
	
	Gui_DrawLine(x1+1,y2-1,x2,y2-1, GRAY1);  //H
	Gui_DrawLine(x1,  y2,  x2,y2, GRAY2);  //H
	Gui_DrawLine(x2-1,y1+1,x2-1,y2, GRAY1);  //V
    Gui_DrawLine(x2  ,y1  ,x2,y2, GRAY2); //V
}


void Gui_DrawFont_GBK16(u16 x, u16 y, u16 fc, u16 bc, char *s)
{
	unsigned char i,j;
	unsigned short k,x0;
	x0=x;

	while(*s) 
	{	
		if((*s) < 128) 
		{
			k=*s;
			if (k==13) 
			{
				x=x0;
				y+=16;
			}
			else 
			{
				if (k>32) k-=32; else k=0;
	
			    for(i=0;i<16;i++)
				for(j=0;j<8;j++) 
					{
				    	if(asc16[k*16+i]&(0x80>>j))	Gui_DrawPoint(x+j,y+i,fc);
						else 
						{
							if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
						}
					}
				x+=8;
			}
			s++;
		}
			
		else 
		{
		

			for (k=0;k<hz16_num;k++) 
			{
			  if ((hz16[k].Index[0]==*(s))&&(hz16[k].Index[1]==*(s+1)))
			  { 
				    for(i=0;i<16;i++)
				    {
						for(j=0;j<8;j++) 
							{
						    	if(hz16[k].Msk[i*2]&(0x80>>j))	Gui_DrawPoint(x+j,y+i,fc);
								else {
									if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
								}
							}
						for(j=0;j<8;j++) 
							{
						    	if(hz16[k].Msk[i*2+1]&(0x80>>j))	Gui_DrawPoint(x+j+8,y+i,fc);
								else 
								{
									if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc);
								}
							}
				    }
				}
			  }
			s+=2;x+=16;
		} 
		
	}
}

void Gui_DrawFont_GBK24(u16 x, u16 y, u16 fc, u16 bc, u8 *s)
{
	unsigned char i,j;
	unsigned short k;

	while(*s) 
	{
		if( *s < 0x80 ) 
		{
			k=*s;
			if (k>32) k-=32; else k=0;

		    for(i=0;i<16;i++)
			for(j=0;j<8;j++) 
				{
			    	if(asc16[k*16+i]&(0x80>>j))	
					Gui_DrawPoint(x+j,y+i,fc);
					else 
					{
						if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
					}
				}
			s++;x+=8;
		}
		else 
		{

			for (k=0;k<hz24_num;k++) 
			{
			  if ((hz24[k].Index[0]==*(s))&&(hz24[k].Index[1]==*(s+1)))
			  { 
				    for(i=0;i<24;i++)
				    {
						for(j=0;j<8;j++) 
							{
						    	if(hz24[k].Msk[i*3]&(0x80>>j))
								Gui_DrawPoint(x+j,y+i,fc);
								else 
								{
									if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
								}
							}
						for(j=0;j<8;j++) 
							{
						    	if(hz24[k].Msk[i*3+1]&(0x80>>j))	Gui_DrawPoint(x+j+8,y+i,fc);
								else {
									if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc);
								}
							}
						for(j=0;j<8;j++) 
							{
						    	if(hz24[k].Msk[i*3+2]&(0x80>>j))	
								Gui_DrawPoint(x+j+16,y+i,fc);
								else 
								{
									if (fc!=bc) Gui_DrawPoint(x+j+16,y+i,bc);
								}
							}
				    }
			  }
			}
			s+=2;x+=24;
		}
	}
}
void Gui_DrawFont_Num32(u16 x, u16 y, u16 fc, u16 bc, u16 num)
{
	unsigned char i,j,k,c;
	//lcd_text_any(x+94+i*42,y+34,32,32,0x7E8,0x0,sz32,knum[i]);
//	w=w/8;

    for(i=0;i<32;i++)
	{
		for(j=0;j<4;j++) 
		{
			c=*(sz32+num*32*4+i*4+j);
			for (k=0;k<8;k++)	
			{
	
		    	if(c&(0x80>>k))	Gui_DrawPoint(x+j*8+k,y+i,fc);
				else {
					if (fc!=bc) Gui_DrawPoint(x+j*8+k,y+i,bc);
				}
			}
		}
	}
}

void Redraw_Mainmenu(void)
{

	Lcd_Clear(GRAY0);
	
	Gui_DrawFont_GBK16(16,0,BLUE,GRAY0,"全动电子技术");
	Gui_DrawFont_GBK16(16,20,RED,GRAY0,"液晶测试程序");

	DisplayButtonUp(15,38,113,58); //x1,y1,x2,y2
	Gui_DrawFont_GBK16(16,40,YELLOW,GRAY0,"颜色填充测试");

	DisplayButtonUp(15,68,113,88); //x1,y1,x2,y2
	Gui_DrawFont_GBK16(16,70,BLUE,GRAY0,"文字显示测试");

	DisplayButtonUp(15,98,113,118); //x1,y1,x2,y2
	Gui_DrawFont_GBK16(16,100,RED,GRAY0,"图片显示测试");


	Gui_DrawFont_GBK16(16,120,BLUE,GRAY0,"S1:Move.    ");
	Gui_DrawFont_GBK16(16,140,RED,GRAY0, "S2:Sellect  ");
	
	Gui_DrawFont_Num32(100,125,RED,GRAY0,Num[5]);
	delay_ms(1000);
	Gui_DrawFont_Num32(100,125,RED,GRAY0,Num[4]);
	delay_ms(1000);
	Gui_DrawFont_Num32(100,125,RED,GRAY0,Num[3]);
	delay_ms(1000);
	Gui_DrawFont_Num32(100,125,RED,GRAY0,Num[2]);
	delay_ms(1000);
	Gui_DrawFont_Num32(100,125,RED,GRAY0,Num[1]);
	delay_ms(1000);
	Gui_DrawFont_Num32(100,125,RED,GRAY0,Num[0]);	
}

void Num_Test(void)
{
	u8 i=0;
	Lcd_Clear(GRAY0);
	Gui_DrawFont_GBK16(16,20,RED,GRAY0,"Num Test");
	delay_ms(1000);
	Lcd_Clear(GRAY0);

	for(i=0;i<10;i++)
	{
	Gui_DrawFont_Num32((i%3)*40,32*(i/3)+30,RED,GRAY0,Num[i+1]);
	delay_ms(100);
	}
	
}

void Font_Test(void)
{
	Lcd_Clear(GRAY0);
	Gui_DrawFont_GBK16(16,10,BLUE,GRAY0,"文字显示测试");

	delay_ms(1000);
	Lcd_Clear(GRAY0);
	Gui_DrawFont_GBK16(16,30,YELLOW,GRAY0,"全动电子技术");
	Gui_DrawFont_GBK16(16,50,BLUE,GRAY0,"专注液晶批发");
	Gui_DrawFont_GBK16(16,70,RED,GRAY0, "全程技术支持");
	Gui_DrawFont_GBK16(0,100,BLUE,GRAY0,"Tel:15989313508");
	Gui_DrawFont_GBK16(0,130,RED,GRAY0, "www.qdtech.net");	
	delay_ms(1800);	
}

void Color_Test(void)
{
	u8 i=1;
	Lcd_Clear(GRAY0);
	
	Gui_DrawFont_GBK16(20,10,BLUE,GRAY0,"Color Test");
	delay_ms(200);

	while(i--)
	{
	Lcd_Clear(WHITE);
	Lcd_Clear(BLACK);
	Lcd_Clear(RED);
  Lcd_Clear(GREEN);
  Lcd_Clear(BLUE);
	}		
}
//16位 垂直扫描  右到左  高位在前
void show_pic(void)
{
	int i,j,k;
	unsigned char picH,picL;
	Lcd_Clear(GRAY0);
	Gui_DrawFont_GBK16(16,10,BLUE,GRAY0,"图片显示测试");
	delay_ms(1000);
	Lcd_Clear(GRAY0);
	k=0;
	for(i=0;i<128;i++)
	for(j=0;j<160;j++)
	{
		picH=gImage_123[k++];
		picL=gImage_123[k++];
		Lcd_WriteData(picH);
		Lcd_WriteData(picL);
	}	
} 

 GUI.h文件:




u16 LCD_BGR2RGB(u16 c);
void Gui_Circle(u16 X,u16 Y,u16 R,u16 fc); 
void Gui_DrawLine(u16 x0, u16 y0,u16 x1, u16 y1,u16 Color);  
void Gui_box(u16 x, u16 y, u16 w, u16 h,u16 bc);
void Gui_box2(u16 x,u16 y,u16 w,u16 h, u8 mode);
void DisplayButtonDown(u16 x1,u16 y1,u16 x2,u16 y2);
void DisplayButtonUp(u16 x1,u16 y1,u16 x2,u16 y2);

void Gui_DrawFont_GBK16(u16 x, u16 y, u16 fc, u16 bc, char *s);
void Gui_DrawFont_GBK24(u16 x, u16 y, u16 fc, u16 bc, u8 *s);
void Gui_DrawFont_Num32(u16 x, u16 y, u16 fc, u16 bc, u16 num) ;

void Redraw_Mainmenu(void);
void Num_Test(void);
void Font_Test(void);
void Color_Test(void);
void show_pic(void);


 main.c文件:

#include "stm32f10x.h"
#include <math.h>    //Keil library  
#include <stdio.h>   //Keil library	
#include "Delay.H"
#include "Lcd_Driver.h"
#include "GUI.h"
#include "DS1302.H"
extern char DS1302_data_1[10];//当前时间
extern char DS1302_data_2[8];//当前时间
int main(void)
{
	SystemInit();
  delay_init(72);//延时初始化
//-----------------------------------------------------------
	Lcd_Init(0);//LCD初始化
	LCD_LED_SET;//通过IO控制背光亮
	Lcd_Clear(GRAY0);//LCD清屏
//-----------------------------------------------------------	
	ds1302_gpio_init();delay_ms(5); //初始化ds1302端口
	//ds1032_init();delay_ms(5);      //ds1302初始化,用于第一次使用DS1302,赋时间初值
	ds1302_read_realTime();         //读取实时数据
	min=TimeData.minute;            //记录此时分钟值

	while(1)
	{

			//DS1302读取数据,TFT屏幕显示
			ds1302_read_realTime();    //读取此时时刻
			Gui_DrawFont_GBK16(1,100,BLUE,GRAY0,DS1302_data_1);//TFT屏幕显示DS1302数据
			Gui_DrawFont_GBK16(1,120,BLUE,GRAY0,DS1302_data_2);//TFT屏幕显示DS1302数据	
	
	} 
}

.新手可能会遇到的疑点

        1.TFT屏幕显示内容或者串口输出内容有时候是需要发送字符串的,但如果需要发送的变量是整型而不是字符型,该怎么把整型数据转化为字符串呢?

        可采用DS1302.c中的一个笨方法,如图:

        这里涉及到的算法有C语言中的:提取多位数中的各个位数(取余,取整思想),还有单字符的加减法。(详细教程请参考其他资料)

        提取多位数中的各个位数(取余,取整思想):

int a,b,c,d,e;
a=1234;
b=a/1000;
c=a/100%10;
d=a/10%10;
e=a%10;

如上所示,该代码结果b=1,c=2,d=3,e=4。

        单字符的加减法:

char a;
a='0'+4;

如上所示,该代码结果会得到字符a='4'。

        2.关于DS1302初始时间怎么设置的问题,如图:

 该函数的作用是为DS1302写入初始时间,一般这个函数只会在你第一次使用DS1302模块或者更新模块时间时使用。而改变它初始时间的方法就是将初始的、年、月、日、时、分、秒、周用16进制写入上图标荧光的地方。

 或者为了方便,也可以将函数中的年月日时分秒周单独放入一个数组中,然后在函数中调用数组就可以了

unsigned int DS1302_start_Data[7]={0x22,0x01,0x19,0x21,0x03,0x00,0x07};//年月日时分秒周


void ds1302_init()
{
ds1302_wirte_rig(0x8e,0x00);//关闭写保护
ds1302_wirte_rig(0x80,DS1302_start_Data[5]);//seconds 0秒
ds1302_wirte_rig(0x82,DS1302_start_Data[4]);//minutes 03分
ds1302_wirte_rig(0x84,DS1302_start_Data[3]);//hours   21时
ds1302_wirte_rig(0x86,DS1302_start_Data[2]);//date    19日
ds1302_wirte_rig(0x88,DS1302_start_Data[1]);//months   1月
ds1302_wirte_rig(0x8a,DS1302_start_Data[6]);//days    星期日
ds1302_wirte_rig(0x8c,DS1302_start_Data[0]);//year    2022年
ds1302_wirte_rig(0x8e,0x80);//关闭写保护
}

(这是本人发表的第一篇文章,望大家给予宝贵的建议)

物联沃分享整理
物联沃-IOTWORD物联网 » 用stm32控制并读取DS1302,外加TFT屏幕显示实时时间

发表评论