AT24C02数据存储+普中51单片机+江科大自化协

发布时间:2024-08-08  

1 系统原理图

2 现象

 

当按键Key1被按下时,LCD1602显示的数值加1,每按下一次,自增1;当按键Key2被按下时,LCD1602显示的数值自减1;当按键Key3被按下时,单片机将LCD1602显示的数值保存在AT24C02中,掉电不丢失;当按键Key4被按下时,单片机从AT24C02中读取数据,并显示在LCD1602。


3 参考程序


(1)主函数


#include

#include "delayms.h"

#include "key.h"

#include "lcd1602.h"

#include "at24c02.h"


unsigned char KeyNum;

unsigned int Num;


void main()

{

    LCD1602_Init();

    LCD1602_ShowNum(1,1,Num,5);

    while(1)

    {

        KeyNum=key();

        if(KeyNum==1)    //K1按键,Num自增

        {

            Num++;

            LCD1602_ShowNum(1,1,Num,5);

        }

        if(KeyNum==2)    //K2按键,Num自减

        {

            Num--;

            LCD1602_ShowNum(1,1,Num,5);

        }

        if(KeyNum==3)    //K3按键,向AT24C02写入数据

        {

            AT24C02_WriteByte(0,Num%256);

            delayms(5);

            AT24C02_WriteByte(1,Num/256);

            delayms(5);

            LCD1602_ShowString(2,1,"Write is OK");

            delayms(1000);

            LCD1602_ShowString(2,1,"           ");

        }

        if(KeyNum==4)    //K4按键,从AT24C02读取数据

        {

            Num=AT24C02_ReadByte(0);

            Num|=AT24C02_ReadByte(1)<<8;

            LCD1602_ShowNum(1,1,Num,5);

            LCD1602_ShowString(2,1,"Read is OK");

            delayms(1000);

            LCD1602_ShowString(2,1,"           ");

        }

    }

}


(2)I2C函数


#ifndef _i2c_h_

#define _i2c_h_


void I2C_Start(void);

void I2C_Stop(void);

void I2C_SendByte(unsigned char Byte);

unsigned char I2C_ReceiveByte(void);

void I2C_SendAck(unsigned char AckBit);

unsigned char I2C_ReceiveAck(void);

    

#endif


#include


sbit I2C_SCL=P2^1;

sbit I2C_SDA=P2^0;


/**

  * @brief  I2C通信开始

  * @param  无

  * @retval 无

  */

void I2C_Start(void)

{

    I2C_SCL=1;    //空闲状态

    I2C_SDA=1;    //空闲状态

    I2C_SDA=0;

    I2C_SCL=0;

}


/**

  * @brief  I2C通信结束

  * @param  无

  * @retval 无

  */

void I2C_Stop(void)

{

    I2C_SDA=0;    

    I2C_SCL=1;    //回到空闲状态

    I2C_SDA=1;    //回到空闲状态

}


/**

  * @brief  I2C主机向从机发送一个字节,SCL为同步信号,低电平写数据

  * @param  Byte 要发送的字节

  * @retval 无

  */

void I2C_SendByte(unsigned char Byte)

{

    unsigned char i;

    for(i=0;i<8;i++)            //一个字节,8bit

    {

        I2C_SDA=Byte&(0x80>>i);    //SCL为低电平,主机为发送器,写数据

        I2C_SCL=1;                //SCL为高电平,从机为接收器,读数据

        I2C_SCL=0;                //时序要求,51单片机速度比较慢

    }

}


/**

  * @brief  I2C主机接收从机一个字节,SCL为同步信号,高电平读数据

  * @param  无

  * @retval 接收到的一个字节数据

  */

unsigned char I2C_ReceiveByte(void)

{

    unsigned char i,Byte=0x00;

    I2C_SDA=1;                //主机释放数据线SDA

    for(i=0;i<8;i++)

    {

        I2C_SCL=1;            //主机作为接收器

        if(I2C_SDA) Byte|=(0x80>>i);    //读数据

        I2C_SCL=0;            //从机作为发送器,写数据

    }    

    return Byte;

}


/**

  * @brief  I2C主机发送应答

  * @param  AckBit 应答位,0为应答,1为非应答

  * @retval 无

  */

void I2C_SendAck(unsigned char AckBit)

{

    I2C_SDA=AckBit;

    I2C_SCL=1;

    I2C_SCL=0;

}


/**

  * @brief  I2C主机接收应答位

  * @param  无

  * @retval 接收到的应答位,0为应答,1为非应答

  */

unsigned char I2C_ReceiveAck(void)

{

    unsigned char AckBit;

    I2C_SDA=1;

    I2C_SCL=1;

    AckBit=I2C_SDA;

    I2C_SCL=0;

    return AckBit;

}


(3)AT24C02函数


#ifndef _at24c02_h_

#define _at24c02_h_


void AT24C02_WriteByte(unsigned char WordAddress,Data);

unsigned char AT24C02_ReadByte(unsigned char WordAddress);

    

#endif


#include

#include "i2c.h"


#define AT24C02_ADDRESS 0xA0


/**

  * @brief  AT24C02写入一个字节

  * @param  WordAddress 要写入字节的地址

  * @param  Data 要写入的数据

  * @retval 无

  */

void AT24C02_WriteByte(unsigned char WordAddress,Data)

{

    I2C_Start();

    I2C_SendByte(AT24C02_ADDRESS);

    I2C_ReceiveAck();

    I2C_SendByte(WordAddress);

    I2C_ReceiveAck();

    I2C_SendByte(Data);

    I2C_ReceiveAck();

    I2C_Stop();

}


/**

  * @brief  AT24C02读取一个字节

  * @param  WordAddress 要读出字节的地址

  * @retval 读出的数据

  */

unsigned char AT24C02_ReadByte(unsigned char WordAddress)

{

    unsigned char Data;

    I2C_Start();

    I2C_SendByte(AT24C02_ADDRESS);

    I2C_ReceiveAck();

    I2C_SendByte(WordAddress);

    I2C_ReceiveAck();

    

    I2C_Start();

    I2C_SendByte(AT24C02_ADDRESS|0x01);

    I2C_ReceiveAck();

    Data=I2C_ReceiveByte();

    I2C_SendAck(1);

    I2C_Stop();

    return Data;

}


(4)LCD1602函数


#ifndef __LCD1602_H__

#define __LCD1602_H__

    

    void LCD1602_WriteCommand(unsigned char Command);

    void LCD1602_WriteData(unsigned char Data);


    void LCD1602_Init(void);

    void LCD1602_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char);

    void LCD1602_ShowString(unsigned char Line,unsigned char Column,unsigned char *String);

    void LCD1602_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

    void LCD1602_ShowSignedNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

    void LCD1602_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

    void LCD1602_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

    

#endif


#include

#include "intrins.h"


//引脚配置,硬件原理图,普中A2

sbit LCD1602_RS = P2^6;

sbit LCD1602_RW = P2^5;

sbit LCD1602_E  = P2^7;

#define LCD1602_DATAPORT P0



/**

  * @brief  LCD1602延时函数

  * @param  xms=1, 延时1ms

  * @retval 无

  */

void LCD1602_Delayms(unsigned char xms)        //@11.0592MHz

{

    unsigned char i, j,k;


    for(k=0;k    {

        _nop_();

        i = 2;

        j = 199;

        do

        {

            while (--j);

        } while (--i);

    }


}


/**

  * @brief  LCD1602写命令,时序图

  * @param  Command 要写入的命令

  * @retval 无

  */

void LCD1602_WriteCommand(unsigned char Command)

{

    LCD1602_RS = 0;

    LCD1602_RW = 0;

    LCD1602_DATAPORT  = Command;

    LCD1602_E  = 1;

    LCD1602_Delayms(1);    //延时1ms

    LCD1602_E  = 0;

    LCD1602_Delayms(1);    //延时1ms

}


/**

  * @brief  LCD1602写数据,时序图

  * @param  Data 要写入的数据

  * @retval 无

  */

void LCD1602_WriteData(unsigned char Data)

{

    LCD1602_RS = 1;

    LCD1602_RW = 0;

    LCD1602_DATAPORT  = Data;

    LCD1602_E  = 1;

    LCD1602_Delayms(1);    //延时1ms

    LCD1602_E  = 0;

    LCD1602_Delayms(1);    //延时1ms

}


/**

  * @brief  LCD1602初始化函数

  * @param  无

  * @retval 无

  */

void LCD1602_Init(void)

{

    LCD1602_WriteCommand(0x38);    //0011_1000 功能设置,设置16x2显示,5x7点阵,8位数据接口

    LCD1602_WriteCommand(0x0C);    //0000_1100 显示开关控制,显示开,光标关,闪烁关    

    LCD1602_WriteCommand(0x06);    //0000_0110 输入方式设置,数据写后,AC自动加一,画面不动

    LCD1602_WriteCommand(0x01);    //0000_0001 清屏,数据指针清零、所有显示清零

}

/**

  * @brief  LCD1602设置光标位置

  * @param  Line 行位置,范围:1~2

  * @param  Column 列位置,范围:1~16

  * @retval 无

  */

void LCD1602_SetCursor(unsigned char Line,unsigned char Column)

{

    if(Line == 1)

    {

        LCD1602_WriteCommand(0x80|(Column-1)); //设置要存入数据的DDROM地址,第一行地址

    }

    else

    {

        LCD1602_WriteCommand(0x80|(Column-1)+0x40); //设置要存入数据的DDROM地,第二行地址

    }

}

    


/**

  * @brief  在LCD1602指定位置上显示一个字符

  * @param  Line 行位置,范围:1~2

  * @param  Column 列位置,范围:1~16

  * @param  Char 要显示的字符

  * @retval 无

  */

void LCD1602_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)

{

    LCD1602_SetCursor(Line,Column);

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>