STM32 IIC--EEPROM实验

STM32 IIC--EEPROM实验_第1张图片
STM32 IIC--EEPROM实验_第2张图片
STM32 IIC--EEPROM实验_第3张图片
STM32 IIC--EEPROM实验_第4张图片
STM32 IIC--EEPROM实验_第5张图片
STM32 IIC--EEPROM实验_第6张图片
STM32 IIC--EEPROM实验_第7张图片
STM32 IIC--EEPROM实验_第8张图片
STM32 IIC--EEPROM实验_第9张图片

本章所要实现的功能是:首先检测 AT24C02 芯片是否存在,如果存在则输出 提示信息,然后通过按键 KEY_UP 和 KEY1 控制 AT24C02 数据读写,并输出写入和 读取的数据信息,最后让 DS0 指示灯闪烁提示系统正常运行。程序框架如下: (1)使能所用 GPIO 端口时钟,初始化 GPIO (2)使用软件模拟 I2C 通信时序,包含起始和停止信号、应答信号等 (3)编写 AT24C02 读写函数 (4)编写主函数

iic.h+iic.c

#ifndef _i2c_H
#define _i2c_H

#include "system.h"

#define IIC_SCL_PORT GPIOB
#define IIC_SCL_PIN  GPIO_Pin_6
#define IIC_SCL_RCC  RCC_APB2Periph_GPIOB

#define IIC_SDA_PORT GPIOB
#define IIC_SDA_PIN  GPIO_Pin_7
#define IIC_SDA_RCC  RCC_APB2Periph_GPIOB


#define IIC_SCL PBout(6)      
#define IIC_SDA PBout(7)      
#define READ_SDA PBin(7)      
void IIC_Init();
void IIC_Send_Byte(u8 txd);//要发送的字节
u8 IIC_Read_Byte(u8 ack);
u8 IIC_Wait_Ack();
void IIC_Start();
void IIC_Stop();
void  IIC_Ack();
void  IIC_NAck();
#endif
#include "i2c.h"
#include "SysTick.h"
void IIC_Init()//用io口来模拟iic时序
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(IIC_SCL_RCC, ENABLE);
    RCC_APB2PeriphClockCmd(IIC_SDA_RCC, ENABLE);

    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin=IIC_SCL_PIN ;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(IIC_SCL_PORT,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
    GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);

    IIC_SCL=1;
    IIC_SDA=1;

}
void SDA_OUT()//SDA输出模式
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//输出模式
    GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN ;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);

}
void SDA_IN()//输入模式
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//输入模式
    GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN ;
    GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);


}
void IIC_Start()//起始信号
{
    SDA_OUT();
    IIC_SCL=1;
    IIC_SDA=1;
    delay_us(5);//scl sda基本上时纳秒级的
    IIC_SDA=0;
    delay_us(5);
    IIC_SCL=0;//使设备开始工作
}
void IIC_Stop()//停止信号
{
    SDA_OUT();//sda线输出
    IIC_SCL=0;
    IIC_SDA=0;
    IIC_SCL=1;
    delay_us(5);//scl sda基本上时纳秒级的
    IIC_SDA=1;//设备停止工作
    delay_us(5);
}
void  IIC_Ack()//应答信号
{
    SDA_OUT();
    IIC_SCL=0;
    IIC_SDA=0;
    delay_us(2);
    IIC_SCL=1;
}
void  IIC_NAck()//非应答信号
{
    SDA_OUT();
    IIC_SCL=0;
    IIC_SDA=1;
    delay_us(2);
    IIC_SCL=1;
}
void IIC_Send_Byte(u8 txd)//要发送的字节
{
    u8 i=0;
    SDA_OUT();
    IIC_SCL=0;//只有时钟低电平,数据线才能进行操作 
    for(i=0;i<8;i++)//串行通信,一位一位的穿
    {
        if((txd&0x80)>0)//从高位开始传输
            IIC_SDA=1;//第八位为1,则发送高电平
        else
            IIC_SDA=0;//第八位为0,则发送低电平
        txd<<=1;
        delay_us(2);
        IIC_SCL=1;//为了传输数据稳定
        delay_us(2);
        IIC_SCL=0;//只有时钟低电平,数据线才能进行操作 
    }

}
u8 IIC_Read_Byte(u8 ack)//读取字节函数,ack为应答信号
{
    u8 i=0;
    u8 rec_data=0;
    SDA_IN();
    for(i=0;i<8;i++)
    {
        IIC_SCL=0;//从机数据传输
        delay_us(2);
        IIC_SCL=1;//只有高电平的时候,数据才是稳定的,才可以读取
        rec_data<<=1;//因为从传输的数据最高位读取,所以要从rec的最低位左移
        if(READ_SDA)rec_data++;
        delay_us(1);
    }
    if(!ack)//传输完一个字节之后在如果不应答就结束,否则继续传输
        IIC_NAck();
    else
        IIC_Ack();
    return rec_data;
}
u8 IIC_Wait_Ack()//等待从机的应答信号0成功,1失败
{
    u8 temptime=0;
    SDA_IN();
    IIC_SCL=1;//只有高电平的时候,数据才是稳定的,才可以读取
  delay_us(1);
    while(READ_SDA)
    {
        temptime++;
        if(temptime>250)
        {
            IIC_Stop();//停止信号
            return 1;
        }
    }
    IIC_SCL=0;//等待应答成功后,需要对从机进行数据间的传输
    return 0;
}

at24cxx.h+at24cxx.c

#ifndef _at24cxx_H
#define _at24cxx_H

#include "system.h"
#include "i2c.h"
void AT24CXX_Init();
void AT24CXX_WriteOneByte(u8 WriteAddr,u8 dat);
u8 AT24CXX_ReadOneByte(u8 ReadAddr);
u8 AT24CXX_Check();
#endif
#include "at24cxx.h"
#include "SysTick.h"
void AT24CXX_Init()
{
    IIC_Init();
    
}
void AT24CXX_WriteOneByte(u8 WriteAddr,u8 dat)//发送完一个字节就结束
    //at24c02只能存256个字节,所以用u8
{
    IIC_Start();
    IIC_Send_Byte(0XA0);
    IIC_Wait_Ack();
    IIC_Send_Byte(WriteAddr);
    IIC_Wait_Ack();
    IIC_Send_Byte(dat);
    IIC_Wait_Ack();
    IIC_Stop();
    delay_ms(10);
}
u8 AT24CXX_ReadOneByte(u8 ReadAddr)//读取一个字节
{
    u8 temp=0;
    IIC_Start();
    IIC_Send_Byte(0XA0);
    IIC_Wait_Ack();
    IIC_Send_Byte(ReadAddr%256);//看开发原理图,随机读
    IIC_Wait_Ack();
    IIC_Start();
    IIC_Send_Byte(0XA1);
    IIC_Wait_Ack();
    temp=IIC_Read_Byte(0);//读完一个字节就结束
    IIC_Stop();
    return temp;
}
u8 AT24CXX_Check()//检测AT124CXX是否读写正常 0正常,1不正常
{
    u8 temp=0;
    temp=AT24CXX_ReadOneByte(255);
    if(temp==0x36)return 0;
    else
    { 
        AT24CXX_WriteOneByte(255,0x36);
        temp=AT24CXX_ReadOneByte(255);
        if(temp==0x36)return 0;
    }
    return 1;
}

main.c

#include "stm32f10x.h"
#include "led.h"
#include "system.h"
#include "SysTick.h"
#include "beep.h"
#include "key.h"
#include "exti.h"
#include "time.h"
#include "pwm.h"
#include "usart.h"
#include "stdio.h"
#include "iwdg.h"
#include "wwdg.h"
#include "input.h"
#include "touch_key.h"
#include "wkup.h"
#include "adc.h"
#include "adc_temp.h"
#include "lsens.h"
#include "dac.h"
#include "dma.h"
#include "rtc.h"
#include "at24cxx.h"
#include "i2c.h"
int main()
{
    u8 i=0;
    u8 key=0;
    u8 k=0;
    KEY_Init();
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置优先级分组
  SysTick_Init(72);
    LED_Init();
    AT24CXX_Init();
    USART1_Init(115200);//波特率115200
    while(AT24CXX_Check())
    {
        printf("读写失败,AT24C02不正常\r\n");
        delay_ms(500);
    }
    printf("AT24C02正常\r\n");
    while(1)
    {
        key=KEY_Scan(0);
        if(key==KEY_UP_PRESS)
        {
            k++;
            if(k>255)k=255;
            AT24CXX_WriteOneByte(0,k);
            printf("写入的数据是:%d\r\n",k);
        }
        else if(key==KEY1_PRESS)
        {
            k=AT24CXX_ReadOneByte(0);
            printf("读取的数据是:%d\r\n",k);
        }
        i++;
        if(i%20==0)LED1=!LED1;
        delay_ms(10);
    }
    
}

你可能感兴趣的:(STM32K开发,stm32,单片机,嵌入式硬件,嵌入式实时数据库)