stm32 12864 lcd显示时间和温度

#include "stm32f10x.h"
#include "stdio.h"

//-------------------------------------------------------------------------------------------------
#define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//读取按键0
#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取按键1
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键2

#define KEY0_PRES 1 //KEY0
#define KEY1_PRES 2 //KEY1
#define WKUP_PRES 3 //WK_UP
//-------------------------------------------------------------------------------------------------
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C

#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08

//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入

#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入

#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入

#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入

#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入

#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入

#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
//-------------------------------------------------------------------------------------------------
#define LED0 PAout(8) // PA8
#define LED1 PDout(2) // PD2
#define LED2 PAout(2)
#define LED3 PAout(3)
//-------------------------------------------------------------------------------------------------
// lcd12864
//-------------------------------------

------------------------------------------------------------
#define SID_H GPIOC->BSRR=GPIO_Pin_7
#define SID_L GPIOC->BRR=GPIO_Pin_7
#define CS_H GPIOC->BSRR=GPIO_Pin_8
#define CS_L GPIOC->BRR=GPIO_Pin_8
#define SCLK_H GPIOC->BSRR=GPIO_Pin_6
#define SCLK_L GPIOC->BRR=GPIO_Pin_6
#define x1 0x80
#define x2 0x88
#define y 0x80
#define comm 0
#define dat1 1
u8 const num_lcd[]={"0123456789"};
void Clr_Scr(void);
void LCD_Write_String(u8 X,u8 Y,uc8 *s);//12864
u8 A,B,C,D;
void display_temp_time(void);
void display_main(void);
void display_1(void);
//-------------------------------------------------------------------------------------------------
// DS1302
//-------------------------------------------------------------------------------------------------
#define ds1302clk GPIO_Pin_12
#define ds1302dat GPIO_Pin_13
#define ds1302rst GPIO_Pin_14
uint8_t time_ds1302[7]={0x00,0x54,0x10,0x08,0x12,0x01,0x08};
uint8_t read[] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//读秒、分、时、日、月、周、年的寄存器地址
uint8_t write[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//写秒、分、时、日、月、周、年的寄存器地址

//按键中断按下显示时间,所以需要全局变量
uint8_t i=0,g[7];
void ds1302_data(uint8_t *read);
uint8_t DSPH[]={"00"};
uint8_t DSPM[]={"00"};
uint8_t DSPS[]={"00"};
uint8_t DSPN[]={"00"};
uint8_t DSPY[]={"00"};
uint8_t DSPR[]={"00"};
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// DS18b20
//-------------------------------------------------------------------------------------------------
float DS18B20_Get_Temp(void);
uint8_t DS18B20_Init(void);
//-------------------------------------------------------------------------------------------------
#define HIGH 1
#define LOW 0
//-------------------------------------------------------------------------------------------------
#define DS18B20_CLK RCC_APB2Periph_GPIOC
#define DS18B20_PIN GPIO_Pin_13
#define DS18B20_PORT GPIOC

//带参宏,可以像内联函数一样使用,输出高电平或低电平
#define DS18B20_DATA_OUT(a) if (a) \
GPIO_SetBits(GPIOC,GPIO_Pin_13);\
else \
GPIO_ResetBits(GPIOC,GPIO_Pin_13)
//读取引脚的电平
#define DS18B20_DATA_IN() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)

uint8_t DSPWD[]={"00"};
uint8_t str[2]={0};
uint8_t temp;
//-------------------------------------------------------------------------------------------------
typedef struct
{
uint8_t humi_int; //湿度的整数部分
uint8_t humi_deci; //湿度的小数部分
uint8_t temp_int; //温度的整数部分
uint8_t temp_deci; //温度的小数部分
uint8_t check_sum; //校验和

}DS18B20_Data_TypeDef;

//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
static u8 fac_us=0;//us延时倍乘数
static u16 fac_ms=0;//ms延时倍乘数
//-------------------------------------------------------------------------------------------------
volatile u32 time = 0;
//-------------------------------------------------------------------------------------------------
unsigned char sz[5]={0x00,0x01,0x02,0x03,0x04};
//-------------------------------------------------------------------------------------------------
void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);
void KEY_Init(void);
//void Delay_us(__IO u32 nTime);
void delay_init(void);
//-------------------------------------------------------------------------------------------------
// 系统定时器初始化
//-------------------------------------------------------------------------------------------------
void delay_init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数
}
//-------------------------------------------------------------------------------------------------
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//--------------------------------------------------------------------
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
//--------------------------------------------------------------------
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//-------------------------------------------------------------------------------------------------
// 中断优先级配置
//-------------------------------------------------------------------------------------------------
void NVIC_Configuration1(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位

抢占优先级,2位响应优先级
}
//-------------------------------------------------------------------------------------------------
// 外部中断初始化函数
//-------------------------------------------------------------------------------------------------
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //外部中断,需要使能AFIO时钟
KEY_Init(); //初始化按键对应io模式

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5); //GPIOC.5 中断线以及中断初始化配置

EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15); //GPIOA.15 中断线以及中断初始化配置

EXTI_InitStructure.EXTI_Line=EXTI_Line15;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); //GPIOA.0 中断线以及中断初始化配置

EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,
NVIC_

InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
}
//-----------------------------------------------------------------
// 按键中断函数
//-----------------------------------------------------------------
void EXTI0_IRQHandler(void)
{
delay_ms(10);
if(WK_UP==1)
{
LED0=!LED0;
LED1=!LED1;

Clr_Scr();
A=1;
Clr_Scr();
//=================================================================
//printf("测试");
//printf("\r\n 现在温度 %.1f 度\r\n",DS18B20_Get_Temp());
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0线路挂起位
}
//-----------------------------------------------------------------
void EXTI9_5_IRQHandler(void)
{
delay_ms(10);
if(KEY0==0)
{
LED0=!LED0;
A=0;
//printf("稍等");
//adcx=Get_Adc_Average(ADC_Channel_1,10);
//temp =(float) adcx/4096*3.3;
//printf("\r\n The current AD value = 0x%04X \r\n",adcx);
//printf("\r\n The current AD value = %f V \r\n",temp);
}
EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE5上的中断标志位
}
//-----------------------------------------------------------------
void EXTI15_10_IRQHandler(void)
{
delay_ms(10);
if(KEY1==0)
{
LED1=!LED1;
A=2;
//printf("硕硕");
// ds1302_data(read);
//printf("20%d%d年%d%d月%d%d日%d%d:%d%d:%d%d 星期%d\r\n",time_ds1302[6],g[6],time_ds1302[4],g[4],time_ds1302[3],g[3],
//time_ds1302[2],g[2],time_ds1302[1],g[1],time_ds1302[0],g[0],g[5]);
}
EXTI_ClearITPendingBit(EXTI_Line15); //清除LINE15线路挂起位
}
//=================================================================================================

//-------------------------------------------------------------------------------------------------
// LED GPIO 初始化
//-------------------------------------------------------------------------------------------------
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_2|GPIO_Pin_3; //LED0-->PA.8 端口配置

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高
}
//-------------------------------------------------------------------------------------------------
// GPIO 按键初始化
//----------------

---------------------------------------------------------------------------------
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PA15
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA15

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PC5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC5

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0
}
//-------------------------------------------------------------------------------------------------
// 串口配置
//-------------------------------------------------------------------------------------------------
void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

USART_https://www.360docs.net/doc/4a61524.html,ART_BaudRate = 9600;
USART_https://www.360docs.net/doc/4a61524.html,ART_WordLength = USART_WordLength_8b;
USART_https://www.360docs.net/doc/4a61524.html,ART_StopBits = USART_StopBits_1;
USART_https://www.360docs.net/doc/4a61524.html,ART_Parity = USART_Parity_No ;
USART_https://www.360docs.net/doc/4a61524.html,ART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_https://www.360docs.net/doc/4a61524.html,ART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

USART_Cmd(USART1, ENABLE);
}
//--------------------------------------------------------------------
// 配置USART1接收中断
//--------------------------------------------------------------------
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// 重定向c库函数printf到USART1
//------------------------------

--------------------------------------
int fputc(int ch, FILE *f)
{
//发送一个字节数据到USART1
USART_SendData(USART1, (uint8_t) ch);
//等待发送完毕
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
return (ch);
}
// 重定向c库函数scanf到USART1
int fgetc(FILE *f)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(USART1);
}
//--------------------------------------------------------------------
// 串口3配置
//--------------------------------------------------------------------
void USART3_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
//GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);

USART_https://www.360docs.net/doc/4a61524.html,ART_BaudRate = 9600;
USART_https://www.360docs.net/doc/4a61524.html,ART_WordLength = USART_WordLength_8b;
USART_https://www.360docs.net/doc/4a61524.html,ART_StopBits = USART_StopBits_1;
USART_https://www.360docs.net/doc/4a61524.html,ART_Parity = USART_Parity_No ;
USART_https://www.360docs.net/doc/4a61524.html,ART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_https://www.360docs.net/doc/4a61524.html,ART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);

USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

USART_Cmd(USART3, ENABLE);


NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

//=====================================================================================================================================================================
// DS1302
//=====================================================================================================================================================================
void DS1302_GPIO(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

GPIO_InitStruct.GPIO_Pin = ds1302clk|ds1302rst; //clk、rst配置为输出
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin = ds1302dat;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; //IO配置为双向
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
//--------------------------------------------------------------------------

-----------------------

//-------------------------------------------------------------------------------------------------
void write_1302byte(uint8_t dat)
{
uint8_t i = 0;
GPIO_ResetBits(GPIOB,ds1302clk);
delay_us(2);//延时大约2us
for(i = 0;i < 8;i ++)
{
GPIO_ResetBits(GPIOB,ds1302clk); //ds1302clk=0;
if(dat&0x01)
GPIO_SetBits(GPIOB,ds1302dat);
else GPIO_ResetBits(GPIOB,ds1302dat);
delay_us(2);
GPIO_SetBits(GPIOB,ds1302clk);
dat >>= 1;
delay_us(1);
}
}
//-----------------------------------------------
uint8_t read_1302(uint8_t add)
{
uint8_t i=0;
uint8_t Return_dat=0x00;
GPIO_ResetBits(GPIOB,ds1302rst);
GPIO_ResetBits(GPIOB,ds1302clk);
delay_us(3);
GPIO_SetBits(GPIOB,ds1302rst);
delay_us(3);
write_1302byte(add);
for(i=0;i<8;i++)
{
GPIO_SetBits(GPIOB,ds1302clk);
Return_dat >>= 1;
GPIO_ResetBits(GPIOB,ds1302clk);
if(GPIO_ReadInputDataBit(GPIOB,ds1302dat)==1) //数据线此时为高电平
{
Return_dat = Return_dat|0x80;}
}
delay_us(1);
GPIO_ResetBits(GPIOB,ds1302rst); //ds1302rst=0;释放总线
return Return_dat;
}
//-----------------------------------------------
void write_1302(uint8_t add,uint8_t dat) //向指定寄存器写入一个字节的数据
{
GPIO_ResetBits(GPIOB,ds1302rst);
GPIO_ResetBits(GPIOB,ds1302clk); //ds1302rst=0;
//ds1302clk=0;
delay_us(1);
GPIO_SetBits(GPIOB,ds1302rst); //ds1302rst=1;
delay_us(2);
write_1302byte(add);
write_1302byte(dat);
GPIO_ResetBits(GPIOB,ds1302rst);
GPIO_ResetBits(GPIOB,ds1302clk); //ds1302clk=0;
//ds1302rst=0;
delay_us(1);
}
//-----------------------------------------------
void ds1302_init(uint8_t*write,uint8_t*time) //初始化1302
{
uint8_t i=0,j=0;
write_1302(0x8e,0x00);
for(i=0;i<7;i++)
{
j=time_ds1302[i]%10;
time_ds1302[i]=(time_ds1302[i]/10)*16+j;
}
for(i=0;i<7;i++)
{
write_1302(write[i],time_ds1302[i]);
}
write_1302(0x8e,0x80);
}
//-----------------------------------------------
void ds1302_data(uint8_t *read)
{
//中断按键按下显示时间,所以定义为全局变量
//uint8_t i=0,g[7],time_ds1302[7];
//static uint8_t s = 1;

for(i=0;i<7;i++)
{
time_ds1302[i]=read_1302(read[i]);
}

//===============================================
/*for(i=0;i<7;i++)
{
g[i]=time_ds1302[i]%16; time_ds1302[i]=time_ds1302[i]/16;
}*/
//此时已转换成10进制数,g[i]里面存放的是秒分时日月周年的各个位数据
//而此时的time[i]存放的是十位数据
//if(s != (time[0]+g[0]))
//printf("20%d%d年%d%d月%d%d日%d%d:%d%d:%d%d 星期%d\r\n",time_ds1302[6],g[6],time_ds1302[4],g[4],time_ds1302[3],g[3],
//time_ds1302[2],g[2],time_ds1302[1],g[1],time_ds1302[0],g[0],g[5]);
//s = time[0]+g[0];
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------

// DS18B20温度传感器
//-------------------------------------------------------------------------------------------------
void DS18B20_GPIO_Config(void)
{

GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypeDef类型的结构体
RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE); //开启DS18B20_PORT的外设时钟
GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式为通用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速率为50MHz
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORT
GPIO_SetBits(DS18B20_PORT, DS18B20_PIN);
}
//-------------------------------------------------------------------------------------------------
void DS18B20_Mode_IPU(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置引脚模式为浮空输入模式
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORT
}
//-------------------------------------------------------------------------------------------------
void DS18B20_Mode_Out_PP(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式为通用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置引脚速率为50MHz
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORT
}
//-------------------------------------------------------------------------------------------------
void DS18B20_Rst(void)
{
DS18B20_Mode_Out_PP(); //主机设置为推挽输出
DS18B20_DATA_OUT(LOW);
delay_us(750); // 主机至少产生480us的低电平复位信号
DS18B20_DATA_OUT(HIGH); //主机在产生复位信号后,需将总线拉高
delay_us(15); //从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
}
//-------------------------------------------------------------------------------------------------
//检测从机给主机返回的存在脉冲
//0:成功
//1:失败
//-------------------------------------------------------------------------------------------------
uint8_t DS18B20_Presence(void)
{
uint8_t pulse_time = 0;
DS18B20_Mode_IPU(); //主机设置为上拉输入
//等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
//如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
while( DS18B20_DATA_IN() && pulse_time<100 )
{
pulse_tim

e++;
delay_us(1); //经过100us后,存在脉冲都还没有到来
}
if( pulse_time >=100 )
return 1;
else
pulse_time = 0;
while( !DS18B20_DATA_IN() && pulse_time<240 ) //存在脉冲到来,且存在的时间不能超过240us
{
pulse_time++;
delay_us(1);
}
if( pulse_time >=240 )
return 1;
else
return 0;
}
//从DS18B20读取一个bit
uint8_t DS18B20_Read_Bit(void)
{
uint8_t dat; //读0和读1的时间至少要大于60us
DS18B20_Mode_Out_PP();
DS18B20_DATA_OUT(LOW); //读时间的起始:必须由主机产生 >1us <15us 的低电平信号
delay_us(10);
DS18B20_Mode_IPU(); //设置成输入,释放总线,由外部上拉电阻将总线拉高
//Delay_us(2);
if( DS18B20_DATA_IN() == SET )
dat = 1;
else
dat = 0;
delay_us(45); //这个延时参数请参考时序图
return dat;
}
//从DS18B20读一个字节,低位先行
uint8_t DS18B20_Read_Byte(void)
{
uint8_t i, j, dat = 0;

for(i=0; i<8; i++)
{
j = DS18B20_Read_Bit();
dat = (dat) | (j<}
return dat;
}
//写一个字节到DS18B20,低位先行
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t i, testb;
DS18B20_Mode_Out_PP();

for( i=0; i<8; i++ )
{
testb = dat&0x01;
dat = dat>>1;
//写0和写1的时间至少要大于60us
if (testb)
{
DS18B20_DATA_OUT(LOW);
//1us < 这个延时 < 15us
delay_us(8);
DS18B20_DATA_OUT(HIGH);
delay_us(58);
}
else
{
DS18B20_DATA_OUT(LOW);
//60us < Tx 0 < 120us
delay_us(70);

DS18B20_DATA_OUT(HIGH);
//1us < Trec(恢复时间) < 无穷大
delay_us(2);
}
}
}
//-------------------------------------------------------------------------------------------------
void DS18B20_Start(void)
{
DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); // 跳过 ROM
DS18B20_Write_Byte(0X44); // 开始转换
}
//-------------------------------------------------------------------------------------------------
uint8_t DS18B20_Init(void)
{
DS18B20_GPIO_Config();
DS18B20_Rst();

return DS18B20_Presence();
}
//温度 = 符号位 + 整数 + 小数*0.0625
float DS18B20_Get_Temp(void)
{
uint8_t tpmsb, tplsb;
short s_tem;
float f_tem;

DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); // 跳过 ROM
DS18B20_Write_Byte(0X44); // 开始转换

DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); // 跳过 ROM
DS18B20_Write_Byte(0XBE); // 读温度值

tplsb = DS18B20_Read_Byte();
tpmsb = DS18B20_Read_Byte();

s_tem = tpmsb<<8;
s_tem = s_tem | tplsb;

if( s_tem < 0 ) // 负温度
f_tem = (~s_tem+1) * 0.0625;
else
f_tem = s_tem * 0.0625;

return f_tem;
}
//=================================================================================
void Show_Temperature(void)
{

temp=DS18B20_Get_Temp();
str[0]=temp/10;
str[1]=temp%10;

DSPWD[0]=str[0]+0x30;
DSPWD[1]=str[1]+0x30;
}
//-------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
// LCD12864
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
void Lcds_Config(void)
{
// SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/*PC4-A0*/
// GPIO_SetBits(GPIOC, GPIO_Pin_12);//预置为高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

}
//===========================================================================
void Delaynms(u16 di)
{
u16 da,db;
for(da=0;dafor(db=0;db<10;db++);
}
//===========================================================================
void Delay_Lcd(u16 us) //delay time
{
while(us--);
}
//===========================================================================
void Send_Byte(u8 bbyte)
{
u8 i,t;
for(i=0;i<8;i++)
{
if((bbyte)&0x80)
SID_H; //取出最高位
else
SID_L;
SCLK_H;
t = 0x10;
while(t--); //延时 lcd读取数据
SCLK_L;
bbyte <<= 1; //左移
}
}
//===========================================================================
void Write_Char(u8 start, u8 ddata)
{
u8 start_data,Hdata,Ldata;
if(start==0)
start_data=0xf8; //写指令
else
start_data=0xfa; //写数据

Hdata=ddata&0xf0; //取高四位
Ldata=(ddata<<4)&0xf0; //取低四位
Send_Byte(start_data); //发送起始信号
Delaynms(10); //延时是必须的
Send_Byte(Hdata); //发送高四位
Delaynms(5); //延时是必须的
Send_Byte(Ldata); //发送低四位
Delaynms(5); //延时是必须的
}
//===========================================================================
void Lcd_Init(void)
{
Delaynms(50); //启动等待,等LCM讲入工作状态
CS_H;
Write_Char(0,0x30); //8 位介面,基本指令集
Write_Char(0,0x0c); //显示打开,光标关,反白关
Write_Char(0,0x01); //清屏,将DDRAM的地址计数器归零
}
//===========================================================================
void Clr_Scr(void)//清屏函数
{
Write_Char(0,0x01);
}
//===========================================================================
void LCD_Set_XY( u8 X, u8 Y )
{
u8 address;
switch(X)
{
case 0:
address = 0x80 + Y;
break;
case 1:
address

= 0x80 + Y;
break;
case 2:
address = 0x90 + Y;
break;
case 3:
address = 0x88 + Y;
break;
case 4:
address = 0x98 + Y;
break;
default:
address = 0x80 + Y;
break;
}
Write_Char(0, address);
}
//===========================================================================
void LCD_Write_String(u8 X,u8 Y,uc8 *s)
{
LCD_Set_XY( X, Y );

while (*s)
{
Write_Char( 1, *s );
s ++;
Delaynms(1);
}
}
//===========================================================================
void LCD_Write_Number(u8 s)// 数字显示函数
{
Write_Char(1,num_lcd[s]);
Delaynms(1);
}
//===========================================================================
void Display_Img(u8 const *img)
{
u8 i,j;
for(j=0;j<32;j++)
{
for(i=0;i<8;i++)
{
Write_Char(comm,0x34);
Delaynms(10);
Write_Char(comm,y+j);
Delaynms(10);
Write_Char(comm,x1+i);
Delaynms(10);
Write_Char(comm,0x30);
Delaynms(10);
Write_Char(dat1,img[j*16+i*2]);
Delaynms(10);
Write_Char(dat1,img[j*16+i*2+1]);
Delaynms(10);
}
}
for(j=32;j<64;j++)
{
for(i=0;i<8;i++)
{
Write_Char(comm,0x34);
Delaynms(10);
Write_Char(comm,y+j-32);
Delaynms(10);
Write_Char(comm,x2+i);
Delaynms(10);
Write_Char(comm,0x30);
Delaynms(10);
Write_Char(dat1,img[j*16+i*2]);
Delaynms(10);
Write_Char(dat1,img[j*16+i*2+1]);
Delaynms(10);
}
}
Delaynms(10);
Write_Char(comm,0x36);
}
//===========================================================================
void send_str(uint8_t n,uint8_t *cc)
{
uint32_t i;
Write_Char(0,0x30);
for(i=0;(iWrite_Char(dat1,*(cc+i));
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//=================================================================================================
// 12864主屏
//=================================================================================================
void display_main(void)
{
A=0;
Clr_Scr(); //清屏
delay_ms(100);
LCD_Write_String(1,0," 时钟 ");
LCD_Write_String(2,0,"日期: . . ");
LCD_Write_String(3,0,"时间: : : ");
LCD_Write_String(4,0,"温度: 摄氏度");
}
//======================================================
void display_temp_time(void)
{
Show_Temperature();
ds1302_data(read);
//------------------------------------------------------
LCD_Set_XY(4,3);
send_str(16,DSPWD);
//======================================================
DSPR[1]=(time_ds1302[3]&0x0f)+0X30;
DSPR[0]=((time_ds1302[3]&0xf0)>>4)+0X30;
LCD_Set_XY(2,7);
send_str(16,DSPR);

DSPY[1]=(time_ds1302[4]&0x0f)+0X30;
DSPY[0]

=((time_ds1302[4]&0xf0)>>4)+0X30;
LCD_Set_XY(2,5);
send_str(16,DSPY);

DSPN[1]=(time_ds1302[6]&0x0f)+0X30;
DSPN[0]=((time_ds1302[6]&0xf0)>>4)+0X30;
LCD_Set_XY(2,3);
send_str(16,DSPN);
//-------------------------------------------
// 秒分时
//-------------------------------------------

DSPS[1]=(time_ds1302[0]&0x0f)+0X30;
DSPS[0]=((time_ds1302[0]&0xf0)>>4)+0X30;
LCD_Set_XY(3,7);
send_str(2,DSPS) ;

DSPM[1]=(time_ds1302[1]&0x0f)+0X30;
DSPM[0]=((time_ds1302[1]&0xf0)>>4)+0X30;
LCD_Set_XY(3,5);
send_str(2,DSPM) ;

DSPH[1]=(time_ds1302[2]&0x0f)+0X30;
DSPH[0]=((time_ds1302[2]&0xf0)>>4)+0X30;
LCD_Set_XY(3,3);
send_str(2,DSPH) ;
}
//======================================================
void display_1(void)
{
Clr_Scr();
while(A==1)
{
delay_ms(100);
LCD_Write_String(1,0,"八百标兵奔北坡");
LCD_Write_String(2,0,"炮兵并排北边跑");
LCD_Write_String(3,0,"炮兵怕把标兵碰");
LCD_Write_String(4,0,"标兵怕碰炮兵炮");
}
if(A==0)
{
Clr_Scr();
display_main();
}
}
//======================================================
void display_2(void)
{
Clr_Scr();
while(A==2)
{
delay_ms(100);
LCD_Write_String(1,0," 设置时间 ");
LCD_Write_String(2,0," 读取AD值 ");
LCD_Write_String(3,0," 控制发送 ");
LCD_Write_String(4,0," 设置参数 ");
}
if(A==0)
{
Clr_Scr();
display_main();
}
}
//-------------------------------------------------------------------------------------------------
// 主函数
//-------------------------------------------------------------------------------------------------
int main(void)
{
//------------------------------------------------------
//USART1_Config();
//NVIC_Configuration();
//USART3_Config();
//------------------------------------------------------
LED_Init(); //初始化与LED连接的硬件接口
NVIC_Configuration1();
EXTIX_Init(); //外部中断初始化
delay_init();
DS1302_GPIO();

//------------------------------------------------------
Lcds_Config();
Lcd_Init();
delay_ms(100);
Clr_Scr(); //清屏
delay_ms(100);
Clr_Scr(); //清屏
delay_ms(100);
//======================================================
display_main(); //显示框架

while(1)
{
//======================================================
display_temp_time();
//======================================================
while(A==1)
{
display_1();
}
//======================================================
while(A==2)
{
display_2();
}
//======================================================
}
}
//-------------------------------------------------------











相关文档
最新文档