历史上的今天
返回首页

历史上的今天

今天是:2025年04月17日(星期四)

正在发生

2020年04月17日 | 单片机实现具有掉电记忆功能的计时器

2020-04-17 来源:eefocus

项目描述:

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

仿真原理图如下:

在这里插入图片描述

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--);

}

推荐阅读

史海拾趣

Gespac Inc公司的发展小趣事

对于快速充电IC(bq2002)电路,网友可能还会有多种问题,以下是一些常见问题及其回答:

一、电路设计相关问题

  1. BQ2002的BAT引脚如何正确接入电池电压?
    • 回答:BQ2002的BAT引脚用于接收电池电压的取样信号。通常,电池电压会经过一个电阻分压网络后接入BAT引脚,以确保BQ2002能够正确检测电池电压。电阻分压网络的输入电阻不应小于200kΩ,以避免对电池电压造成过大影响。
  2. 如何设置BQ2002的充电速率?
    • 回答:BQ2002的充电速率可以通过TM引脚进行设置。当TM引脚接地时,充电速率为1C(即电池容量的1倍)。此外,根据数据手册,TM引脚的不同电平还可能对应不同的充电速率,如C/2或2C,但具体设置需参考具体的数据手册或应用指南。
  3. BQ2002的CC引脚如何控制充电电流?
    • 回答:BQ2002的CC引脚用于控制充电电流的开关,而不是直接调节充电电流的大小。CC引脚有两种状态:高阻态和接地态。当CC引脚为高阻态时,充电电流可以流动;当CC引脚接地时,充电电流被抑制。充电电流的大小通常由外部恒流源(如LM317等)的电阻设置决定,与CC引脚的状态无关。

二、功能实现与调试问题

  1. 为什么BQ2002没有进入快速充电模式?
    • 回答:BQ2002没有进入快速充电模式可能由多种原因造成,如电池电压或温度不符合快速充电条件、TS引脚电压不在正常范围内、或外部电路设计问题等。建议检查电池电压和温度是否满足快速充电条件,同时检查TS引脚电压是否介于0.25VCC和0.4VCC之间(或1.25V和2.0V之间),并确认外部电路设计无误。
  2. BQ2002在充电过程中突然停止充电怎么办?
    • 回答:BQ2002在充电过程中突然停止充电可能是由于电池过热、电池电压过高或外部电路故障等原因造成的。建议检查电池温度是否过高,电池电压是否超出BQ2002的承受范围,并检查外部电路是否有短路或断路等故障。如果问题依旧存在,可能需要更换BQ2002芯片或重新设计外部电路。
  3. 如何调整BQ2002的充电截止电压?
    • 回答:BQ2002的充电截止电压通常是通过外部电路设计来调整的。具体方法可能因电路设计而异,但一般可以通过调整与BAT引脚相连的分压电阻的阻值来改变BQ2002检测到的电池电压值,从而调整充电截止电压。需要注意的是,在调整充电截止电压时,应确保电池不会因过充而损坏。

三、其他常见问题

  1. BQ2002支持哪些类型的电池?
    • 回答:BQ2002通常支持多种类型的可充电电池,如镍氢电池、锂离子电池等。但具体支持的电池类型可能因BQ2002的版本或制造商而有所不同。因此,在使用BQ2002进行电池充电时,应参考具体的数据手册或应用指南以了解支持的电池类型。
  2. BQ2002的功耗如何?
    • 回答:BQ2002的功耗通常较低,但具体功耗值可能因工作条件(如输入电压、输出电流、环境温度等)的不同而有所变化。在设计电路时,应充分考虑BQ2002的功耗对系统整体性能的影响,并采取相应的措施来降低功耗。

以上是针对快速充电IC(bq2002)电路的一些常见问题及其回答。需要注意的是,由于BQ2002的具体应用可能因电路设计、电池类型等因素而有所不同,因此在实际应用中应参考具体的数据手册或应用指南以获取准确的信息。

DDP Engineered LED Solutions公司的发展小趣事

在电子行业中,绿色环保已经成为一个不可忽视的趋势。DDP Engineered LED Solutions公司积极响应这一趋势,将绿色环保理念融入到公司的产品研发和生产过程中。公司开发的LED照明产品不仅具有出色的照明效果,而且具有较低的能耗和较少的废弃物产生,符合绿色环保的要求。同时,公司还积极推动绿色供应链管理,与供应商共同构建绿色、环保的产业链。这些努力不仅让DDP在行业中树立了良好的形象,也为公司的可持续发展提供了有力保障。

Alliance Memory公司的发展小趣事

在电子行业中,绿色环保已经成为一个不可忽视的趋势。DDP Engineered LED Solutions公司积极响应这一趋势,将绿色环保理念融入到公司的产品研发和生产过程中。公司开发的LED照明产品不仅具有出色的照明效果,而且具有较低的能耗和较少的废弃物产生,符合绿色环保的要求。同时,公司还积极推动绿色供应链管理,与供应商共同构建绿色、环保的产业链。这些努力不仅让DDP在行业中树立了良好的形象,也为公司的可持续发展提供了有力保障。

Advanced Optoelectronic Technology Corp公司的发展小趣事

在追求经济效益的同时,AOTC也积极履行社会责任。公司注重环保和可持续发展,采用环保材料和节能技术生产产品,降低对环境的影响。此外,公司还积极参与公益事业,支持教育、科研等领域的发展,为社会做出了积极贡献。

这些故事虽然是虚构的,但它们反映了一个电子行业中公司可能经历的一些典型发展阶段和挑战。在真实情况中,公司的发展路径会受到市场环境、技术变革、竞争态势等多种因素的影响。

General Industrial Controls ( GIC )公司的发展小趣事
确保所有元件均为合格产品,无损坏或老化现象。特别是电感器,其载流能力、Q值和工作频率等参数需满足要求。
ARMKEIL Microcontroller Tools公司的发展小趣事

2005年,对于Keil公司来说是一个具有里程碑意义的年份。在这一年,英国的ARM公司看中了Keil在嵌入式系统开发工具领域的领先地位和技术实力,决定对其进行收购。收购完成后,Keil公司正式成为ARM公司的一部分,继续专注于嵌入式系统开发工具的研发和销售。这一事件标志着Keil公司进入了一个新的发展阶段,也为其未来的发展奠定了坚实的基础。

问答坊 | AI 解惑

用74LS73(双jk触发器)设计一个六进制计数器。

请问用74LS73(双jk触发器)怎样设计一个六进制计数器?请把接线法说一下。…

查看全部问答>

protel图解教程

看看吧,挺有帮助的,快速入门…

查看全部问答>

Cypress:触摸屏将成为2010年市场热点

观察琳琅满目的电子产品,我们不难发现触摸屏的采用已经越来越普及,从手机到GPS,从数码相机到刚刚上市的iPad,消费者已经不再满足于简单的点击、拉伸,触摸控制技术的发展可谓日新月异。 市场调研机构iSuppli的预测,未来几年全球触摸屏幕设备的 ...…

查看全部问答>

谁有at91sam9260 rtl8201驱动,顶贴给分

谁有at91sam9260 rtl8201驱动,顶贴给分…

查看全部问答>

如何解决操作系统不能动态加载驱动程序的故障呢?

我在网吧,发现网吧的电脑上,系统不允许动态加载驱动程序,凡是有会动态加载驱动程序的比如CPU-Z、或VirtualPC2007安装程序等等都无法执行。我想请教一下到底系统是哪里被设置了,如何才能解开这些限制呢?我就是想在网吧的电脑上使用VPC2007在自 ...…

查看全部问答>

谁有arm网络开发的资料?100分求.

谁有arm网络开发的资料?给我发一个好吗,不胜感激.shenjuan@163.com…

查看全部问答>

威视锐ZYNQ开发板-ZingSK高清视频接口实例--HDMI

1. 概述ZingSK开发套件采用核心板加底板的方式,方便用户使用自定义的低成本的底板. ZingSK配套的底板也拥有丰富的接口, ZingSK外观如图1. 图1 本实例主要介绍底板上高清多媒体接口HDMI的使用,并通过软硬件协同设计的方法来实现彩条输出.通过ZYNQ ...…

查看全部问答>

msp430 DCO外接电阻(ROSC)设置频率 无效 求助

此为TI官网例程,msp430f2618 DCO外接电阻(ROSC)设置频率,用IAR编译,430仿真器JTAG口下载仿真,单步调试到标志处(如下代码黄色背景)处程序跑飞,不能继续,实在不明白为什么,求高手知道。 (代码说明中下滑线处说这可能影响到JTAG重新建立链 ...…

查看全部问答>

LPC1830 SWD無法燒錄

各位,我用的LPC1830FBD144,搭ULINK-ME燒錄,KEILC提示如下,SWD Communication failure,求各位幫忙!…

查看全部问答>

STM32F4开发板录音实验喇叭一直叫

今天做STM32的录音实验,遇到喇叭一直长鸣的问题,请求各位大侠帮忙。情况是这样的,板子是SEM32F4探索者V2.2,插了一个4g的SD卡,开发环境是KEIL5,程序是光盘里面的录音实验原代码,没有改动,编译通过,用JLINK正常下载,程序运行时,喇叭就开始 ...…

查看全部问答>