标签:
main.c
1 #include <reg51.h> 2 #include "iic.h" 3 #define AT24C02 0xa0 //AT24C02 地址 4 5 sbit LS138A=P2^2; //译码器端 6 sbit LS138B=P2^3; 7 sbit LS138C=P2^4; 8 9 sbit K1 = P1^0; //保存 10 sbit K2 = P1^1; //读取 11 sbit K3 = P1^2; //+数据 12 sbit K4 = P1^3; //-数据 13 14 void delay(unsigned int i); 15 16 //此表为 LED 的字模, 共阴数码管 0-9 17 unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; 18 19 unsigned char Count1; 20 unsigned long D[17], LedOut[5],LedNumVal; 21 unsigned int idata USEC; //表示这个变量类型是unsigned int,地址在idata区,也就是内部RAM地址的128~255内 22 23 void system_ini() 24 { 25 TMOD|= 0x11; //mode 1 26 TH1 = 0xfe; //0.5ms 27 TL1 = 0x0c; 28 TR1 = 1; 29 IE = 0x8A; 30 } 31 32 void main() 33 { 34 unsigned char i; 35 unsigned char pDat[8]; 36 37 system_ini(); 38 while(1) 39 { 40 //========================IIC 读取 41 if(K2 == 0) //第二个按钮读取数据 42 { 43 IRcvStr(AT24C02,0,&pDat[0], 8); 44 for (i=0; i<4; i++) 45 { 46 D[14+i]=pDat[i*2+0]+pDat[i*2+1]*0x100; 47 Count1 = D[14]; 48 } 49 } 50 51 //========================IIC 保存 52 if(K1 == 0) //第一个按钮保存数据 53 { 54 D[14]= Count1; 55 for (i=0; i<4; i++) 56 { 57 pDat[i*2+0]=D[14+i]; 58 pDat[i*2+1]=D[14+i]>>8; 59 } 60 ISendStr(AT24C02, 0 , &pDat[0], 8); 61 D[14] = 0; 62 } 63 64 /********以下将2402中保存的数据送到LED数码管显示*************/ 65 LedNumVal=Count1; 66 LedOut[0]=Disp_Tab[LedNumVal%10000/1000]; 67 LedOut[1]=Disp_Tab[LedNumVal%1000/100]; 68 LedOut[2]=Disp_Tab[LedNumVal%100/10]|0x80; 69 LedOut[3]=Disp_Tab[LedNumVal%10]; 70 71 for(i=0; i<4; i++) 72 { 73 P0 = LedOut[i]; 74 75 switch(i) 76 { 77 case 0:LS138A=0; LS138B=0; LS138C=0; break; 78 case 1:LS138A=1; LS138B=0; LS138C=0; break; 79 case 2:LS138A=0; LS138B=1; LS138C=0; break; 80 case 3:LS138A=1; LS138B=1; LS138C=0; break; 81 case 4:LS138A=0; LS138B=0; LS138C=1; break; 82 } 83 delay(100); 84 } 85 } 86 } 87 88 void delay(unsigned int i) 89 { 90 char j; 91 for(i; i > 0; i--) 92 for(j = 200; j > 0; j--); 93 } 94 95 void T1zd(void) interrupt 3 //3 为定时器1的中断号 1 定时器0的中断号 0 外部中断1 2 外部中断2 4 串口中断 96 { 97 TH1 = 0xfe; //12M 98 TL1 = 0x0c; 99 if(USEC++==200) 100 { 101 USEC = 0; 102 if(!K3) Count1++; //改变数据 103 if(!K4) Count1--; 104 } 105 }
iic.h
1 #include <reg51.h> 2 #include <intrins.h> 3 #define _NOP() _nop_() 4 sbit SCL = P2^1; 5 sbit SDA = P2^0; 6 bit ack; 7 8 void Start_IIC() 9 { 10 SDA = 1; 11 _NOP(); 12 SCL = 1; 13 _NOP();_NOP();_NOP();_NOP();_NOP(); 14 SDA = 0; 15 _NOP();_NOP();_NOP();_NOP();_NOP(); 16 SCL = 0; 17 _NOP();_NOP(); 18 } 19 20 void Stop_IIC() 21 { 22 SDA = 0; 23 _NOP(); 24 SCL = 1; 25 _NOP();_NOP();_NOP();_NOP();_NOP(); 26 SDA = 1; 27 _NOP();_NOP();_NOP();_NOP();_NOP(); 28 } 29 30 void Send_Byte(unsigned char byte) 31 { 32 int i; 33 for(i = 0;i < 8;i++) 34 { 35 if((byte << i) & 0x80) SDA = 1; 36 else SDA = 0; 37 SCL = 1; 38 _NOP();_NOP();_NOP();_NOP();_NOP(); 39 SCL = 0; 40 } 41 42 SCL = 1; //准备接受应答位 43 _NOP();_NOP(); 44 45 if(SDA == 1) ack = 0; 46 else ack = 1; 47 48 SCL = 0; 49 _NOP();_NOP(); 50 } 51 52 unsigned char Rcv_Byte() 53 { 54 unsigned char byte; 55 int i; 56 byte = 0; 57 58 for(i = 0;i < 8;i++) 59 { 60 SCL = 0; 61 _NOP();_NOP();_NOP();_NOP();_NOP(); 62 SCL = 1; 63 _NOP();_NOP();_NOP();_NOP();_NOP(); 64 byte <<= 1; 65 if(SDA == 1) byte++; 66 } 67 SCL = 0; 68 _NOP();_NOP(); 69 return byte; 70 } 71 72 void Ack_IIC(bit a) 73 { 74 75 if(a==0) SDA=0; /*在此发出应答或非应答信号 */ 76 else SDA=1; 77 _NOP();_NOP();_NOP(); 78 SCL=1; 79 _NOP();_NOP();_NOP();_NOP();_NOP(); 80 SCL=0; /*清时钟线,钳住I2C总线以便继续接收*/ 81 _NOP();_NOP(); 82 } 83 84 //AT2402的功能函数 85 /******************************************************************* 86 向有子地址器件发送多字节数据函数 87 函数原型: bit ISendStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no); 88 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件 89 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。 90 如果返回1表示操作成功,否则操作有误。 91 注意: 使用前必须已结束总线。 92 ********************************************************************/ 93 bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) 94 { 95 unsigned char i; 96 97 Start_IIC(); /*启动总线*/ 98 Send_Byte(sla); /*发送器件地址*/ 99 if(ack==0) return(0); 100 Send_Byte(suba); /*发送器件字地址,存储单元的地址*/ 101 if(ack==0) return(0); 102 103 for(i=0;i<no;i++) 104 { 105 Send_Byte(*s); /*发送数据*/ 106 if(ack==0)return(0); 107 s++; 108 } 109 Stop_IIC(); /*结束总线*/ 110 111 return(1); 112 } 113 114 /******************************************************************* 115 向有子地址器件读取多字节数据函数 116 函数原型: bit RecndStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no); 117 功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件 118 地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。 119 如果返回1表示操作成功,否则操作有误。 120 注意: 使用前必须已结束总线。 121 ********************************************************************/ 122 bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) 123 { 124 unsigned char i; 125 126 Start_IIC(); /*启动总线*/ 127 Send_Byte(sla); /*发送器件地址*/ 128 if(ack==0) return(0); 129 Send_Byte(suba); /*发送器件子地址*/ 130 if(ack==0) return(0); 131 132 Start_IIC(); /*重新启动总线*/ 133 Send_Byte(sla+1); 134 if(ack==0) return(0); 135 for(i=0;i<no-1;i++) 136 { 137 *s=Rcv_Byte(); /*发送数据*/ 138 Ack_IIC(0); /*发送就答位*/ 139 s++; 140 } 141 *s=Rcv_Byte(); 142 Ack_IIC(1); /*发送非应答位*/ 143 Stop_IIC(); /*结束总线*/ 144 return 1; 145 }
标签:
原文地址:http://www.cnblogs.com/boyiliushui/p/4781360.html