定时器16位计时c语言,单片机实现具有掉电记忆功能的计时器

这文章来自互联网如有侵权请和管理员联系删除

项目描述:

用单片机实现0 ~ 99s的计时,将计时实时显示在LCD上,并用24C02实现掉电记忆。

仿真原理图如下:

bc917a3b3f15c3f67123344142ecadb8.png

C语言代码如下:/*------------------------

FileName: clock.h

Function: 头文件

Author: Zhang Kaizhou

Date: 2019-6-12 18:07:29

------------------------*/

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int

/*IIC总线端口定义*/

sbit SDA = P2^0;

sbit SCL = P2^1;

/*LCD1602显示模块端口定义*/

sbit lcdrs = P1^2;

sbit lcdrw = P1^3;

sbit lcden = P1^4;

/*主函数模块函数声明*/

void writeData24C02(uchar address, uchar dat);

void readData24C02(uchar address, uchar * dat);

void checkData(uchar * dat);

void timerInit();

/*IIC总线模块函数声明*/

void initIIC();

void startIIC();

void responseIIC();

void stopIIC();

void writeDataIIC(uchar dat);

void readDataIIC(uchar * dat);

/*LCD1602显示模块函数声明*/

void LCDInit();

void display(uchar dat1, uchar dat2);

void writeCommand(uchar command);

void writeDataLCD(uchar dat);

void delay(uchar xms);/*--------------------------------------------

FileName: main.c

Function: 用单片机实现0 ~ 99s的计时,

将计时实时显示在LCD上,并用24C02实现掉电记忆;

Author: Zhang Kaizhou

Date: 2019-6-12 18:06:18

--------------------------------------------*/

#include "clock.h"

/*定义全局变量*/

uchar second = 0, count = 0;

bit flag = 0;

void main(){

LCDInit();

initIIC();

readData24C02(1, &second); // 通过IIC总线将24C02的第1个存储单元中的数据读取到变量second中

checkData(&second); // 首次读取数据时,原来芯片中的数据可能超过100(非法数据)

timerInit();

TR0 = 1; // 开始计时

while(1){

display(second / 10, second % 10);

if(flag){

flag = 0;

writeData24C02(1, second);

}

}

}

/*向24C02的任意地址address处写入数据dat*/

void writeData24C02(uchar address, uchar dat){

startIIC();

writeDataIIC(0xa0); // 向IIC总线发送寻址信号,并声明要进行写操作

responseIIC();

writeDataIIC(address);

responseIIC();

writeDataIIC(dat);

responseIIC();

stopIIC();

}

/*从24C02的任意地址address处读出数据到变量dat*/

void readData24C02(uchar address, uchar * dat){

startIIC();

writeDataIIC(0xa0);

responseIIC();

writeDataIIC(address);

responseIIC();

startIIC();

writeDataIIC(0xa1); // 向IIC总线发送寻址信号,并声明要进行读操作

responseIIC();

readDataIIC(dat);

stopIIC();

}

/*检测从24C02读取的数据是否合法*/

void checkData(uchar * dat){

if((* dat) > 100){

* dat = 0;

}

}

/*timer初始化*/

void timerInit(){

TMOD = 0x01; // timer0 定时模式 工作方式1(16位定时器)

TH0 = (65536 - 46080) / 256; // 系统晶振为11.0592MHz,定时50ms

TL0 = (65536 - 46080) % 256;

ET0 = 1; // 开定时器0溢出中断

EA = 1; // 开全局中断

}

/*timer0溢出中断服务程序*/

void timer0Service() interrupt 1{

TH0 = (65536 - 46080) / 256; // 重装初值

TL0 = (65536 - 46080) % 256;

count++;

if(count == 20){ // 50ms * 20 = 1s

count = 0;

second++;

flag = 1;

if(second == 100){ // 0 ~ 99s

second = 0;

}

}

}/*------------------------------

FileName: IIC.c

Function: 实现IIC总线的基本操作

Author: Zhang Kaizhou

Date: 2019-6-12 18:08:47

------------------------------*/

#include "clock.h"

/*IIC总线初始化*/

void initIIC(){

SCL = 1;

_nop_();

SDA = 1;

_nop_();

}

/*IIC总线启动信号*/

void startIIC(){ // 在SCL高电平期间,SDA产生一个下降沿表示启动

SDA = 1;

_nop_();

SCL = 1;

_nop_();

SDA = 0;

_nop_();

}

/*IIC总线应答信号*/

void responseIIC(){ // 从机在SCL高电平期间将SDA拉低表示应答

SDA = 0;

_nop_();

SCL = 1;

_nop_();

SCL = 0;

_nop_();

}

/*IIC总线停止信号*/

void stopIIC(){ // 在SCL高电平期间,SDA产生一个上升沿表示停止

SDA = 0;

_nop_();

SCL = 1;

_nop_();

SDA = 1;

_nop_();

}

/*向IIC总线写一个字节数据*/

void writeDataIIC(uchar dat){

uchar i, temp;

temp = dat;

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

temp = temp << 1;

SCL = 0;

_nop_();

SDA = CY;

_nop_();

SCL = 1;

_nop_();

}

SCL = 0;

_nop_();

SDA = 1;

_nop_();

}

/*从IIC总线读一个字节数据*/

void readDataIIC(uchar * dat){

uchar i;

SCL = 0;

_nop_();

SDA = 1;

_nop_();

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

SCL = 1;

_nop_();

* dat = ((* dat) << 1) | SDA;

SCL = 0;

_nop_();

}

}/*-----------------------------

FileName:display.c

Function: LCD1602显示函数

Author: Zhang Kaizhou

Date: 2019-6-12 18:09:16

------------------------------*/

#include "clock.h"

uchar code table0[] = {"Timekeeping"};

uchar code table1[] = {"Time:"};

uchar code table2[] = {"0123456789"};

uchar num = 0;

/*初始化LCD1602的设置*/

void LCDInit(){

uchar i;

lcden = 0; // 拉低使能端,准备产生使能高脉冲信号

writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口)

writeCommand(0x0c); // 开显示,不显示光标

writeCommand(0x06); // 写一个字符后地址指针自动加1

writeCommand(0x01); // 显示清零,数据指针清零

/*LCD上电界面*/

writeCommand(0x80); // 将数据指针定位到第一行首

for(i = 0; i < strlen(table0); i++){

writeDataLCD(table0[i]);

delay(5);

}

writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首

for(i = 0; i < strlen(table1); i++){

writeDataLCD(table1[i]);

delay(5);

}

}

/*LCD显示函数*/

void display(uchar dat1, uchar dat2){

writeCommand(0x80 + 0x40 + strlen(table1));

writeDataLCD(table2[dat1]);

delay(5);

writeCommand(0x80 + 0x40 + strlen(table1) + 1);

writeDataLCD(table2[dat2]);

delay(5);

}

/*写指令函数*/

void writeCommand(uchar command){

lcdrs = 0; // 命令选择

lcdrw = 0;

P0 = command;

delay(5);

lcden = 1; // 产生一个正脉冲使能信号

delay(5);

lcden = 0;

}

/*写数据函数*/

void writeDataLCD(uchar dat){

lcdrs = 1; // 数据选择

lcdrw = 0;

P0 = dat;

delay(5);

lcden = 1;

delay(5);

lcden = 0;

}

/*延时xms函数*/

void delay(uchar xms){

uchar i, j;

for(i = xms; i > 0; i--)

for(j = 110; j > 0; j--);

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值