搜索
bottom↓
回复: 9

stm32 24c02 接收数据0xff

[复制链接]

出0入0汤圆

发表于 2014-5-9 10:30:07 | 显示全部楼层 |阅读模式
本帖最后由 269837846 于 2014-5-9 11:25 编辑

好心人帮忙程序如下:


/*******************************************************************************
* 文件名            : main.c
* 作者                 : Losingamong
* 生成日期          : 14/09/2010
* 描述                           : 主程序
*******************************************************************************/


/* 头文件 ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "stdio.h"

/* 自定义同义关键字    -------------------------------------------------------*/

/* 自定义参数宏        -------------------------------------------------------*/

void delay(unsigned int t)
{//延时函数
    while(t){t--;};                    //延时循环计数
}
void delay_IIC(void)   
{u8 i=80; //这里可以优化速度 ,经测试最低到5还能写入
   while(i)  
   {  
     i--;  
   }
}


#define PB7_OUT() {GPIOB->CRL&=0x0fffffff;GPIOB->CRL|=0x30000000;        }
#define PB7_IN() {GPIOB->CRL&=0x0fffffff;GPIOB->CRL|=0x80000000;        }
#define SDA1() {GPIO_SetBits(GPIOB, GPIO_Pin_7);}
#define SDA0() {GPIO_ResetBits(GPIOB, GPIO_Pin_7);}
#define SCL1() {GPIO_SetBits(GPIOB, GPIO_Pin_6);}
#define SCL0() {GPIO_ResetBits(GPIOB, GPIO_Pin_6);}

//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC总线初始化函数
    SDA1();//释放IIC总线的数据线。
    SCL0();//释放IIC总线的时钟线。
}

//-------------------------------------------------------------------
void IIC_start(void)
{//IIC总线产生起始信号函数  
    SDA1();//拉高数据线
    SCL1();//拉高时钟线
    delay_IIC();
    SDA0();//在时钟线为高电平时,拉低数据线,产生起始信号。
    delay_IIC();
    SCL0();//拉低时钟线
}


//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC总线产生停止信号函数
    SDA0();//拉低数据线
    delay_IIC();
    SCL1();//拉高时钟线。
    delay_IIC();
    SDA1();//时钟时线为高电平时,拉高数据线,产生停止信号。
    delay_IIC();
}

//-------------------------------------------------------------------
u8 IIC_Tack(void)
{//接收应答信号函数
    u8 ack;//定义一个位变量,来暂存应答状态。
    SDA1();//释放数据总线,准备接收应答信号。
    delay_IIC();
    SCL1();//拉高时钟线。
    delay_IIC();
        PB7_IN();
    ack= GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_7);//读取应答信号的状态。
        PB7_OUT();
    delay_IIC();
    SCL0();//拉低时钟线。
    delay_IIC();
    return ack;//返回应答信号的状态,0表示应答,1表示非应答。
}

//-------------------------------------------------------------------
void IIC_write_byte(u8 Data)
{//向IIC总线写入一个字节的数据函数
    u8 i;
     for(i=0;i<8;i++)//有8位数据
    {
      if(Data&0x80)//写最高位的数据
             {SDA1();}
            else
                 {SDA0();}
       delay_IIC();
       SCL1(); //拉高时钟线,将数写入到设备中。
       delay_IIC();
           delay_IIC();
       SCL0();//拉低时钟线,允许改变数据线的状态
       delay_IIC();
           delay_IIC();
       Data=Data<<1;//数据左移一位,把次高位放在最高位,为写入次高位做准备
    }
}

//-------------------------------------------------------------------
unsigned char IIC_read_byte()
{//从IIC总线读取一个字节的数据函数
    u8 i;
    u8 Data;       //定义一个缓冲寄存器。
        PB7_IN();
    for(i=0;i<8;i++)//有8位数据
    {
        SCL1();//拉高时钟线,为读取下一位数据做准备。
        delay_IIC();
        Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
        delay_IIC();
        
        if(GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_7))//如果数据线为高平电平。
            Data=Data|0x1;//则给缓冲字节的最低位写1。
        SCL0();//拉低时钟线,为读取下一位数据做准备。
        delay_IIC();
    }
        PB7_OUT();
    return Data;//返回读取的一个字节数据。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(u8 Daddr,u8 Waddr,u8 Data)
{//向任意地址写入一个字节数据函数
    IIC_start();//产生起始信号
    IIC_write_byte(Daddr);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    IIC_write_byte(Data);//写入数据。
    IIC_Tack();//等待设备的应答。
    IIC_stop();//产生停止符号。
}

//-------------------------------------------------------------------
u8 IIC_single_byte_read(u8 Daddr,u8 Waddr)
{//从任意地址读取一个字节数据函数
    unsigned char Data;//定义一个缓冲寄存器。

    IIC_start();//产生起始信号
    IIC_write_byte(Daddr);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
   
    IIC_start();//产生起始信号
    IIC_write_byte(Daddr+1);//写入设备地址(读)。
    IIC_Tack();//等待设备的应答。
    Data=IIC_read_byte();//写入数据。
    IIC_stop();//产生停止符号。
    //-------------------返回读取的数据--------------------
    return Data;//返回读取的一个字节数据。
}



/* 自定义函数宏        -------------------------------------------------------*/

/* 自定义变量          -------------------------------------------------------*/

/* 用户函数声明 ---------------------------------------------------------*/

void RCC_Configuration(void);
void GPIO_Configuration(void);

void USART_Configuration(void);



int main(void)
{
   
        /* 设置系统时钟 */
        RCC_Configuration();
        /* 设置GPIO端口 */
        GPIO_Configuration();
        /* 设置USART */
        USART_Configuration();
        while(1)
        {
        u8 iic_data=0x00;
        printf("\r\n The I2C is ready!!!\n");
                         
        IIC_single_byte_write(0xA0,0x01,0x66);
        printf("\r\n The I2C write!!!\n");
        iic_data=IIC_single_byte_read(0xA0,0x01);
        printf("\r\n The I2C1 has read data 0x%x\r\n", iic_data);
        iic_data=IIC_single_byte_read(0xA0,0x02);
        printf("\r\n The I2C1 has read data 0x%x\r\n", iic_data);
        }
}


void RCC_Configuration(void)
{
        ErrorStatus HSEStartUpStatus;
       
        RCC_DeInit();
        RCC_HSEConfig(RCC_HSE_ON);
        HSEStartUpStatus = RCC_WaitForHSEStartUp();
        if(HSEStartUpStatus == SUCCESS)
        {
                FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
                FLASH_SetLatency(FLASH_Latency_2);
                RCC_HCLKConfig(RCC_SYSCLK_Div1);
                RCC_PCLK2Config(RCC_HCLK_Div1);
                RCC_PCLK1Config(RCC_HCLK_Div2);
                RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);       
                RCC_PLLCmd(ENABLE);
                while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
                RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
                while(RCC_GetSYSCLKSource() != 0x08);
        }
       
        /* 开启 I2C1、I2C2 设备时钟 */
        //RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2, ENABLE);
        /* 开启 GPIOA、GPIOB和 USART 设备时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
}


void GPIO_Configuration(void)
{
        /* 定义 GPIO 初始化结构体 GPIO_InitStructure */
        GPIO_InitTypeDef GPIO_InitStructure;
       
        /* 配置 I2C1 设备的引脚为复用开漏模式 */
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
        /* 配置 I2C2 设备的引脚为复用开漏模式
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
        GPIO_Init(GPIOB, &GPIO_InitStructure); */
       
        /* 配置 USART 设备引脚 */       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}







void USART_Configuration(void)
{
    /* 定义USART初始化结构体 USART_InitStructure */
    USART_InitTypeDef USART_InitStructure;
    /* 定义USART初始化结构体 USART_ClockInitStructure */
    USART_ClockInitTypeDef  USART_ClockInitStructure;
   
    /*       
        *        波特率为115200bps;
    *        8位数据长度;
    *        1个停止位,无校验;
    *        禁用硬件流控制;
    *        禁止USART时钟;
    *        时钟极性低;
    *        在第2个边沿捕获数据
    *        最后一位数据的时钟脉冲不从 SCLK 输出;
    */
    USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
    USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
    USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
    USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
    USART_ClockInit(USART1 , &USART_ClockInitStructure);
   
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No ;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1 , &USART_InitStructure);
   
    /* 使能USART1 */
    USART_Cmd(USART1 , ENABLE);
}

#pragma import(__use_no_semihosting)
_sys_exit(int x)
{
x = x;
}
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (u8) ch);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    return ch;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2014-5-9 10:31:12 | 显示全部楼层
貌似是写不进24c02

出0入0汤圆

 楼主| 发表于 2014-5-9 10:32:18 | 显示全部楼层
坐等回复

出0入0汤圆

发表于 2014-5-15 09:50:31 | 显示全部楼层
坐等天上掉馅饼

出0入0汤圆

发表于 2014-5-17 10:12:12 | 显示全部楼层
马老师都开口了;  楼主还是自己慢慢调吧

出0入4汤圆

发表于 2014-5-17 11:44:13 | 显示全部楼层
void IIC_single_byte_write(u8 Daddr,u8 Waddr,u8 Data)
{//向任意地址写入一个字节数据函数
    IIC_start();//产生起始信号
    IIC_write_byte(Daddr);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    IIC_write_byte(Data);//写入数据。
    IIC_Tack();//等待设备的应答。
    IIC_stop();//产生停止符号。
}

写数据时序?对吗

出0入0汤圆

 楼主| 发表于 2014-5-22 21:12:07 | 显示全部楼层
machao 发表于 2014-5-15 09:50
坐等天上掉馅饼

走投无路了,才来请教大家的,不好意思

出0入0汤圆

 楼主| 发表于 2014-5-22 21:13:17 | 显示全部楼层
xiaoyigechaos 发表于 2014-5-17 11:44
void IIC_single_byte_write(u8 Daddr,u8 Waddr,u8 Data)
{//向任意地址写入一个字节数据函数
    IIC_star ...

是波特率没有设置好,谢谢啊

出0入0汤圆

 楼主| 发表于 2014-5-22 21:13:57 | 显示全部楼层
男小北 发表于 2014-5-17 10:12
马老师都开口了;  楼主还是自己慢慢调吧

谢谢你,谢谢马老师,问题解决了

出0入0汤圆

发表于 2014-5-23 02:56:23 | 显示全部楼层
汗颜,为什么谢我?你花费了时间,可走的是歪路。貌似解决了,只不过是在错误路上走的更远。

STM32本身有I2C硬件接口,偏用IO口模拟,还用大量的软件延时。这样的代码没有太多的实际工程应用价值,只有初学练连手的作用。不知道通过这个过时的代码练手实践,是否真的掌握了I2C的协议,以及基本的MCU应用方法。

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 02:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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