项目描述:
用单片机实现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--); }
上一篇:51单片机之计时器
下一篇:51单片机计时器实现1000以内的计数功能
推荐阅读最新更新时间:2024-11-08 15:50
设计资源 培训 开发板 精华推荐
- 自平衡小车的原理硬件设计和源代码
- MMA8491Q 三轴多功能数字加速度计典型应用
- 【训练营】蹦蹦跳跳狗狗 v1.0
- 调试小工具,蓝牙&hid&串口&hub大集合
- LTC3552 的典型应用 - 独立线性锂离子电池充电器和双路同步降压转换器
- LT1767EMS8-3.3 12V 至 3.3V 降压转换器的典型应用电路
- LT1942EUF 演示板,用于 TFT 电源和 LED 驱动器的四路转换器,Vin=3V-4.5V,Von=10V/2mA,Voff=-10V/2mA,AVdd=5V/40mA
- ADA4000-2ARZ-R7运算放大器缓冲网络配置的典型应用电路
- 使用增强型隔离放大器且基于分流器的高电流测量 (200A) 参考设计
- 使用 NXP Semiconductors 的 MK21DN512VMC5 的参考设计