完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
将一个float型数据存到AT24C02中,再读出到串口显示,为啥串口显示的是一个错误的数呀?是我程序哪有问题吗?请各位大神指点。谢谢
#include #include #define write_c02 0xa0 #define read_c02 0xa1 typedef unsigned char uchar; typedef unsigned int uint; ***it sda = P2^0; ***it scl = P2^1; /*********延时**************/ void delay() //约5us { ;; } void delayms(uint xms) //延时X毫秒 { uchar x,y; for(x=xms;x>0;x--) for(y=110;y>0;y--); } /**********I2C子程序***************/ void i2c_init() //I2C初始化 { sda=1; delay(); scl=1; delay(); } void start() //启动I2C { sda=1; scl=1; delay(); //在scl为高电平时,sda一个下降沿为启动信号 sda=0; delay(); } void stop() //停止I2C { sda=0; scl=1; delay(); sda=1; //在scl为高电平时,sda一个上升沿为停止信号 delay(); } void ack() //应答信号0 { uchar i=0; //等待变量 scl=1; //在scl为高电平期间等待应答 delay(); while((sda=1)&&i<250)//若为应答0即退出,从机向主机发送应答信号 i++; scl=0; //应答之后将scl拉低 delay(); } void nack() //非应答 { scl=1; //在scl为高电平期间,由主机向从机发送一个1;非应答信号 delay(); sda=1; scl=0; //应答之后将scl拉低 delay(); } void send_byte(uchar date) //写一个字节 { uchar i , temp; temp=date; //存入要写入的数据,即要发送到sda上的数据 for(i=0;i<8;i++) { temp<<=1; scl=0; //只有在scl为低电平时,才允许sda上的数据变化 delay(); sda=CY; //将CY里的数据发送到sda数据线上 delay(); scl=1; //在scl为高电平时,不允许sda上的数据变化,使数据稳定 delay(); scl=0; //允许sda数据线的数据变化,等待下一个数据的传输 delay(); }//发送完一个字节数据后主机要等待从机的应答 scl=0;//允许sda变化 delay(); sda=1;//sda拉高等待应答,当sda=0时,表示从机应答 delay(); } uchar read_byte() //读一个字节数据 { uchar i,j,k; scl=0; //读之前先允许sda变化 delay(); //等待数据 for(i=0;i<8;i++) { scl=1; //不允许sda变化 delay(); j=sda; //读出sda上的数据 k=(k<<1)|j;//将数据通过|运算存入K中 delay(); scl=0; //允许sda变化等待下一位数据的到来 delay(); } delay(); return k; //返回读出的数据 } /*****************从AT24C02中存取数据***********************/ void write_at24c02(uchar address,uchar date)//在at24c02中的指定地址写入数据、 { start(); //启动I2C send_byte(write_c02); //写入期间地址和写操作 ack(); //从机应答0 send_byte(address);//写入写数据的单元地址 ack(); send_byte(date);//在指定地址中写入数据 ack(); stop(); //停止I2C } uchar read_at24c02(uchar address)//在at24c02的指定地址中读出写入的数据 { uchar dat; //用来存储读出的数据 start(); //启动I2C send_byte(write_c02);//写入at24c02期间地址和写操作 ack(); send_byte(address); //写入要读取at24c02的数据的单元地址 ack(); start(); //再次启动I2C send_byte(read_c02);//写入at24c02期间地址和读操作 ack(); dat=read_byte();//读出指定地址中的数据 nack();//主机发出非应答1 stop();//停止I2C return dat; } /**********************从AT24C02中存取float型数据****************************/ void write_f_rom(uchar address,float date)//将系数存入AT24C02 { unsigned long d; unsigned char d0,d1,d2,d3; d=(unsigned long)(date); d0=(unsigned char)(d>>24); d1=(unsigned char)((d&0x00ff0000)>>16); d2=(unsigned char)((d&0x0000ff00)>>8); d3=(unsigned char)(d%256); delayms(10); write_at24c02(address,d0); delayms(10); write_at24c02(address+0x01,d1); delayms(10); write_at24c02(address+0x02,d2); delayms(10); write_at24c02(address+0x03,d3); delayms(10); } float read_f_rom(unsigned char address) //从AT24C02中读取数据 { unsigned char i; float date; unsigned char c[4]; unsigned long d[4]; for(i=0;i<4;i++) { read_at24c02(address+i); c[i]=read_at24c02(address+i); } for(i=0;i<4;i++) { d[i]=(unsigned long)c[i]; } date=((float)((long)((d[0]<<24)+(d[1]<<16)+(d[2]<<8)+d[3]))); return date; } /******************串口初始化**********************/ void uart_init(void) //串口的初始化 { TMOD=0x20;//即0010 0000,定时器/计数器1,工作方式2 TH1=0xfd;//设置波特率为9600 TL1=0xfd; TR1=1;//启动定时器/计数器1 SCON=0x50; //0101 0000.串口工作方式1,允许串行控制 PCON=0x00;//设置SMOD=0 IE=0x90; //CPU允许中断,串行允许中断 ti=1;//直接使用printf必须加入此句才能实现发送 ES=1;//开串口中断 EA=1;//开总中断 } void main() { // uchar i; float shuju=1.1; float shuju1; i2c_init(); uart_init(); start(); while(1) { write_f_rom(0x00,shuju); delayms(100); shuju1=read_f_rom(0x00); delayms(100); printf("%fn",shuju1); delayms(200); } } |
|
相关推荐
8个回答
|
|
应该跟数据处理有关吧
|
|
|
|
不加下面的程序,单独存取char型数据没有问题,比如‘A’。存取float型数据通过串口显示的也是错误的数。加了下面的程序存取float型数据,显示到串口助手上就变成其他数据了。感觉思路应该没有问题吧。请大神指点。谢谢。 void write_f_rom(uchar address,float date)//将系数存入AT24C02 { unsigned long d; unsigned char d0,d1,d2,d3; d=(unsigned long)(date); d0=(unsigned char)(d>>24); d1=(unsigned char)((d&0x00ff0000)>>16); d2=(unsigned char)((d&0x0000ff00)>>8); d3=(unsigned char)(d%256); delayms(10); write_at24c02(address,d0); delayms(10); write_at24c02(address+0x01,d1); delayms(10); write_at24c02(address+0x02,d2); delayms(10); write_at24c02(address+0x03,d3); delayms(10); } float read_f_rom(unsigned char address) //从AT24C02中读取数据 { unsigned char i; float date; unsigned char c[4]; unsigned long d[4]; for(i=0;i<4;i++) { read_at24c02(address+i); c=read_at24c02(address+i); } for(i=0;i<4;i++) { d=(unsigned long)c; } date=((float)((long)((d[0]<<24)+(d[1]<<16)+(d[2]<<8)+d[3]))); return date; } |
|
|
|
楼上正解收藏了先。
|
|
|
|
你怎么判断串口助手接收到的数据是错误的,其实只要串口助手接收到的数据和你储存的一样就可以了
|
|
|
|
(・。・)串口助手接收到的数据和我存储的不一样,我又试了改变我给定的float型数据,无论是给的1.1还是3.4最后串口助手显示的都是4325.6。 |
|
|
|
存储时应该直接把float分四个字节存储就好了,不应该做数据格式转换。
|
|
|
|
|
|
|
|
0o川o0 发表于 2017-5-7 18:06 从你这情况看确实是数据处理的问题,你好好了解一下float型数据在单片机内部如何存储的,然后依照此方式存储和读取即可 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
72 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第二章 常用的C语言知识点
509 浏览 0 评论
【RA-Eco-RA2E1-48PIN-V1.0开发板试用】(第三篇)ADC采集+PWM输出
546 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第四十五章 人脸识别实验
545 浏览 0 评论
1008 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11763 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 16:08 , Processed in 0.713055 second(s), Total 83, Slave 67 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号