谁有ds1302 oled液晶显示时间的程序代码。谢谢了

谁有ds1302 oled液晶显示时间的程序代码。谢谢了,第1张

我给你一份,我之前写过的程序。

/*

* LCD1602 时钟

*

* author:

* date:2011.2.22

*/

#include "main.h"

#include "ds1302.h"

#include "LCD1602.h"

sbit delua = P2^6

sbit welua = P2^7

uint8 Time[7]={55,59,11,22,2,2,11}//秒分时日月周年10-08-15 11:59:55

uint8 T_tmp[7]

uint8 Num, T_n=0

void delay(uint16 n)

{

while (n--)

}

/*

* 初始化系统定时器

*/

void systimer_init(void)

{

TMOD &= 0x0F

TMOD |= 0x10

TH1 = 0xDC // 定时10ms

TL1 = 0x00

TR1 = 0

ET1 = 0

EA = 1

}

/*

* 判断键值

*/

/*

uint8 scan_key(void)

{

uint8 val=0

KeyOut1 = 0

KeyOut2 = 1

KeyOut3 = 1

KeyOut4 = 1

if(KeyIn4 == 0)

{

delay(KEY_DELAY)

if (KeyIn4 == 0)

{

val = K_ADD

}

}

while((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0))

KeyOut1 = 1

KeyOut2 = 0

KeyOut3 = 1

KeyOut4 = 1

if(KeyIn4 == 0)

{

delay(KEY_DELAY)

if(KeyIn4 == 0)

val = K_LEFT

}

while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0))

KeyOut1 = 1

KeyOut2 = 1

KeyOut3 = 0

KeyOut4 = 1

if (KeyIn4 == 0)

{

delay(KEY_DELAY)

if (KeyIn4 == 0)

val = K_SUB

}

while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0))

KeyOut1 = 1

KeyOut2 = 1

KeyOut3 = 1

KeyOut4 = 0

if (KeyIn2 == 0)

{

delay(KEY_DELAY)

if (KeyIn2 == 0)

val = K_SET

}

if (KeyIn3 == 0)

{

delay(KEY_DELAY)

if (KeyIn3 == 0)

val = K_ENTER

}

if (KeyIn4 == 0)

{

delay(KEY_DELAY)

if (KeyIn4 == 0)

val = K_RIGHT

}

while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0))

return val

}

*/

/*

* 启动clock数字闪烁

*/

void start_flash(void)

{

T_n = 0

switch (Num)

{

case 0: w_data(6, Time[0])break

case 1: w_data(3, Time[1])break

case 2: w_data(0, Time[2])break

default: break

}

TH1 = 0xDC // 定时10ms

TL1 = 0x00

TR1 = 1

ET1 = 1

}

/*

* 停止clock数字闪烁

*/

void stop_flash(void)

{

ET1 = 0

TR1 = 0

switch (Num)

{

case 0: w_data(6, Time[0])break

case 1: w_data(3, Time[1])break

case 2: w_data(0, Time[2])break

default: break

}

}

/*

* 更新LCD时间

*/

void refresh_clock(void)

{

if (Time[0] != T_tmp[0]) // 更新秒

{

T_tmp[0] = Time[0]

w_data(6, Time[0])

}

if (Time[1] != T_tmp[1]) // 更新分

{

T_tmp[1] = Time[1]

w_data(3, Time[1])

}

if (Time[2] != T_tmp[2]) // 更新时

{

T_tmp[2] = Time[2]

w_data(0, Time[2])

}

}

/*

* 时钟设置

*/

void set_clock(void)

{

uint8 k_val, flag=0

Num = 0

while (1)

{

// k_val = scan_key()

if (k_val == 0)

{

if (flag == 0)

{

start_flash()

flag = 1

}

continue

}

flag = 0

stop_flash()

if (k_val == K_ENTER)

{

set_time(Time)

break

}

switch (k_val)

{

case K_ADD:

if (Num == 2)

{

if (Time[Num] >= 23)

Time[Num] = 0

else

Time[Num]++

}

else

{

if (Time[Num] >= 59)

Time[Num] = 0

else

Time[Num]++

}

break

case K_SUB:

if (Num == 2)

{

if (Time[Num] == 0)

Time[Num] = 23

else

Time[Num]--

}

else

{

if (Time[Num] == 0)

Time[Num] = 59

else

Time[Num]--

}

break

case K_LEFT:

if (Num >= 2)

Num = 0

else

Num++

break

case K_RIGHT:

if (Num == 0)

Num = 2

else

Num--

break

default: break

}

refresh_clock()

}

}

main()

{

uint8 k_val

delua = 0

welua = 0

systimer_init()

LCD1602_init()

set_time(Time)//初始时间设定

w_string(0, " : : ")

w_data(0, Time[2])// 时

w_data(3, Time[1])// 分

w_data(6, Time[0])// 秒

while (1)

{

read_time(Time)

refresh_clock()

// k_val = scan_key()

if (k_val == K_SET)

set_clock()

}

}

void time1_isr() interrupt 3

{

ET1 = 0

TH1 = 0xDC // 定时10ms

TL1 = 0x00

T_n++

if (T_n == 50) // 0.5s

{

switch (Num)

{

case 0: clear_data(6)break

case 1: clear_data(3)break

case 2: clear_data(0)break

default: break

}

}

else if (T_n >= 100) // 1s

{

T_n = 0

switch (Num)

{

case 0: w_data(6, Time[0])break

case 1: w_data(3, Time[1])break

case 2: w_data(0, Time[2])break

default: break

}

}

ET1 = 1

}

/*

* LCD1602显示

*

*/

#include "main.h"

#include "LCD1602.h"

/**

* 等待繁忙标志

*/

/*

void wait(void)

{

P0 = 0xFF

do

{

RS = 0

RW = 1

EN = 0

EN = 1

}while (BUSY == 1)

EN = 0

}

*/

void Delay_1ms(unsigned int Time)

{

unsigned int x, y

for(x = Timex >0x--)

for(y = 120y >0y--)

}

/**

* 写数据

*/

void w_dat(uint8 dat)

{

RS = 1

P0 = dat

Delay_1ms(5)

EN = 1

Delay_1ms(5)

EN = 0

}

/**

* 写命令

*/

void w_cmd(uint8 cmd)

{

RS = 0

P0 = cmd

Delay_1ms(5)

EN = 1

Delay_1ms(5)

EN = 0

}

/**

* 发送字符串到LCD

*/

void w_string(uint8 addr_start, uint8 *p)

{

w_cmd(addr_start | 0x80)

while (*p != '\0')

{

w_dat(*p++)

}

}

/**

* 发送数字到LCD(00~99)

*/

void w_data(uint8 addr_start, uint8 dat)

{

w_cmd(addr_start | 0x80)

w_dat(dat%100/10 + '0')

w_dat(dat%10 + '0')

}

/**

* 显示两位空白

*/

void clear_data(uint8 addr_start)

{

w_cmd(addr_start | 0x80)

w_dat(' ')

w_dat(' ')

}

/**

* 初始化1602

*/

void LCD1602_init(void)

{

w_cmd(0x38) // 16*2显示,5*7点阵,8位数据接口

w_cmd(0x0C) // 显示器开、光标开、光标允许闪烁

w_cmd(0x06) // 文字不动,光标自动右移

w_cmd(0x01) // 清屏

}

/*

* DS1302 突发方式,连读,连写

*

*/

#include "main.h"

#include "ds1302.h"

/**

* 写一个字节

*/

void write_ds1302_byte(uint8 dat)

{

uint8 i

for (i=0i<8i++)

{

SDA = dat &0x01

SCK = 1

dat >>= 1

SCK = 0

}

}

/**

* 读一个字节

*/

uint8 read_ds1302_byte(void)

{

uint8 i, dat=0

for (i=0i<8i++)

{

dat >>= 1

if (SDA)

dat |= 0x80

SCK = 1

SCK = 0

}

return dat

}

void reset_ds1302(void)

{

RST = 0

SCK = 0

RST = 1

}

/**

* 清除写保护

*/

void clear_ds1302_WP(void)

{

reset_ds1302()

RST = 1

write_ds1302_byte(0x8E)

write_ds1302_byte(0)

SDA = 0

RST = 0

}

/**

* 设置写保护

*/

void set_ds1302_WP(void)

{

reset_ds1302()

RST = 1

write_ds1302_byte(0x8E)

write_ds1302_byte(0x80)

SDA = 0

RST = 0

}

/**

* 设定时钟数据

*/

void set_time(uint8 *timedata)

{

uint8 i, tmp

for (i=0i<7i++) // 转化为BCD格式

{

tmp = timedata[i] / 10

timedata[i] = timedata[i] % 10

timedata[i] = timedata[i] + tmp*16

}

clear_ds1302_WP()//清除写保护

reset_ds1302() //初始化端

RST = 1//使能拉高

write_ds1302_byte(DS1302_W_ADDR) //时钟突发寄存器写寄存器

for (i=0i<7i++)

{

write_ds1302_byte(timedata[i])

delay(10)

}

write_ds1302_byte(0)

SDA = 0

RST = 0

set_ds1302_WP() //设置写保护

}

/**

* 读时钟数据

*/

void read_time(uint8 *timedata)

{

uint8 i, tmp

clear_ds1302_WP()

reset_ds1302()

RST = 1

write_ds1302_byte(DS1302_R_ADDR)

for (i=0i<7i++)

{

timedata[i] = read_ds1302_byte()

delay(10)

}

SDA = 0

RST = 0

set_ds1302_WP()

for (i=0i<7i++) // 转化为正常格式

{

tmp = timedata[i] / 16

timedata[i] = timedata[i] % 16

timedata[i] = timedata[i] + tmp*10

}

}

#define LCM_RW P2_0 //定义引脚

#define LCM_RS P2_1

#define LCM_E P2_2

#define LCM_Data P1

#define Busy0x80 //用于检测LCM状态字中的Busy标识

#i nclude <at89x51.h>

void WriteDataLCM(unsigned char WDLCM)

void WriteCommandLCM(unsigned char WCLCM,BuysC)

unsigned char ReadDataLCM(void)

unsigned char ReadStatusLCM(void)

void LCMInit(void)

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)

void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)

void Delay5Ms(void)

void Delay400Ms(void)

unsigned char code uctech[] = {"uctech"}

unsigned char code net[] = {"uctech.icpcn.com"}

void main(void)

{

Delay400Ms()//启动等待,等LCM讲入工作状态

LCMInit()//LCM初始化

Delay5Ms()//延时片刻(可不要)

DisplayListChar(0, 5, uctech)

DisplayListChar(0, 0, net)

ReadDataLCM()//测试用句无意义

while(1)

}

//写数据

void WriteDataLCM(unsigned char WDLCM)

{

ReadStatusLCM()//检测忙

LCM_Data = WDLCM

LCM_RS = 1

LCM_RW = 0

LCM_E = 0//若晶振速度太高可以在这后加小的延时

LCM_E = 0//延时

LCM_E = 1

}

//写指令

void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测

{

if (BuysC) ReadStatusLCM()//根据需要检测忙

LCM_Data = WCLCM

LCM_RS = 0

LCM_RW = 0

LCM_E = 0

LCM_E = 0

LCM_E = 1

}

//读数据

unsigned char ReadDataLCM(void)

{

LCM_RS = 1

LCM_RW = 1

LCM_E = 0

LCM_E = 0

LCM_E = 1

return(LCM_Data)

}

//读状态

unsigned char ReadStatusLCM(void)

{

LCM_Data = 0xFF

LCM_RS = 0

LCM_RW = 1

LCM_E = 0

LCM_E = 0

LCM_E = 1

while (LCM_Data &Busy)//检测忙信号

return(LCM_Data)

}

void LCMInit(void) //LCM初始化

{

LCM_Data = 0

WriteCommandLCM(0x38,0)//三次显示模式设置,不检测忙信号

Delay5Ms()

WriteCommandLCM(0x38,0)

Delay5Ms()

WriteCommandLCM(0x38,0)

Delay5Ms()

WriteCommandLCM(0x38,1)//显示模式设置,开始要求每次检测忙信号

WriteCommandLCM(0x08,1)//关闭显示

WriteCommandLCM(0x01,1)//显示清屏

WriteCommandLCM(0x06,1)// 显示光标移动设置

WriteCommandLCM(0x0C,1)// 显示开及光标设置

}

//按指定位置显示一个字符

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)

{

Y &= 0x1

X &= 0xF//限制X不能大于15,Y不能大于1

if (Y) X |= 0x40//当要显示第二行时地址码+0x40

X |= 0x80// 算出指令码

WriteCommandLCM(X, 0)//这里不检测忙信号,发送地址码

WriteDataLCM(DData)

}

//按指定位置显示一串字符

void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)

{

unsigned char ListLength

ListLength = 0

Y &= 0x1

X &= 0xF//限制X不能大于15,Y不能大于1

while (DData[ListLength]>0x20) //若到达字串尾则退出

{

if (X <= 0xF) //X坐标应小于0xF

{

DisplayOneChar(X, Y, DData[ListLength])//显示单个字符

ListLength++

X++

}

}

}

//5ms延时

void Delay5Ms(void)

{

unsigned int TempCyc = 5552

while(TempCyc--)

}

//400ms延时

void Delay400Ms(void)

{

unsigned char TempCycA = 5

unsigned int TempCycB

while(TempCycA--)

{

TempCycB=7269

while(TempCycB--)

}

取模是高位在前的形式 temp&0x80 用于判断当前temp 最高位是0还是1 是1就点亮 0就清除

正常显示 点亮OLED是蓝色点 清除是黑屏 反白显示就是反过来 点亮的部分清黑屏 不亮的部分显示蓝色


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11747126.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存