I2c总线的练习题

本文介绍了一个使用51单片机实现的0-99秒表项目,通过I2C接口与数码管交互显示秒表计时。文章详细讲解了软件设计思路、定时器配置及数码管显示原理,特别关注了掉电保护和数据持久化处理。

题目

利用定时器产生一个0-99变化秒表,并且显示在数码管上,每过一秒将变化写在板上,当关闭实验板时,再次打开实验板时,继续变化并显示在实验板上,

分析

对于此题,我比较头疼的是,怎么让数码管和i2c之间怎么组合,然后并读出,因此开始时考虑的是断电便可以读出,因此,每次写入时,都应该把读出的数据保存,并且直接读出保存的数据,因此这是第一步,就是直接读出保存的数据,才能保证下一步断电才可以直接读出,接着,就是数码管的显示,数码管的显示如果是shige的话,开始的时候,会出现均为0 的情况,这是不对的,因此必须用从读出的数据来表示出来,就是num/10,num%10,来表示,是最好的方法,而不是shige会出现00的情况,然后展示数码管,在定时器有时需要标志位,当函数很复杂时,是需要标志位的,特别是中断,考虑标志位,因为中断的复杂性,很容易考虑到标志位,然后标志位清0,然后add写入数据,此题关键就是中间的衔接部分不知道怎么写,考虑时注意顺序,

代码

 

  1 # include <reg52.h>
  2 # define UCHAR unsigned char
  3 # define UINT unsigned int
  4 sbit scl = P2^1;
  5 sbit sda = P2^0;
  6 sbit dula = P2^6;
  7 sbit wela = P2^7;
  8 UCHAR num,i,write;
  9 UCHAR code dulai[]=
 10 {
 11 0x3f,0x06,0x5b,0x4f,
 12 0x66,0x6d,0x7d,0x07,
 13 0x7f,0x6f,0x77,0x7c,
 14 0x39,0x5e,0x79,0x71    
 15 };
 16 void delay()
 17 {
 18 ;;
 19 }
 20 void init()
 21 {
 22    scl = 1;
 23    delay();
 24    sda = 1;
 25    delay();
 26    TMOD = 0x01;
 27    TH0 = (65536-50000)/256;
 28    TL0 = (65536-50000)%256;
 29    EA = 1;
 30    ET0 = 1;
 31    TR0 = 1;
 32 }
 33 
 34 void start()
 35 {
 36     sda = 1;
 37     delay();
 38     scl = 1;
 39     delay();
 40     sda = 0;
 41     delay();
 42 }
 43 
 44 void stop()
 45 {
 46     sda = 0;
 47     delay();
 48     scl = 1;
 49     delay();
 50     sda = 1;
 51     delay();
 52 }
 53 
 54 void respons()
 55 {
 56     UCHAR i = 0;
 57     scl = 1;
 58     delay();
 59     while((sda ==1)&&(i<250))
 60         i++;
 61     scl = 0;//第九个时钟拉低
 62     delay();
 63 }
 64 
 65 void delay1(UCHAR x)
 66 {
 67     UCHAR y,z;
 68     for(y = x;y >0;y--)
 69         for(z = 110;z>0;z--);
 70 }
 71 
 72 void write_byte(UCHAR date)
 73 {
 74     UCHAR temp,i;
 75     temp =date;
 76     for(i = 0;i< 8;i++)
 77     {
 78         temp=temp<<1;
 79         scl = 0;
 80         delay();
 81         sda = CY;
 82         delay();
 83         scl = 1;
 84         delay();
 85     }
 86     scl = 0;
 87     delay();
 88     sda = 1;
 89     delay();
 90     
 91 }
 92 
 93 UCHAR read_byte()
 94 {
 95     UCHAR k,i;
 96     scl = 0;
 97     delay();
 98     sda = 1;
 99     delay();
100     for(i = 0;i< 8;i++)
101     {
102         scl = 1;
103         delay();
104         k = k<<1|sda;
105         delay();
106         scl  = 0;
107         delay();
108     }
109     return k;
110 }
111 
112 void write_add(UCHAR adress,UCHAR date)
113 {
114     start();
115     write_byte(0xa0);
116     respons();
117     write_byte(adress);
118     respons();
119     write_byte(date);
120     respons();
121     stop();
122 
123 }
124 
125 UCHAR read_add(UCHAR address)
126 {
127     UCHAR date;
128     start();
129     write_byte(0xa0);
130     respons();
131     write_byte(address);
132     respons();
133     start();
134     write_byte(0xa1);
135     respons();
136     date = read_byte();
137     stop();
138     return date;
139     
140 
141 }
142 void display(UCHAR shi,UCHAR ge)
143 {
144    wela = 1;
145    P0 = 0xfe;
146    wela = 0;
147    P0 = 0xff;
148    dula = 1;
149    P0= dulai[shi];
150    dula = 0;
151    delay1(5);
152 
153    wela = 1;
154    P0 = 0xfd;
155    wela = 0;
156    P0 = 0xff;
157    dula = 1;
158    P0= dulai[ge];
159    dula = 0;
160    delay1(5);
161 }
162 void main()
163 {
164     init();
165     num = read_add(2);//上去都要读,因为掉电,就是上去就要读出的
166     if(num > 100)
167         num = 0;
168     //delay1(100);
169     
170     while(1)
171     {
172         display(num/10,num%10);//因为num的原因,如果是shige的话,就会出现开始为0的情况
173         if(write == 1)//write是重点,标志位
174         {
175             write = 0;
176             write_add(2,num);
177         }
178     }
179 }
180 void timer0 () interrupt 1
181 {
182     TH0 = (65536-50000)/256;
183        TL0 = (65536-50000)%256;    
184     i++;
185     if(i == 20)
186     {
187         i = 0;
188         num++;
189         write = 1;
190         if(num == 99)
191             num = 0;
192     }
193 }

 

转载于:https://www.cnblogs.com/yelcoved/p/3239628.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值