51单片机 EEPROM 24c02 + 数码管 + 中断 统计开机次数
>_<:delay.c
本文引用地址:https://www.eepw.com.cn/article/201611/318338.htm1 #include "delay.h"2 /*3 uS延时函数,含有输入参数 unsigned char t,无返回值4 unsigned char 是定义无符号字符变量,其值的范围是5 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时6 长度如下 T=tx2+5 uS 7 */8 void DelayUs2x(unsigned char t)9 { 10 while(--t);11 }12 /*13 mS延时函数,含有输入参数 unsigned char t,无返回值14 unsigned char 是定义无符号字符变量,其值的范围是15 0~255 这里使用晶振12M,精确延时请使用汇编16 */17 void DelayMs(unsigned char t)18 {19 while(t--)20 {21 //大致延时1mS22 DelayUs2x(245);23 DelayUs2x(245);24 }25 }
>_<:delay.h
1 #ifndef __DELAY_H__2 #define __DELAY_H__3 /*4 uS延时函数,含有输入参数 unsigned char t,无返回值5 unsigned char 是定义无符号字符变量,其值的范围是6 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时7 长度如下 T=tx2+5 uS 8 */9 void DelayUs2x(unsigned char t);10 /*11 mS延时函数,含有输入参数 unsigned char t,无返回值12 unsigned char 是定义无符号字符变量,其值的范围是13 0~255 这里使用晶振12M,精确延时请使用汇编14 */15 void DelayMs(unsigned char t);16 17 #endif
>_<:display.c
1 #include"display.h"2 #include"delay.h"3 4 #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换5 //sbit LATCH1=P2^0;//定义锁存使能端口 段锁存6 //sbit LATCH2=P2^3;// 位锁存7 8 unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~99 unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码10 unsigned char TempData[8]; //存储显示值的全局变量11 /*12 显示函数,用于动态扫描数码管13 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示14 如输入0表示从第一个显示。15 Num表示需要显示的位数,如需要显示99两位数值则该值输入216 */17 void Display(unsigned char FirstBit,unsigned char Num)18 {19 static unsigned char i=0;20 21 DataPort=0; //清空数据,防止有交替重影22 LATCH1=1; //段锁存23 LATCH1=0;24 25 DataPort=dofly_WeiMa[i+FirstBit]; //取位码 26 LATCH2=1; //位锁存27 LATCH2=0;28 29 DataPort=TempData[i]; //取显示数据,段码30 LATCH1=1; //段锁存31 LATCH1=0;32 33 i++;34 if(i==Num)35 i=0; 36 }37 /*38 定时器初始化子程序39 */40 void Init_Timer0(void)41 {42 TMOD = 0x01; //使用模式1,16位定时器,使用""符号可以在使用多个定时器时不受影响 43 //TH0=0x00; //给定初值44 //TL0=0x00;45 EA=1; //总中断打开46 ET0=1; //定时器中断打开47 TR0=1; //定时器开关打开48 }49 /*50 定时器中断子程序51 */52 void Timer0_isr(void) interrupt 1 53 {54 TH0=(65536-2)/256; //重新赋值 2ms55 TL0=(65536-2)%256;56 Display(0,8);57 }
>_<:display.h
1 #include2 3 #ifndef __DISPLAY_H__4 #define __DISPLAY_H__5 6 #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换7 sbit LATCH1=P2^2;//定义锁存使能端口 段锁存8 sbit LATCH2=P2^3;// 位锁存9 10 extern unsigned char TempData[8]; //存储显示值的全局变量11 extern unsigned char code dofly_DuanMa[10];12 /*13 显示函数,用于动态扫描数码管14 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示15 如输入0表示从第一个显示。16 Num表示需要显示的位数,如需要显示99两位数值则该值输入217 */18 void Display(unsigned char FirstBit,unsigned char Num);19 /*20 定时器初始化子程序21 */22 void Init_Timer0(void);23 24 #endif
>_<:i2c.c
1 /*--2 名称:IIC协议 3 内容:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 一定的修改....(本例是1us机器4 周期,即晶振频率要小于12MHZ)5 */ 6 #include "i2c.h"7 #include "delay.h"8 #define _Nop() _nop_() //定义空指令 9 bit ack; //应答标志位10 sbit SDA=P2^1;11 sbit SCL=P2^0;12 /*13 启动总线14 */15 void Start_I2c()16 {17 SDA=1; //发送起始条件的数据信号18 _Nop();19 SCL=1;20 _Nop(); //起始条件建立时间大于4.7us,延时21 _Nop();22 _Nop();23 _Nop();24 _Nop(); 25 SDA=0; //发送起始信号26 _Nop(); //起始条件锁定时间大于4μ27 _Nop();28 _Nop();29 _Nop();30 _Nop(); 31 SCL=0; //钳住I2C总线,准备发送或接收数据32 _Nop();33 _Nop();34 }35 /*36 结束总线37 */38 void Stop_I2c()39 {40 SDA=0; //发送结束条件的数据信号41 _Nop(); //发送结束条件的时钟信号42 SCL=1; //结束条件建立时间大于4μ43 _Nop();44 _Nop();45 _Nop();46 _Nop();47 _Nop();48 SDA=1; //发送I2C总线结束信号49 _Nop();50 _Nop();51 _Nop();52 _Nop();53 }54 /*-55 字节数据传送函数 56 函数原型: void SendByte(unsigned char c);57 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对58 此状态位进行操作.(不应答或非应答都使ack=0 假) 59 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。60 */61 void SendByte(unsigned char c)62 {63 unsigned char BitCnt;64 65 for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位66 {67 if((c<
>_<:i2c.h
1 /*--2 名称:IIC协议 头文件3 内容:4 */ 5 #ifndef __I2C_H__6 #define __I2C_H__ 7 8 #include//头文件的包含9 #include 10 #define _Nop() _nop_() //定义空指令11 /*12 启动总线13 */14 void Start_I2c();15 /*16 结束总线17 */18 void Stop_I2c();19 /*-20 字节数据传送函数 21 函数原型: void SendByte(unsigned char c);22 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对23 此状态位进行操作.(不应答或非应答都使ack=0 假) 24 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。25 */26 void SendByte(unsigned char c);27 /*-28 字节数据传送函数 29 函数原型: unsigned char RcvByte();30 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),31 发完后请用应答函数。 32 */ 33 unsigned char RcvByte();34 /*-35 应答子函数36 原型: void Ack_I2c(void);37 -*/38 void Ack_I2c(void);39 /*-40 非应答子函数41 原型: void NoAck_I2c(void);42 -*/43 void NoAck_I2c(void);44 /*-45 向无子地址器件发送字节数据函数 46 函数原型: bit ISendByte(unsigned char sla,ucahr c); 47 功能: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.48 如果返回1表示操作成功,否则操作有误。49 注意: 使用前必须已结束总线。50 -*/51 bit ISendByte(unsigned char sla,unsigned char c);52 /*-53 向有子地址器件发送多字节数据函数 54 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no); 55 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件56 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。57 如果返回1表示操作成功,否则操作有误。58 注意: 使用前必须已结束总线。59 -*/60 bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);61 /*-62 向无子地址器件读字节数据函数 63 函数原型: bit IRcvByte(unsigned char sla,ucahr *c); 64 功能: 从启动总线到发送地址,读数据,结束总线的全过程,从器件地65 址sla,返回值在c.66 如果返回1表示操作成功,否则操作有误。67 注意: 使用前必须已结束总线。68 -*/69 bit IRcvByte(unsigned char sla,unsigned char *c);70 /*-71 向有子地址器件读取多字节数据函数 72 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no); 73 功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件74 地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。75 如果返回1表示操作成功,否则操作有误。76 注意: 使用前必须已结束总线。77 -*/78 bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);79 #endif
>_<:main()
1 /*--2 名称:IIC协议 24c02存储开机次数3 内容:每次开机,开机数值加1并存储到24c024 */ 5 #include6 #include "i2c.h"7 #include "delay.h"8 #include "display.h"9 10 main()11 {12 unsigned char num=0;13 Init_Timer0();14 IRcvStr(0xae,50,&num,1); //从24c02读出数据 15 num++; 16 ISendStr(0xae,50,&num,1); //写入24c02 17 DelayMs(10);18 TempData[0]=dofly_DuanMa[num/100]; 19 TempData[1]=dofly_DuanMa[(num%100)/10];20 TempData[2]=dofly_DuanMa[(num%100)%10];21 22 while(1)23 {24 }25 }
评论