是设计一个红外计数器的,就差这个计数器计数的保存 存到AT24C02里面好像就最多就255,一到256就清零了
初学者有很多不太懂,at24c02 程序是直接搬书里的 我觉得关键就在我写的那个中断1那里 有大神可以帮看看程序吗
单片机源程序如下:
- #include <reg52.h> //51头文件
- # include <intrins.h>
- #define uchar unsigned char//宏定义
- #define uint unsigned int //宏定义
- #define AT24C02_ADDR 0xa0 //AT24C02地址
- sbit we = P2^7; //位定义数码管位选锁存器接口
- sbit du = P2^6; //位定义数码管段选锁存器接口
- sbit SDA = P2^0;
- sbit SCL = P2^1;
- sbit key = P2^5;//清零键
- sbit LED = P1^2;//指示灯,若灯亮说明IIC数据写入成功
- long uint n;
- void delay_5us()
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*1Ms延时*/
- void delay(uint z)
- {
- uint x,y;
- for(x = z; x > 0; x--)
- for(y = 114; y > 0 ; y--);
- }
- /*I2C初始化*/
- void I2C_init()
- {
- SDA = 1;
- _nop_();
- SCL = 1;
- _nop_();
- }
- /*I2C起始信号*/
- void I2C_Start()
- {
- SCL = 1;
- _nop_();
- SDA = 1;
- delay_5us();
- SDA = 0;
- delay_5us();
- }
- /*I2C终止信号*/
- void I2C_Stop()
- {
- SDA = 0;
- _nop_();
- SCL = 1;
- delay_5us();
- SDA = 1;
- delay_5us();
- }
- /*主机发送应答*/
- void Master_ACK(bit i)
- {
- SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化
- _nop_(); // 让总线稳定
- if (i) //如果i = 1 那么拉低数据总线 表示主机应答
- {
- SDA = 0;
- }
- else
- {
- SDA = 1; //发送非应答
- }
- _nop_();//让总线稳定
- SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号
- delay_5us();
- SCL = 0;//拉低时钟总线, 占用总线继续通信
- _nop_();
- SDA = 1;//释放SDA数据总线。
- _nop_();
- }
- /*检测从机应答*/
- bit Test_ACK()
- {
- SCL = 1;
- delay_5us();
- if (SDA)
- {
- SCL = 0;
- _nop_();
- I2C_Stop();
- return(0);
- }
- else
- {
- SCL = 0;
- _nop_();
- return(1);
- }
- }
- /*发送一个字节*/
- void I2C_send_byte(uchar byte)
- {
- uchar i;
- for(i = 0 ; i < 8 ; i++)
- {
- SCL = 0;
- _nop_();
- if (byte & 0x80)
- {
- SDA = 1;
- _nop_();
- }
- else
- {
- SDA = 0;
- _nop_();
- }
- SCL = 1;
- _nop_();
- byte <<= 1; // 0101 0100B
- }
- SCL = 0;
- _nop_();
- SDA = 1;
- _nop_();
- }
- /*I2C 读一字节*/
- uchar I2C_read_byte()
- {
- uchar dat,i;
- SCL = 0;
- _nop_();
- SDA = 1;
- _nop_();
- for(i = 0 ; i < 8 ; i++)
- {
- SCL = 1;
- _nop_();
- if (SDA)
- {
- dat |= 0x01; //
- }
- else
- {
- dat &= 0xfe; //1111 1110
- }
- _nop_();
- SCL = 0 ;
- _nop_();
- if(i < 7)
- {
- dat = dat << 1;
- }
- }
- return(dat);
- }
- /*I2C发送数据*/
- bit I2C_TransmitData(uchar ADDR, DAT)
- {
- I2C_Start();
- I2C_send_byte(AT24C02_ADDR+0);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_send_byte(ADDR);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_send_byte(DAT);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_Stop();
- return(1);
- }
- /*I2C接收数据*/
- uchar I2C_ReceiveData(uchar ADDR)
- {
- uchar DAT;
- I2C_Start();
- I2C_send_byte(AT24C02_ADDR+0);
- if (!Test_ACK()) //检测从机应答
- {
- return(0);
- }
- I2C_send_byte(ADDR); //发送需要读取的数据所在的地址
- Master_ACK(0);
- I2C_Start();
- I2C_send_byte(AT24C02_ADDR+1);
- if (!Test_ACK())
- {
- return(0);
- }
- DAT = I2C_read_byte();
- Master_ACK(0); //主机发应答
- I2C_Stop();
- return(DAT);
- }
- //数码管段选表
- uchar code leddata[]={
- 0x3F, //"0"
- 0x06, //"1"
- 0x5B, //"2"
- 0x4F, //"3"
- 0x66, //"4"
- 0x6D, //"5"
- 0x7D, //"6"
- 0x07, //"7"
- 0x7F, //"8"
- 0x6F, //"9"
- };
- uchar code WS[]={
- 0x7f,
- 0xbf,
- 0xdf,
- 0xef,
- 0xf7,
- 0xfb,
- 0xfd,
- 0xfe //1111 1110
- };
- void T0_int() interrupt 1
- {
- n++;
- TH0 = 65535/256; //重装初值
- TL0 = 65535%256; //从15536开始计数
- if(!I2C_TransmitData(6,n%1000)); //往AT24C02第255个单元中写入数据,1000 0000的2进制为3个八位,16进制为0x98 96 80,1000 0000%256=80;低八位
- delay(5);
- if(!I2C_TransmitData(5,n/1000%1000)); //往AT24C02第255个单元中写入数据,1000 0000的2进制为3个八位,16进制为0x98 96 80,1000 0000%256=80;低八位
- delay(5);
- if(!I2C_TransmitData(4,n/1000/1000)); //往AT24C02第255个单元中写入数据,1000 0000的2进制为3个八位,16进制为0x98 96 80,1000 0000%256=80;高八位
- delay(5);
- if(n>10000000) //计数次数达到1000W
- {
- P2 = WS[13]; //数码管显示E代表计数已达上限
- P0 = leddata[1];
- }
- }
- void INT0_int() interrupt 2
- {
- if(!I2C_TransmitData(6,0)); //往AT24C02第255个单元中写入数据,1000 0000的2进制为3个八位,16进制为0x98 96 80,1000 0000%256=80;低八位
- delay(5);
- if(!I2C_TransmitData(5,0)); //往AT24C02第255个单元中写入数据,1000 0000的2进制为3个八位,16进制为0x98 96 80,1000 0000%256=80;低八位
- delay(5);
- if(!I2C_TransmitData(4,0)); //往AT24C02第255个单元中写入数据,1000 0000的2进制为3个八位,16进制为0x98 96 80,1000 0000%256=80;高八位
- delay(5);
- }
- void main()
- {
- uchar a,b,c,d,e,f,g,h,i,j,k;
- TH0 = 65535/256;
- TL0 = 65535%256; //从15536开始计数
- TMOD = 0x05 ;//设置T0为计数器模式,工作方式1,16位计数器
- TR0 = 1; //启动T0
- EA = 1;
- EX1 = 1;
- IT1 = 1;
- ET0 = 1;//允许T0溢出中断
- I2C_init();//I2C初始化
- while(1)
- {
- i = I2C_ReceiveData(4);//从AT24C02单元中读取数据,高八位
- j = I2C_ReceiveData(5);//从AT24C02单元中读取数据,中八位
- k = I2C_ReceiveData(6);//从AT24C02单元中读取数据,低八位
- n = i*10000+j*100+k;
- a = n%10;
- b = n/10%10;
- c = n/100%10;
- d = n/1000%10;
- e = n/10000%10;
- f = n/100000%10;
- g = n/1000000%10;
- h = n/10000000;
- P0 = WS[0];
- we = 1;//打开位选
- we = 0; //关闭位选
- P0 = leddata[a];
- du = 1; //打开段选
- du = 0; //关闭段选
- delay(2);//延时
-
- we = 1; //打开位选
- P0 = WS[1];//1111 1101 只选通第二位数码管
- we = 0; //关闭位选
-
- P0 = leddata[b]; //显示2
- du = 1;//打开段选
- du = 0; //关闭段选
- delay(2);//延时
-
- P0 = WS[2];// 1111 1011只选通第三位数码管
- we = 1; //打开位选
- we = 0; //关闭位选
-
- P0 = leddata[c]; //显示3
- du = 1;//打开段选
- du = 0; //关闭段选
- delay(2);//延时
-
- P0 = WS[3];//1111 0111 只选通第四位数码管
- we = 1; //打开位选
- we = 0; //关闭位选
-
- P0 = leddata[d]; //显示4
- du = 1;//打开段选
- du = 0; //关闭段选
- delay(2);//延时
-
- P0 = WS[4];//1110 1111 只选通第五位数码管
- we = 1; //打开位选
- we = 0; //关闭位选
-
- P0 = leddata[e];
- du = 1;//打开段选
- du = 0; //关闭段选
- delay(2);//延时
-
- P0 = WS[5];//1101 1111 只选通第六位数码管
- we = 1; //打开位选
- we = 0; //关闭位选
-
- P0 = leddata[f]; //显示6
- du = 1;//打开段选
- du = 0; //关闭段选
- delay(2);//延时
-
- we = 1; //打开位选
- P0 = WS[6];//1011 1111 只选通第七位数码管
- we = 0; //关闭位选
-
- P0 = leddata[g];
- du = 1;//打开段选
- du = 0; //关闭段选
- delay(2);//延时
-
- P0 = WS[7];//0111 1111 只选通第八位数码管
- we = 1; //打开位选
- we = 0; //关闭位选
-
- P0 = leddata[h];
- du = 1;//打开段选
- du = 0; //关闭段选
- delay(2);//延时
- }
- }
复制代码
|