来帮帮忙啊!硬件仿真和直接下载出现完全不一样的结果?

[复制链接]
2632|6
手机看帖
扫描二维码
随时随地手机跟帖
na239152605|  楼主 | 2012-4-4 10:19 | 显示全部楼层 |阅读模式
STM32驱动TMP102时出现硬件仿真和直接下载出现完全不一样的结果。不知道是怎么回事?求解释啊?谢谢帮忙!!
下面是TMP102温度传感器的驱动
//TMP102温度传感器
#include "tmp102.h"

//初始化IIC接口
void TMP102_Init(void)
{
        IIC_Init();
}
//在TMP102指定地址读出数据
//PointerAddr:开始读数的地址  
//返回值  :读到的数据
uint32_t TMP102_ReadTwoByte(uint16_t PointerAddr)
{                                  
        uint32_t temp=0;
        uint16_t temp1,temp2;                                                                                                                                                               
    IIC_Start();  
        IIC_Send_Byte(0x90); //发送地址1 写
        IIC_Wait_Ack();
        IIC_Send_Byte(PointerAddr);         //指针寄存器
        IIC_Wait_Ack();
        IIC_Stop();    //产生一个停止条件
        delay_ms(500);
        delay_ms(500);
        IIC_Start();
        IIC_Send_Byte(0x91); //发送地址2 读
        IIC_Wait_Ack();
        temp1=IIC_Read_Byte();//读第一个字节
        IIC_Ack();
        LCD_ShowNum(110,30,temp1,4,16);//显示读出的值

        temp2=IIC_Read_Byte();//读第二个字节
        IIC_Ack();
        LCD_ShowNum(110,50,temp2,4,16);//显示读出的值
        temp1<<=8;
        temp=temp1|temp2;               
        IIC_Stop();    //产生一个停止条件
        delay_ms(10);

        return temp;

}
//在TMP102指定地址写入数据
//PointerAddr  :写入数据的目的地址   
//DataxWrite:要写入的数据
void TMP102_WriteTwoByte(uint16_t PointerAddr,uint16_t Data1Write,uint16_t Data2Write)
{                                                                                                                                                                                          
    IIC_Start();  
        IIC_Send_Byte(0x90); //发送地址 写
        IIC_Wait_Ack();
        IIC_Send_Byte(PointerAddr);         //指针寄存器
        IIC_Wait_Ack();
        IIC_Send_Byte(Data1Write);        //数据第一字节
        IIC_Wait_Ack();
        IIC_Send_Byte(Data2Write); //数据第二字节
        IIC_Wait_Ack();                       
        IIC_Stop();    //产生一个停止条件
        delay_ms(10);         
}
下面是main函数
int main(void)
{
        uint32_t temp;
        float temperate;
    /* Setup STM32 system (clock, PLL and Flash configuration) */
    SystemInit();
        delay_init(72);             //延时初始化
//  RCC_Configuration();
//        GPIO_Configuration();
//  uart_initConfiguration(9600);
//        NVIC_Configuration();
//        EXTI_Configuration();
        STM_EVAL_LEDInit(LED1);
        STM_EVAL_LEDInit(LED2);
    /* Add your application code here        */
        LCD_Init();
        POINT_COLOR=RED;
        LCD_ShowString(30,30,"TEMP1_VAL:");                           
        LCD_ShowString(30,50,"TEMP2_VAL:");
        LCD_ShowString(30,70,"TEMP_VAL:");                                   
        LCD_ShowString(30,90,"TEMPERATE:000.0000C");
        delay_ms(10);
        TMP102_Init();
        TMP102_WriteTwoByte(0x01,0x78,0xA0);
        delay_ms(10);
        temp=TMP102_ReadTwoByte(0x0);
        temp>>=4;
        LCD_ShowNum(102,70,temp,4,16);//显示读出的值
        temperate=(float)temp*(0.0625);        //保存温度传感器的温度
        temp=temperate;                  //取温度的整数部分
        LCD_ShowNum(110,90,temp,3,16);     //显示温度值整数部分
        temperate-=(uint32_t)temperate;
        temperate*=10000;
        LCD_ShowNum(142,90,temperate,4,16);//显示温度小数部分
  /* Infinite loop */
    while (1)
    {
                STM_EVAL_LEDOff(LED1);
                delay_ms(100);
                STM_EVAL_LEDOn(LED1);                         
                delay_ms(100);
       
    }
}
下面是IIC时序
//初始化IIC
void IIC_Init(void)
{                                             
        GPIO_InitTypeDef GPIO_InitStructure;
        //RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOC, ENABLE );       
          
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);

}
//产生IIC起始信号
void IIC_Start(void)
{
        SDA_OUT();     //sda线输出
        IIC_SCL_SET;
        delay_us(5);                    
        IIC_SDA_SET;
        delay_us(5);
        IIC_SDA_CLR;//START:when CLK is high,DATA change form high to low
        delay_us(5);
        IIC_SCL_CLR;//钳住I2C总线,准备发送或接收数据
}          
//产生IIC停止信号
void IIC_Stop(void)
{
        SDA_OUT();     //sda线输出
//        IIC_SCL_CLR;
        IIC_SDA_CLR;//STOP:when CLK is high DATA change form low to high
        delay_us(5);
        IIC_SCL_SET;
        delay_us(5);
        IIC_SDA_SET;//发送I2C总线结束信号
        delay_us(5);                                                                  
}
//等待从机的应答信号到来
void IIC_Wait_Ack(void)
{
        uint8_t i=0;
    IIC_SCL_SET;
    delay_us(5);
    while((IIC_SDA==1)&&(i<250))
        i++;
    IIC_SCL_CLR;
    delay_us(5);           
}
//主机产生ACK应答
void IIC_Ack(void)
{
        IIC_SCL_CLR;
        SDA_OUT();
        IIC_SDA_CLR;
//        IIC_SDA_SET;
        delay_us(5);
        IIC_SCL_SET;
        delay_us(5);
        IIC_SCL_CLR;
}
//不产生ACK应答                    
void IIC_NAck(void)
{
        IIC_SCL_CLR;
        SDA_OUT();
        IIC_SDA_SET;
        delay_us(5);
        IIC_SCL_SET;
        delay_us(5);
        IIC_SCL_CLR;
}                                                                              
//IIC写一个字节                  
void IIC_Send_Byte(uint8_t txd)
{                        
    uint8_t t;   
        SDA_OUT();             
    IIC_SCL_CLR;   //拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1;           
                delay_us(5);   
                IIC_SCL_SET;
                delay_us(5);
                IIC_SCL_CLR;       
                delay_us(5);
    }         
}             
//读1个字节
uint8_t IIC_Read_Byte(void)
{
        uint8_t i,receive=0;
        SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
        {
                IIC_SCL_CLR;
                delay_us(5);
              IIC_SDA_SET;
              delay_us(10);
              for(i=0;i<8;i++)
              {
            IIC_SCL_SET;
            delay_us(5);
            receive=(receive<<1) | READ_SDA;        //READ_SDA
            IIC_SCL_SET;
            delay_us(5);
              }
    }                                          
    return receive;
}
不知道哪里出错了,个人感觉应该是读时序错了。谢谢帮忙
香水城| | 2012-4-4 11:18 | 显示全部楼层
这种情况多数都是因为STM32的上电快,而片外器件上电慢,程序初始化片外器件时,片外器件还没有就绪,导致片外器件没有被正确初始化。

使用特权

评论回复
na239152605|  楼主 | 2012-4-4 14:13 | 显示全部楼层
2# 香水城 谢谢你的回答,看了你的博客,写的很好值的学习。但我还是不清楚问题出在哪?

使用特权

评论回复
na239152605|  楼主 | 2012-4-4 17:55 | 显示全部楼层
我下面具体描述一下:
用Jlink仿真时TFT显示如下:
        TEMP1_VAL:255                           
        TEMP2_VAL:255
        TEMP_VAL:4095                                   
        TEMPERATE:255.9375C
直接下载时显示如下:
        TEMP1_VAL:  0                           
        TEMP2_VAL:  0
        TEMP_VAL:   0                           
        TEMPERATE:0.   0C
还有就是这两个显示都不对,我怀疑是如下函数的问题
void TMP102_WriteTwoByte(uint16_t PointerAddr,uint16_t Data1Write,uint16_t Data2Write);
但我又是按时序来写的,很纠结啊!谢谢个各位了!

使用特权

评论回复
na239152605|  楼主 | 2012-4-4 21:11 | 显示全部楼层
上一下原理图 QQ截图20120404205833.jpg

使用特权

评论回复
na239152605|  楼主 | 2012-4-4 22:25 | 显示全部楼层
谢谢各位!我已经调出了!问题出在下面这个函数:
uint8_t IIC_Read_Byte(void)
{
        uint8_t i,receive=0;
        SDA_IN();    //SDA设置为输入
    for(i=0;i<8;i++ )
        {
                IIC_SCL_CLR;
                delay_us(4);
              IIC_SDA_SET;
              for(i=0;i<8;i++)
              {
            IIC_SCL_SET;
            delay_us(4);
            receive=(receive<<1) | READ_SDA;        //READ_SDA
            IIC_SCL_CLR;
            delay_us(4);
              }
    }                                          
    return receive;
}
以前是 IIC_SCL_SET;应该为 IIC_SCL_CLR;

使用特权

评论回复
diyiyuzhousu| | 2013-6-20 11:25 | 显示全部楼层
   for(i=0;i<8;i++ )
        {
                IIC_SCL_CLR;
                delay_us(4);
              IIC_SDA_SET;
              for(i=0;i<8;i++)
              {
            IIC_SCL_SET;
            delay_us(4);
            receive=(receive<<1) | READ_SDA;        //READ_SDA
            IIC_SCL_CLR;
            delay_us(4);
              }


大侠,这个地方怎么有2个for循环呢?这样的话,I2C取数都不对的呀?是我理解错了吗?还是写错了?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

212

帖子

1

粉丝