標題:
ds1302驅(qū)動程序+lcd12864串行顯示,使用結(jié)構(gòu)體寫,可讀性更強
[打印本頁]
作者:
老馬工作室
時間:
2019-5-13 19:13
標題:
ds1302驅(qū)動程序+lcd12864串行顯示,使用結(jié)構(gòu)體寫,可讀性更強
ds1302.c
#include "ds1302.h"
// 定義RTC初始化結(jié)構(gòu)體,決定了初始化時間
RTC_TIME rtc_time = {
25, // 秒
35, // 分
02, // 時
25, // 日
4, // 月
4, // 星期
19 // 年
};
/*******************************************************************************
* 函 數(shù) 名 : bcd_to_hex
* 函數(shù)功能 : 從時鐘芯片中讀出的時間數(shù)據(jù),需轉(zhuǎn)換為十進制數(shù)。
* 輸 入 : val:需要轉(zhuǎn)換的值
* 輸 出 : 無
*******************************************************************************/
static uint8_t bcd_to_hex(uint8_t val)
{
uint8_t temp;
temp = val & 0x0f;
val >>= 4;
val &= 0x0f;
val *= 10;
temp += val;
return temp;
}
/*******************************************************************************
* 函 數(shù) 名 : hex_to_bcd
* 函數(shù)功能 : 往時鐘芯片寫入數(shù)據(jù)時,需將待寫的十進制數(shù)轉(zhuǎn)換為8421碼。
* 輸 入 : val:需要轉(zhuǎn)換的值
* 輸 出 : 無
*******************************************************************************/
static uint8_t hex_to_bcd(uint8_t val)
{
uint8_t i,j,k;
i = val / 10;
j = val % 10;
k= j + (i << 4);
return k;
}
/*******************************************************************************
* 函 數(shù) 名 : DS1302_Write
* 函數(shù)功能 : 向DS1302命令(地址+數(shù)據(jù))
* 輸 入 : addr,dat
* 輸 出 : 無
*******************************************************************************/
static void DS1302_Write(uint8_t addr, uint8_t dat)
{
uint8_t n;
RST = 0;
_nop_();
SCLK = 0;//先將SCLK置低電平。
_nop_();
RST = 1; //然后將RST(CE)置高電平。
_nop_();
for (n=0; n<8; n++)//開始傳送八位地址命令
{
DSIO = addr & 0x01;//數(shù)據(jù)從低位開始傳送
addr >>= 1;
SCLK = 1;//數(shù)據(jù)在上升沿時,DS1302讀取數(shù)據(jù)
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++)//寫入8位數(shù)據(jù)
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;//數(shù)據(jù)在上升沿時,DS1302讀取數(shù)據(jù)
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;//傳送數(shù)據(jù)結(jié)束
_nop_();
}
/*******************************************************************************
* 函 數(shù) 名 : DS1302_Read
* 函數(shù)功能 : 讀取一個地址的數(shù)據(jù)
* 輸 入 : addr
* 輸 出 : dat
*******************************************************************************/
static uint8_t DS1302_Read(uint8_t addr)
{
uint8_t n;
uint8_t dat;
uint8_t dat1;
RST = 0;
_nop_();
/* 先將SCLK置低電平 */
SCLK = 0;
_nop_();
/* 然后將RST(CE)置高電平 */
RST = 1;
_nop_();
/* 開始傳送八位地址命令 */
for(n=0; n<8; n++)
{
DSIO = addr & 0x01; /* 數(shù)據(jù)從低位開始傳送 */
addr >>= 1;
SCLK = 1; /* 數(shù)據(jù)在上升沿時,DS1302讀取數(shù)據(jù) */
_nop_();
SCLK = 0; /* DS1302下降沿時,放置數(shù)據(jù) */
_nop_();
}
_nop_();
/* 讀取8位數(shù)據(jù) */
for(n=0; n<8; n++)
{
dat1 = DSIO; /* 從最低位開始接收 */
dat = (dat>>1) | (dat1<<7);
SCLK = 1;
_nop_();
SCLK = 0; /* DS1302下降沿時,放置數(shù)據(jù) */
_nop_();
}
/* 以下為DS1302復位的穩(wěn)定時間,必須的 */
RST = 0;
_nop_();
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return dat;
}
/*******************************************************************************
* 函 數(shù) 名 : DS1302_ReadTime
* 函數(shù)功能 : 讀取時鐘信息
* 輸 入 : RTC_TIME類型的結(jié)構(gòu)體指針,RTC_TIME的成員有:
rtc_sec 秒
rtc_min 分鐘
rtc_hour 小時
rtc_date 日
rtc_month 月
rtc_day 星期
rtc_year 年
* 輸 出 : 無
*******************************************************************************/
void DS1302_ReadTime(RTC_TIME *rtc_time)
{
unsigned temp;
temp = DS1302_Read(SEC_ADDR | 0x01);
rtc_time->rtc_sec = bcd_to_hex(temp);
temp = DS1302_Read(MIN_ADDR | 0x01);
rtc_time->rtc_min = bcd_to_hex(temp);
temp = DS1302_Read(HR_ADDR | 0x01);
rtc_time->rtc_hour = bcd_to_hex(temp);
temp = DS1302_Read(DATE_ADDR | 0x01);
rtc_time->rtc_date = bcd_to_hex(temp);
temp = DS1302_Read(MON_ADDR | 0x01);
rtc_time->rtc_month = bcd_to_hex(temp);
temp = DS1302_Read(DAY_ADDR | 0x01);
rtc_time->rtc_day = bcd_to_hex(temp);
temp = DS1302_Read(YEAR_ADDR | 0x01);
rtc_time->rtc_year = bcd_to_hex(temp);
}
/*******************************************************************************
* 函 數(shù) 名 : DS1302_SetTime
* 函數(shù)功能 : 向DS1302寫入時間
* 輸 入 : RTC_TIME類型的結(jié)構(gòu)體指針,RTC_TIME的成員有:
rtc_sec 秒
rtc_min 分鐘
rtc_hour 小時
rtc_date 日
rtc_month 月
rtc_day 星期
rtc_year 年
* 輸 出 : 無
*******************************************************************************/
void DS1302_SetTime(RTC_TIME *rtc_time)
{
uint8_t temp;
DS1302_Write(0x8E,0X00); //禁止寫保護,就是關閉寫保護功能
temp = hex_to_bcd(rtc_time->rtc_sec);
DS1302_Write(SEC_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_min);
DS1302_Write(MIN_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_hour);
DS1302_Write(HR_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_date);
DS1302_Write(DATE_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_month);
DS1302_Write(MON_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_day);
DS1302_Write(DAY_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_year);
DS1302_Write(YEAR_ADDR, temp);
DS1302_Write(0x8E,0x80); //打開寫保護功能
}
/*******************************************************************************
* 函 數(shù) 名 : DS1302_Init
* 函數(shù)功能 : 初始化DS1302,初始化時間時由RTC初始化結(jié)構(gòu)體決定的
* 輸 入 : addr
* 輸 出 : dat
*******************************************************************************/
void DS1302_Init(void)
{
DS1302_SetTime(&rtc_time);
}
復制代碼
ds1302.h
#ifndef __DS1302_H_
#define __DS1302_H_
#include "config.h"
// DS1302的寄存器地址
#define SEC_ADDR 0x80 // 秒
#define MIN_ADDR 0x82 // 分
#define HR_ADDR 0x84 // 時
#define DATE_ADDR 0x86 // 日
#define MON_ADDR 0x88 // 月
#define DAY_ADDR 0x8a // 星期
#define YEAR_ADDR 0x8c // 年
//定義ds1302使用的IO口
sbit DSIO = P1^1;
sbit RST = P1^2;
sbit SCLK = P1^3;
typedef struct rtc_time{
uint8_t rtc_sec;
uint8_t rtc_min;
uint8_t rtc_hour;
uint8_t rtc_date;
uint8_t rtc_month;
uint8_t rtc_day;
uint8_t rtc_year;
}RTC_TIME;
extern RTC_TIME rtc_time; // 聲明RTC初始化結(jié)構(gòu)體,以便外部文件使用
void DS1302_SetTime(RTC_TIME *rtc_time); // 設置時間
void DS1302_ReadTime(RTC_TIME *rtc_time); // 讀取時間
void DS1302_Init(void); // 初始化DS1302
#endif
復制代碼
lcd12864.c
#include "lcd12864.h"
//sbit LCD_CS = P2^5; //片選信號 (cs可以直接接高電平)
sbit LCD_SID = P3^5; //數(shù)據(jù)信號
sbit LCD_SCLK = P3^6; //時鐘信號
//sbit LCD_RST = P2^2; //復位信號 (可以不接)
/********************************************************************
* 名稱 : LCD12864_Delay()
* 功能 : 延時,延時時間為 100us * t。這是通過軟件延時,有一定誤差。
* 輸入 : t
* 輸出 : 無
***********************************************************************/
static void LCD12864_Delay(unsigned int t)
{
unsigned int i,j;
for (i=0; i<t; i++)
for (j=0; j<10; j++);
}
/********************************************************************
* 名稱 : LCD12864_SendByte
* 功能 : 按照液晶的串口通信協(xié)議,發(fā)送數(shù)據(jù)
* 輸入 : zdata
* 輸出 : 無
***********************************************************************/
static void LCD12864_SendByte(unsigned char zdata)
{
unsigned int i;
for(i=0; i<8; i++)
{
if((zdata << i) & 0x80)
{
LCD_SID = 1;
}
else
{
LCD_SID = 0;
}
LCD_SCLK = 0;
LCD_SCLK = 1;
}
}
/********************************************************************
* 名稱 : LCD12864_Write_Com
* 功能 : 寫串口指令
* 輸入 : cmdcode:指令
* 輸出 : 無
***********************************************************************/
void LCD12864_Write_Com(unsigned char cmdcode)
{
// LCD_CS = 1;
LCD12864_SendByte(0xf8);
LCD12864_SendByte(cmdcode & 0xf0);
LCD12864_SendByte((cmdcode << 4) & 0xf0);
LCD12864_Delay(2);
}
/********************************************************************
* 名稱 : LCD12864_Write_Data
* 功能 : 寫串口指令
* 輸入 : cmdcode:數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
void LCD12864_Write_Data(unsigned char Dispdata)
{
// LCD_CS = 1;
LCD12864_SendByte(0xfa);
LCD12864_SendByte(Dispdata & 0xf0);
LCD12864_SendByte((Dispdata << 4) & 0xf0);
LCD12864_Delay(2);
}
/********************************************************************
* 名稱 : LCD12864_SetLocation
* 功能 : 設置顯示位置
* 輸入 : pos_x: (0~15)
pos_y: (0~3)
* 輸出 : 無
***********************************************************************/
static void LCD12864_SetLocation(uint8_t pos_x, uint8_t pos_y)
{
if (pos_y == 0x00)
{
pos_x += 0x80;
}
else if (pos_y == 0x01)
{
pos_x += 0x90;
}
else if (pos_y == 0x02)
{
pos_x += 0x88;
}
else
{
pos_x += 0x98;
}
LCD12864_Write_Com(pos_x);
}
/********************************************************************
* 名稱 : LCD12864_ShowStr
* 功能 : LCD12864顯示字符串
* 輸入 : pos_x: (0~15)
pos_y: (0~3)
str:字符串
* 輸出 : 無
***********************************************************************/
void LCD12864_ShowStr(uint8_t pos_x, uint8_t pos_y, char *str)
{
LCD12864_SetLocation(pos_x, pos_y); // 設置顯示位置
while (*str != '\0')
{
LCD12864_Write_Data(*str++);
}
}
/********************************************************************
* 名稱 : LCD12864_Init
* 功能 : 初始化函數(shù)
* 輸入 : cmdcode
* 輸出 : 無
***********************************************************************/
void LCD12864_Init(void)
{
// LCD_RST = 0;
LCD12864_Delay(100);
// LCD_RST = 1;
LCD12864_Delay(20000);
LCD12864_Write_Com(0x30);
LCD12864_Delay(50);
LCD12864_Write_Com(0x0c);
LCD12864_Delay(50);
LCD12864_Write_Com(0x01); // 清屏指令
LCD12864_Delay(50);
LCD12864_Write_Com(0x02);
LCD12864_Delay(50);
LCD12864_Write_Com(0x80);
LCD12864_Delay(50);
}
復制代碼
lcd12864.h
#ifndef _12864_H_
#define _12864_H_
#include <STC12C5A60S2.H>
#include "config.h"
void LCD12864_Write_Com(unsigned char cmdcode);
void LCD12864_Write_Data(unsigned char Dispdata);
void LCD12864_ShowStr(uint8_t pos_x, uint8_t pos_y, char *str);
void LCD12864_Init(void);
//void LCD12864_Clear(void);
#endif /* MSP430_C_X_12864_H_ */
復制代碼
config.h
#ifndef __CONFIG_H
#define __CONFIG_H
#include <STC12C5A60S2.H>
#include <intrins.h>
#include <string.h>
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
#define KEY_SET KEY5
#endif
復制代碼
main.c
<div>#include <STC12C5A60S2.H>
#include "lcd12864.h"
#include "ds1302.h"
void main(void)
{
LCD12864_Init(); // 初始化LCD12864
DS1302_Init(); // 初始化DS1302時鐘芯片
while (1)
{
DS1302_ReadTime(&rtc_time); // 讀取時間
LCD12864_ShowStr(0, 1, "日期:");
LCD12864_Write_Data('0' + rtc_time.rtc_year / 10);
LCD12864_Write_Data('0' + rtc_time.rtc_year % 10);
LCD12864_Write_Data('-');
LCD12864_Write_Data('0' + rtc_time.rtc_month / 10);
LCD12864_Write_Data('0' + rtc_time.rtc_month % 10);
LCD12864_Write_Data('-');
LCD12864_Write_Data('0' + rtc_time.rtc_date / 10);
LCD12864_Write_Data('0' + rtc_time.rtc_date % 10);
LCD12864_ShowStr(0, 2, "時間:");
LCD12864_Write_Data('0' + rtc_time.rtc_hour / 10);
LCD12864_Write_Data('0' + rtc_time.rtc_hour % 10);
LCD12864_Write_Data('-');
LCD12864_Write_Data('0' + rtc_time.rtc_min / 10);
LCD12864_Write_Data('0' + rtc_time.rtc_min % 10);
LCD12864_Write_Data('-');
LCD12864_Write_Data('0' + rtc_time.rtc_sec / 10);
LCD12864_Write_Data('0' + rtc_time.rtc_sec % 10);
}
}
復制代碼
作者:
280570255
時間:
2019-5-25 10:24
學習了
作者:
lichuanyi
時間:
2019-5-25 11:04
不錯,謝謝
作者:
wgh008
時間:
2020-1-23 00:33
好資料,謝謝分享,正在學習中
作者:
秋爽
時間:
2020-2-21 22:12
謝謝分享,學習中!
作者:
szzxl10
時間:
2020-2-22 11:03
<div>#include <STC12C5A60S2.H>
是什么意思?
作者:
老馬工作室
時間:
2020-11-23 13:27
szzxl10 發(fā)表于 2020-2-22 11:03
#include
是什么意思?
復制的時候沒注意,<div>應該是沒有的。
作者:
楊天想
時間:
2021-5-19 10:37
樓主能打包一下提供下載嗎
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1