|
- /****************************************************************
- AT24C前四位固定为1010 A1-A2由管脚电平默认接地,最后一位表示读写操作所以AT24C读地址0xa1 写地址0xa0
- 写AT24C02的时候从器件地址为10100 0000,(0xa0),读AT24C02的时候从器件地址为10100 0001,(0xa1)
- ***************************************************************/
- #include<reg51.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define AT24C02_ADDRESS 0xA0 //0xA0 1010 00000写地址
- uint Count;
- uint Set_Count;
- // unsigned int Count;
- // unsigned int Set_Count;
- uint Num_L;
- uint Num_H;
- uint num1;
- uint num2;
- char yiwei_Count;//移位计数
- sbit I2C_SCL= P1^6;
- sbit I2C_SDA= P1^7;
- sbit Start_Dianji=P3^0; //电机启动_dianji
- sbit forward=P3^1; //正转检测
- //sbit back=P3^1; //反转检测
- sbit run=P3^7; //运行信号
- sbit jia_up=P1^0;// 增加键
- sbit jian_down=P1^1;//减少键
- sbit yiwei_up=P1^2; //移位键
- sbit qingling=P1^3; //清零键
- uchar code ledcode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共阴数码管编码0-9
- uchar data Ledbuff[8]={1};//显示缓冲区
- #define I2CDelay_us(){_nop_();_nop_();_nop_();_nop_();}//voidI2CDelay_us
- /***********************
- AT24C初始化
- *************************/
- void I2C_init()
- {
- I2C_SCL=1;
- // I2CDelay_us(4);
- I2C_SDA=1;//首先确保SCL SDA都是高电平
- // I2CDelay_us(4);
-
- }
- /***********************
- 产生总线起始信号
- *************************/
- void I2C_Start(void )
- {
- I2C_SDA=1;//首先确保SCL SDA都是高电平
- // I2CDelay_us(5);
- I2C_SCL=1; //确保SCL高电平
- // I2CDelay_us(5);
- I2C_SDA=0;//先在SCL为高时拉低SDA,即为起始信号
- // I2CDelay_us(5);
- I2C_SCL=0; //在拉低 SCL,钳住I2C总线准备发送或接收数据
- }
- /***********************
- 产生总线停止信号:先拉低SDA在拉低SCL
- *************************/
- void I2C_Stop(void )
- {
- I2C_SDA=0;//首先确保SCL SDA都是低电平
- I2C_SCL=1; //先拉高 SCL
- I2C_SDA=1;//在拉高 SDA
- /*
- I2C_SCL=0;
- I2C_SDA=0;
- // I2CDelay_us(4);
- I2C_SCL=1;
- I2C_SDA=1;
- // I2CDelay_us(4);
- */
- }
- /*******************************************************************************
- *@brief I2C发送一个字节数据
- *@param Byte要发送的字节
- *@retval 无
- 起始信号后必须送一个从机地址(7)位,1-7位为要接收器件的地址,第八位读写位0发送1接收,第9位ACK应答位,
- 紧接着为第一个数据字节,然后一位应答位ACK后面继续第二个数据字节
- **********************************************************************************/
- void I2C_SendByte(unsigned char Byte)
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- I2C_SDA=Byte&(0x80>>i);
- I2C_SCL=1; //先拉高 SCL
- I2C_SCL=0; //SCL
- }
- }
- /***********************************************************************************************
- *@brief I2C读取 接收一个字节
- *@param 无
- *@retval 读取 接收到的一个字节数据
- ********************************************************************************************/
- unsigned char I2C_ReceiveByte(void)
- {
- unsigned char i,Byte=0x00;//
- I2C_SDA=1; //
- for(i=0;i<8;i++)
- {
- I2C_SCL=1; //先拉高 SCL
- if(I2C_SDA){Byte |= (0x80>>i); }
- I2C_SCL=0; //SCL
- }
- return Byte;
- }
- /*********************
- *@brief I2C发送应答Ack
- *@param AckBit应答位 0为应答(成功) 1为非应答(失败)
- *@retval 无
- ************************/
- void I2C_SendAck(unsigned char AckBit)
- {
- I2C_SDA=AckBit;
- I2C_SCL=1; //先拉高 SCL
- I2C_SCL=0; //SCL
- }
- /*********************
- *@brief I2C接收应答位
- *@param 无
- *@retval AckBit应答位 0为应答(成功) 1为非应答(失败)
- ************************/
- unsigned char I2C_ReceiveAck(void)
- {
- unsigned char AckBit;
- I2C_SDA=1;
- I2C_SCL=1; //先拉高 SCL
- AckBit=I2C_SDA;
- I2C_SCL=0; //SCL
- return AckBit; //返回值
- }
- /**********向AT24C写数据***********
- *@brief AT24C写入一个字节
- *@param WordAddress要写入字节的地址
- *@param Data要写入的数据
- *@retval无
- 写多字节时,写入一个字节。在写一个字节前,必须延时5ms
- ************************/
- void AT24C_WriteByte(unsigned char WordAddress,Data)
- {
- I2C_Start();//启动总线
- I2C_SendByte(AT24C02_ADDRESS);//发送写操作地址+写数据(0xa0)
- I2C_ReceiveAck(); //等待应答
- I2C_SendByte(WordAddress);//要写入的地址
- I2C_ReceiveAck(); //等待应答完成
- I2C_SendByte(Data); //要写入的数据,第一字节 ,第二字节注意:每个字节都回应一个应答位0,如果没有回应说明写入不成功
- I2C_ReceiveAck(); //等待完成 注意:每个字节都回应一个应答位0,如果没有回应说明写入不成功
- I2C_Stop(); //发送结束信号:停止总线
- }
- /************从AT24C中读出数据*********
- *@brief AT24C读取一个字节
- *@param WordAddress要读出字节的地址
- *@param 无
- *@retval要读出的数据
- ************************/
- unsigned char AT24C_ReadByte(unsigned char WordAddress) //void
- {
- unsigned char Data;
- I2C_Start(); //发送起始信号:启动总线
- I2C_SendByte(AT24C02_ADDRESS); //接上首字节,发送器件写操作地址+写数据(0xa0)这里写操作时维纶把所要读的数据地址AT24C02_ADDRESS通知读取哪个地址信息
- I2C_ReceiveAck(); //等待完成应答
- I2C_SendByte(WordAddress);//发送要读取内存的地址(WORD ADDRESS)
- I2C_ReceiveAck(); //等待应答完成
- I2C_Start();//在次启动总线
- I2C_SendByte(AT24C02_ADDRESS| 0x01); //对E2PROM进行读操作(0XA1)E2PROM会自动向主机发回数据,读取一个字节后回应一个应答位,后会继续传送下一个地址的数据0xa1
- I2C_ReceiveAck(); //等待完成
- Data= I2C_ReceiveByte(); //要读出的数据到Data
- I2C_SendAck(1); //等待完成::如果不想读了,就发送一个非应答位NAK(1),发送结束,停止总线
- I2C_Stop(); //停止总线
- return Data ;//返回值
- }
- /***********************************/
- void delayms(uint ms)
- {
- uchar k;
- while(ms--)
- {
- for(k = 0; k < 120; k++);
- }
- }
- void display() //显示程序display(uchar a,b,c,d,e) char i;
- {
- static unsigned char i = 0;
- switch(i)//使用多分支选择语句 i=count display 0x代表16进制
- {
- case(0):Ledbuff[7]=Set_Count/1000;break; //取设定千位字符送缓存
- case(1):Ledbuff[6]=Set_Count/100%10;break; //取设定百位字符送缓冲
- case(2):Ledbuff[5]=Set_Count/10%10;break; //取设定十位字符送缓冲
- case(3):Ledbuff[4]=Set_Count%10;break; //取设定个位字符送缓存
-
- case(4):Ledbuff[3]=Count/1000;break; //取计数千位字符送缓存
- case(5):Ledbuff[2]=Count/100%10;break;
- case(6):Ledbuff[1]=Count/10%10;break;
- case(7):Ledbuff[0]=Count%10;break;
- }
- P0=0x00; //消阴:段码全部低电平关闭
- P2=~(0x01<<i); //P2位选,左移i位取反
- P0=ledcode[Ledbuff[i]]; //P0字符刷新显示
- delayms(1); //显示2MS
- i=++i%8; //自加1
- }
- /*
- void Adjust(void) //按键设定匝数,用P2.4个位-P2.7(千位)前四位数码管显示
- {
-
- if(yiwei_up==0) //移位按键按下
- {
- while(!yiwei_up); //等待移位按键松开
- if(yiwei_Count<3) //移位
- {
- yiwei_Count +=1;
- }
- else //如果>3
- {
- yiwei_Count=0; //设定位在个位
- }
- }
-
- if(Set_Count>=0 && Set_Count<9999)//最大9999yiwei_Count=0; //设定加 jia_up==0
- {
- if (jia_up==0) //增加按键按下
- {
- while(!jia_up);//等待加按键松开
- {
- if (yiwei_Count==0) //
- {
- Set_Count += 1; //设定+1
- }
- if (yiwei_Count==1&&Set_Count<9990)
- {
- Set_Count += 10; //设定+1
- }
- if (yiwei_Count==2&&Set_Count<9900)
- {
- Set_Count += 100; //设定+1
- }
- if (yiwei_Count==3 && Set_Count<9000)
- {
- Set_Count += 1000; //设定+1
- }
- }
- }
- if (jian_down==0) //减少按键按下
- {
- while(!jian_down);//等待按键松开
- {
- if (yiwei_Count==0&&Set_Count>1) // 移位在个位
- {
- Set_Count -= 1; //设定+1
- }
- if (yiwei_Count==1&&Set_Count>9)
- {
- Set_Count -= 10; //设定+1
- }
- if (yiwei_Count==2 && Set_Count>99)
- {
- Set_Count -= 100; //设定+1
- }
- if (yiwei_Count==3 && Set_Count>999)
- {
- Set_Count -= 1000; //设定+1
- }
- }
- //写入数据
- /* AT24C_WriteByte(0,Set_Count%256);
- delayms(5) ; //显示2MS
- AT24C_WriteByte(1,Set_Count/256);
- delayms(5); //显示2MS
- }
- */
- /**********************************************************
- 主函数
- **********************************************************/
- void main()
- {
- I2C_init();
- // init(); //初始化24C02
- // num=5678; //num为小于等于65535的整数。 */
- Set_Count=1234;
- Num_H =Set_Count/256; //1234/256就简单了,高位:取的是整数倍,不被整除的部分自然就被剔除了1234/256=4
- Num_L =Set_Count%256; //%256是取余,低位:也就是你把前面的数值除以256取余,商跟除数则是256的整数倍部分1234%256=210 ;4*256=1024 %256=1234-1024=210
- AT24C_WriteByte(0,Num_L);
- delayms(10); //显示2MS
- AT24C_WriteByte(1,Num_H );
- delayms(10); //显示2MS
- num1=AT24C_ReadByte(0); //用地址0单元存储num十六进制表示时的低两位
- num2=AT24C_ReadByte(1); //用地址0单元存储num十六进制表示时的高两位
- Count=num2*256+num1;
- //写入24C02
- // AT24C_WriteByte(0,Set_Count%256); //低8位写入0x00
- /*
- AT24C_WriteByte(0,120); //低8位写入0x00
- delayms(5); //显示2MS
- // AT24C_WriteByte(1,Set_Count/256); //高8位写入0x01
- AT24C_WriteByte(1,0); //高8位写入0x01
- delayms(5); //显示2MS
- //读取数据 /*
- Num_L = AT24C_ReadByte(0);
- Num_H |=AT24C_ReadByte(1)<<8;
- Count= Num_H+Num_L;
- */
- while(1)
- {
- /* Adjust();
- if (jia_up==0) //增加按键按下
- {
- while(!jia_up);//等待加按键松开
- {
- Set_Count += 1; //设定+1
- }
- }
- if (jian_down==0) //减少按键按下
- {
- while(!jian_down);//等待按键松开
- {
- Set_Count -= 1; //设定+1
- }
- }
- if(yiwei_up==0) //保存按键按下,向AT24C写入数据
- {
- while(!yiwei_up); //等待移位按键松开
- {
- AT24C_WriteByte(0,Set_Count%256);
- delayms(6) ; //显示2MS
- AT24C_WriteByte(1,Set_Count/256);
- delayms(6); //显示2MS
- }
- }
-
- if( qingling==0) //读取按键按下
- {
- while(! qingling); //等待移位按键松开
- {
- Count=AT24C_ReadByte(0);
- Count |=AT24C_ReadByte(1)<<8;
- // Count = Num_H+Num_L;
- }
- } */
- display();
- }
- }
复制代码 |
|