4691|2

45

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

有谁用过io口读写e2prom啊,求指导 [复制链接]

有哪位大侠用过io口读写e2prom啊  跪求指导 感激不敬
此帖出自stm32/stm8论坛

最新回复

#include"myiic.h"                         //包含头文件        #include"delay.h"                         //包含延时头文件 void IIC_Init(void)                         //IIC初始化子程序 { RCC->APB2ENR|=1CRH|=0X00033000;             //设置IO口C 11,12 位状态寄存器为推挽输出 GPIOC->ODR|=37;             //数据线值等于TXD(字节)与上10000000,然后右移7位,(相当与取第8位)   txd  详情 回复 发表于 2012-3-3 18:17
点赞 关注
 

回复
举报

2

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
#include"myiic.h"                         //包含头文件       
#include"delay.h"                         //包含延时头文件
void IIC_Init(void)                         //IIC初始化子程序
{
RCC->APB2ENR|=1<<4;                     //使能IO口C时钟
GPIOC->CRH&=0XFFF00FFF;             //清除IO口C 11,12 位状态寄存器
GPIOC->CRH|=0X00033000;             //设置IO口C 11,12 位状态寄存器为推挽输出
GPIOC->ODR|=3<<11;                         //设置IO口C 11位为上拉输出
}

void IIC_Start(void)                     //IIC开始信号子程序
{
SDA_OUT();                                     //调用IO口状态寄存器变更子程序,使IO口为输出
IIC_SDA=1;                                     //数据线输出为高
IIC_SCL=1;                                     //时钟线输出为高
delay_us(4);                                 //延时4微秒
IIC_SDA=0;                                     //数据线输出为低
delay_us(4);                                   //延时4微秒
IIC_SCL=0;                                     //时钟线输出为低
}

void IIC_Stop(void)                         //IIC停止信号子程序
{
SDA_OUT();                                     //调用IO口状态寄存器变更子程序,使IO口为输出
IIC_SCL=0;                                     //数据线输出为低
IIC_SDA=0;                                     //时钟线输出为低
delay_us(4);                                 //延时4微秒
IIC_SCL=1;                                     //时钟线输出为高                       
IIC_SDA=1;                                     //数据线输出为高
delay_us(4);                                 //延时4微秒
}

u8 IIC_Wait_Ack(void)                     //IIC等待应答信号子程序
{
u8 ucErrTime=0;                         //数据类型声明,初始化为0
SDA_IN();                                     //调用IO口状态寄存器变更子程序,使IO口为输入
IIC_SDA=1;delay_us(1);                     //数据线拉高,延时1微秒
IIC_SCL=1;delay_us(1);                     //时钟线拉高,延时1微秒
  while(READ_SDA)                         //等待读取数据
  {
    ucErrTime++;                         //时间累加
    if(ucErrTime>250)                     //如果时间大于250
      {
       IIC_Stop();                         //调用IIC停止子函数
        return 1;                         //程序返回值1
       }
   }
  IIC_SCL=0;                                 //时钟线为低
  return 0;                                     //返回值0
}

void IIC_Ack(void)                         //IIC应答子程序
{
IIC_SCL=0;                                     //时钟线拉低
SDA_OUT();                                     //调用IO口状态寄存器变更子程序,使IO口为输出
IIC_SDA=0;                                     //数据线输出为低
delay_us(2);                                 //延时2微秒
IIC_SCL=1;                                     //时钟线输出为高
delay_us(2);                                 //延时2微秒
IIC_SCL=0;                                     //时钟线输出为低
}


void IIC_NAck(void)                         //IIC未应答子程序
{
  IIC_SCL=0;                                 //时钟线拉低
  SDA_OUT();                                 //调用IO口状态寄存器变更子程序,始IO口为输出
  IIC_SDA=1;                                 //数据线输出为高
  delay_us(2);                                 //延时2微秒
  IIC_SCL=1;                                 //时钟线输出为高
  delay_us(2);                                 //延时2微秒
  IIC_SCL=0;                                 //时钟线输出为低
}

void IIC_Send_Byte(u8 txd)             //IIC发送字节子程序
{
u8 t;                                             //数据类型声明
SDA_OUT();                                     //调用IO口状态寄存器变更子程序,使IO口为输出
IIC_SCL=0;                                     //时钟线拉低
for(t=0;t<8;t++)                         //循环执行8次以下程序
{
  IIC_SDA=(txd&0x80)>>7;             //数据线值等于TXD(字节)与上10000000,然后右移7位,(相当与取第8位)
  txd<<=1;                                   //TXD(8位字节)左移1位
  delay_us(2);                                 //延时
  IIC_SCL=1;                                 //时钟线输出为高
  delay_us(2);                                 //延时
  IIC_SCL=0;                                 //时钟线输出为低
  delay_us(2);                                 //延时
  }
}

u8 IIC_Read_Byte(unsigned char ack) //IIC读取字节子程序
{
unsigned char i,receive=0;             //字符型变量i receive 声明及初始化
SDA_IN();                                     //调用IO口状态寄存器变更子程序,使IO口为输入
for(i=0;i<8;i++)                         //循环执行8次以下程序
{
  IIC_SCL=0;                                 //时钟线拉低
  delay_us(2);                                 //延时
  IIC_SCL=1;                                   //时钟线输出为高
  receive<<=1;                                 //接收数据左移
  if(READ_SDA) receive++;             //如果读取到数据,原数据值左移后加1,读取到的新值
  delay_us(1);                                 //延时
  }
  if(!ack)                                     //如果未收到应答信号
      IIC_NAck();                         //调用未收到应答信号子程序
  else                                             //否则
      IIC_Ack();                         //调用应答信号子程序
  return receive;                         //返回接收的数据值
}
//////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _MYIIC_H                                                        //如果未定义了MYIIC.H
#define _MYIIC_H                                                //定义MYIIC.H
#include"sys.h"                                                        //包含SYS头文件
#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}        //预定义数据输入子函数,IO口状态寄存器设置
#define SDA_OUT(){GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}        //预定义数据输入子函数,IO口状态寄存器设置
#define IIC_SCL  PCout(12)                                        //定义时钟线输出对应IO口
#define IIC_SDA  PCout(11)                                        //定义数据线输出对应IO口
#define READ_SDA PCin(11)                                        //定义读取数据线对应IO口

void IIC_Init(void);                                                //IIC初始化子程序声明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Send_Byte(u8 txd);                                        //IIC发送字节子程序声明
u8 IIC_Read_Byte(unsigned char ack);                                //IIC读取字节子程序声明
u8 IIC_Wait_Ack(void);                                                //IIC等待应答子程序声明
void IIC_Ack(void);                                                //IIC应答子程序声明
void IIC_NAck(void);                                                //IIC未应答子程序声明

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);                //子程序声明
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);                                //子程序声明
#endif                                                                //结束if
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#include"24CXX.h"                                        //包含头文件
#include"delay.h"                                        //包含延时头文件
#include"myiic.h"

void AT24CXX_Init(void)                                        //24cxx初始化子程序
{                               
  IIC_Init();                                                //调用IIC初始化子程序
}
u8 AT24CXX_ReadOneByte(u16 ReadAddr)                        //读取一个字节子程序(参数是地址)
{
  u8 temp=0;                                                //临时变量声明,8位,整数

    IIC_Start();                                                //声明IIC开始子程序
         if( EE_TYPE>AT24C16 )                                //如果型号大于24c16的容量
           {
            IIC_Send_Byte(0xa0);                        //调用发送字节程序发送0xa0
            IIC_Wait_Ack();                                //调用等待应答信号子程序
            IIC_Send_Byte(ReadAddr>>8);                //调用发送字节子程序,地址右移8位
            IIC_Wait_Ack();                                //等待应答子程序
            }
          else IIC_Send_Byte(0xa0+((ReadAddr/256)<<1)); //否则 调用IIC发送字节程序(0xa0加读取地址除以256,左移1位)
       IIC_Wait_Ack();                                        //等待应答
       IIC_Send_Byte(ReadAddr%256);                        //发送低8位
       IIC_Wait_Ack();                                        //等待应答
       IIC_Start();                                        //开始信号
       IIC_Send_Byte(0xa1);                                //发送0xa1
       IIC_Wait_Ack();                                        //等待应答
       temp=IIC_Read_Byte(0);                                //临时变量赋值为读取的字节
       IIC_Stop();                                        //停止信号
       return temp;                                        //返回临时变量
}

void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)        //AT24CXX写一字节程序(参数为,地址(16位),字节(8位)
{
IIC_Start();                                        //开始信号
  if(EE_TYPE>AT24C16)                                        //如果容量大于at24c16
        {
        IIC_Send_Byte(0XA0);                                 //发送写命令
        IIC_Wait_Ack();                                        //等待应答
        IIC_Send_Byte(WriteAddr>>8);                        //发送高地址
        IIC_Wait_Ack();                                        //等待应答
        }
        else                                                //否则
        {
        IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));         //发送器件地址0XA0,写数据
        }
        IIC_Wait_Ack();                                        //等待应答
        IIC_Send_Byte(WriteAddr%256);                         //发送低地址
        IIC_Wait_Ack();                                        //等待应答
        IIC_Send_Byte(DataToWrite);                        //发送字节
        IIC_Wait_Ack();                                        //等待应答
    IIC_Stop()        ;                                                //产生一个停止信号
        delay_ms(10);                                        //延时       

}


void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len) //写多个字节(写入起始地址,待写数据,数据长度)
{
u8 t;                                                                //变量声明
for(t=0;t         {
        AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);//写字节,地址加t,待写数据右移 8*T与上 11111111
        }
}


u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)                        //读多个字节(读出起始地址,读出数据长度)
{
        u8 t;                                                        //数据类型声明
        u32 temp=0;                                                //临时变量声明
        for(t=0;t         {
        temp<<=8;                                                //temp的新值等于旧值左移8位(相当于16位数据低8位移到高8位)
        temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);                //temp的新值等于读取地址加LEN-T-1位的数据
        }
        return temp;                                                //返回tep的值

}


u8 AT24CXX_Check(void)                                                //芯片确认子程序
{
        u8 temp;                                                //临时变量声明
        temp=AT24CXX_ReadOneByte(255);  //避免每次开机都写AT24CXX //读取地址255的数据
        if(temp==0X55)return 0;                                        //如果数据等于0x55则返回0
        else                                                        //否则 排除第一次初始化的情况                       
        {
        AT24CXX_WriteOneByte(255,0X55);                                //在255地址写入0x55                       
        temp=AT24CXX_ReadOneByte(255);                                //再次读地址255数据
        if(temp==0X55)return 0;                                        //如果为0x55返回0
        }
return 1;                                                        //返回值1
}

void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)        //读取(16位地址,8位指针,16位需要读取的数量)
{
        while(NumToRead)                                        //循环读取指定书目的数据
        {
        *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);                //指向存储区(加1循环)数值等于读取字节地址(加1循环)的数据
        NumToRead--;                                                //需要读取的数目递减
        }
}

void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)        //
{
        while(NumToWrite--)
        {
        AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
        WriteAddr++;
        pBuffer++;
        }
}
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef __24CXX_H
#define __24CXX_H
#include "myiic.h"

#define AT 127
#define AT24C02 255
#define AT24C04 511
#define AT24C08 1023
#define AT24C16 2047
#define AT24C32 4095
#define AT24C64 8191
#define AT24C128 16383
#define AT24C256 32767

#define EE_TYPE AT24C02
u8 AT24CXX_ReadOneByte(u16 ReadAddr);                               //指定地址读取
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite);            //指定地址写入一个

void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);    //指定地址开始写入指定长度的数据

u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len);                       //指定地址开始读取指定长度数据

void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);       //从指定地址开始写入指定长度的数据

void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);          //从指定地址开始读出指定长度的数据

u8 AT24CXX_Check(void);         //检查器件
                                 
void AT24CXX_Init(void);         //初始化IIC

#endif
///////////////////////////////////////////////////////////////////////////////////////////
以上是STM32  IO口模拟IIC与EEROM通讯部分代码
源自正点原子的例程
此帖出自stm32/stm8论坛
 
 

回复

45

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

回复 沙发 mackyming 的帖子

哥们 虽然我已经写好了 但是还要谢谢你
此帖出自stm32/stm8论坛
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表