OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6300|回复: 12

关于通过I2C向AT24C02写数字的问题

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-4-1
在线时间
2 小时
发表于 2016-4-2 21:34:07 | 显示全部楼层 |阅读模式
1金钱
新人求助!
原子哥的I2C实验中往AT24C02中写的是常量字符型数组,我现在想往24C02中写入动态数字怎么办,想做一个里程表的掉电储存模块。
我自己按自己的理解试着改了好几次,都没有成功。test.c中注释修改的地方是我自己最后一次尝试改过的地方
求原子哥,各路大神帮我改一改写数字和读数字的程序!感激不尽
文件24cxx.c


#include "24cxx.h"
#include "delay.h"                                                                                  
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK MiniSTM32开发板
//24CXX驱动 代码(适合24C01~24C512)                  
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2014/3/9
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////

//初始化IIC接口
void AT24CXX_Init(void)
{
        IIC_Init();
}
//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址  
//返回值  :读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{                                  
        u8 temp=0;                                                                                                                                                               
    IIC_Start();  
        if(EE_TYPE>AT24C16)
        {
                IIC_Send_Byte(0XA0);           //发送写命令     起始地址改变的话修改0XA0
                IIC_Wait_Ack();
                IIC_Send_Byte(ReadAddr>>8);//发送高地址            
        }else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址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;
}
//在AT24CXX指定地址写入一个数据
//WriteAddr  :写入数据的目的地址   
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{                                                                                                                                                                                          
    IIC_Start();  
        if(EE_TYPE>AT24C16)
        {
                IIC_Send_Byte(0XA0);            //发送写命令
                IIC_Wait_Ack();
                IIC_Send_Byte(WriteAddr>>8);//发送高地址          
        }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);        //对于EEPROM器件,每写一次要等待一段时间,否则写失败!         
}
//在AT24CXX里面的指定地址开始写入长度为Len的数据
//该函数用于写入16bit或者32bit的数据.
//WriteAddr  :开始写入的地址  
//DataToWrite:数据数组首地址
//Len        :要写入数据的长度2,4
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
{         
        u8 t;
        for(t=0;t<Len;t++)
        {
                AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
        }                                                                                                    
}
//在AT24CXX里面的指定地址开始读出长度为Len的数据
//该函数用于读出16bit或者32bit的数据.
//ReadAddr   :开始读出的地址
//返回值     :数据
//Len        :要读出数据的长度2,4
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{         
        u8 t;
        u32 temp=0;
        for(t=0;t<Len;t++)
        {
                temp<<=8;
                temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);                                            
        }
        return temp;                                                                                                    
}
//检查AT24CXX是否正常
//这里用了24XX的最后一个地址(255)来存储标志字.
//如果用其他24C系列,这个地址要修改
//返回1:检测失败
//返回0:检测成功
u8 AT24CXX_Check(void)
{
        u8 temp;
        temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX                          
        if(temp==0X55)return 0;                  
        else//排除第一次初始化的情况
        {
                AT24CXX_WriteOneByte(255,0X55);
            temp=AT24CXX_ReadOneByte(255);          
                if(temp==0X55)return 0;
        }
        return 1;                                                                                          
}

//在AT24CXX里面的指定地址开始读出指定个数的数据
//ReadAddr :开始读出的地址 对24c02为0~255
//pBuffer  :数据数组首地址
//NumToRead:要读出数据的个数
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
        while(NumToRead)
        {
                *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);       
                NumToRead--;
        }
}  
//在AT24CXX里面的指定地址开始写入指定个数的数据
//WriteAddr :开始写入的地址 对24c02为0~255
//pBuffer   :数据数组首地址
//NumToWrite:要写入数据的个数
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
        while(NumToWrite--)
        {
                AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
                WriteAddr++;
                pBuffer++;
        }
}




文件test.c

#include "sys.h"
#include "usart.h"               
#include "delay.h"       
#include "led.h"
#include "oled.h"
#include "key.h"  
#include "24cxx.h"
#include "usmart.h"
//ALIENTEK Mini STM32开发板范例代码19
//IIC实验  
//技术支持:www.openedv.com
//广州市星翼电子科技有限公司
          
//要写入到24c02的字符串数组
const u8 TEXT_Buffer[]={"max"};
#define SIZE sizeof(TEXT_Buffer)
#define size1        sizeof(h)
int main(void)
{               
   u32 h=2;                                                      //修改
        u8 key;
        u16 i=0;
        u8 datatemp[SIZE];
        u32 datatemp1[size1];
        Stm32_Clock_Init(9);        //系统时钟设置
        uart_init(72,9600);                 //串口初始化为9600
        delay_init(72);                            //延时初始化
        LED_Init();                                  //初始化与LED连接的硬件接口
        OLED_Init();
        usmart_dev.init(72);        //初始化USMART               
        KEY_Init();                                //按键初始化                        
        AT24CXX_Init();                        //IIC初始化

        while(AT24CXX_Check())//检测不到24c02
        {
                OLED_ShowString(0,0,"24C02 Check Failed!",24);
                OLED_Refresh_Gram();//更新显示到OLED
                delay_ms(500);
                LED0=!LED0;//DS0闪烁
        }
        OLED_ShowString(0,0,"Ready!",24);
        OLED_Refresh_Gram();//更新显示到OLED
        while(1)
        {
                key=KEY_Scan(0);
                if(key==WKUP_PRES)//WK_UP 按下,写入24C02
                {
                        OLED_ShowString(0,24,"Start Write 24C02....",12);
                                OLED_Refresh_Gram();//更新显示到OLED
                        //AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);                                          //修改
                        AT24CXX_Write1(0,(u32*)h,size1);
                        OLED_ShowString(0,24,"24C02 Write Finished!",12);//提示传送完成
                                OLED_Refresh_Gram();//更新显示到OLED
                }
                if(key==KEY0_PRES)//KEY0 按下,读取字符串并显示
                {
                        OLED_ShowString(0,24,"Start Write 24C02....",12);
                        OLED_Refresh_Gram();//更新显示到OLED
                        //AT24CXX_Read(0,datatemp,SIZE);                                                   //修改
                        AT24CXX_Read1(0,(u32*)datatemp1,size1);
                        OLED_ShowString(0,24,"The Data Readed Is:  ",12);//提示传送完成
                        OLED_Refresh_Gram();//更新显示到OLED
                        //OLED_ShowString(0,36,datatemp,12);//显示读到的字符串
                        OLED_ShowNum(0,36,(u32)datatemp1,2,12);
                        OLED_Refresh_Gram();//更新显示到OLED
                        /*for(i=0;i<size1;i++)                                                             //修改
                        {
                        //OLED_ShowNum(i*6,36,datatemp1,1,12);
                                OLED_ShowString(i*6,36,(u8*)datatemp,12);//显示读到的字符串
                        OLED_Refresh_Gram();//更新显示到OLED
                        }*/
                }
                i++;
                delay_ms(10);
                if(i==20)
                {
                        LED0=!LED0;//提示系统正在运行       
                        i=0;
                }                  
        }
}


最佳答案

查看完整内容[请看2#楼]

你可用sprintf函数把数值转换(包括把若干个数据拼接)为一个字符串(等同于u8数组)就可以了。 但是,俺觉得直接写入数值也应该是可以的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

78

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2015-12-10
在线时间
49 小时
发表于 2016-4-2 21:34:08 | 显示全部楼层
你可用sprintf函数把数值转换(包括把若干个数据拼接)为一个字符串(等同于u8数组)就可以了。

但是,俺觉得直接写入数值也应该是可以的。
逆水行舟不进则退
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-4-1
在线时间
2 小时
 楼主| 发表于 2016-4-3 10:33:17 | 显示全部楼层
自顶,求解答!!
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11555
金钱
11555
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-3 11:05:51 | 显示全部楼层

看不出你改了什么,什么现象,
这么一堆代码,。。。没法帮你。



回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-4-1
在线时间
2 小时
 楼主| 发表于 2016-4-3 21:34:54 | 显示全部楼层
xuande 发表于 2016-4-3 11:05
看不出你改了什么,什么现象,
这么一堆代码,。。。没法帮你。

我贴出来的基本是原子哥的源码,只是原子哥定义的读写数据的格式都是字符串的,在test.c文件中,定义了一个const u8 型数组,这样才能写入24C02,但是我想写入动态数字,该怎么修改程序呢
回复

使用道具 举报

0

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2016-1-17
在线时间
44 小时
发表于 2016-4-4 17:49:43 来自手机 | 显示全部楼层
那你直接写进去不就行了,到底问题是什么呢?
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2016-5-4
在线时间
0 小时
发表于 2016-5-4 18:06:28 | 显示全部楼层
这个问题我也遇到了,不知道楼主解决了没有啊。现在正头疼这个问题呢
回复

使用道具 举报

7

主题

76

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
245
金钱
245
注册时间
2016-4-11
在线时间
54 小时
发表于 2016-12-19 17:40:56 | 显示全部楼层
写十六进制进行了
回复

使用道具 举报

10

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
362
金钱
362
注册时间
2018-5-14
在线时间
46 小时
发表于 2018-10-23 17:14:52 | 显示全部楼层
x646102053 发表于 2016-4-3 21:34
**** 作者被禁止或删除 内容自动屏蔽 ****

楼主你实现了么 最近我也在头疼这个问题
行至水穷处 坐看云起时
回复

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-10-23 17:30:37 | 显示全部楼层
GZH931022 发表于 2018-10-23 17:14
楼主你实现了么 最近我也在头疼这个问题

我扎眼一看不知道楼主说的啥,你竟然看懂了?你的问题是什么、
Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复

使用道具 举报

10

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
362
金钱
362
注册时间
2018-5-14
在线时间
46 小时
发表于 2018-10-23 19:39:48 | 显示全部楼层
秋天 发表于 2018-10-23 17:30
我扎眼一看不知道楼主说的啥,你竟然看懂了?你的问题是什么、

刚实现了 楼主的意思是 他要往24C02里写动态数据 原子哥给的是写的字符串 用数组存的 动态数据不用那么麻烦 直接顶一个变量存取就完事
行至水穷处 坐看云起时
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-10-23 22:34:46 | 显示全部楼层
回复

使用道具 举报

4

主题

91

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1091
金钱
1091
注册时间
2017-11-7
在线时间
311 小时
发表于 2018-10-24 14:55:33 | 显示全部楼层
写函数void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)中DataToWrite:要写入的数据不是U8类型吗?直接写就行了。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 15:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表