打印

STM32很奇怪啊(adc i2c问题)

[复制链接]
6137|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
brotherwen|  楼主 | 2009-6-3 16:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void SetADC(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    /* Enable GPIOC  ADC1 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1, ENABLE);
    /* Enable DMA clock*/
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);   

    /* Configure PC 0,1,2 (ADC Channel1) as analog input */
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /* DMA Channel1 Configuration ----------------------------------------------*/
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
    DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)&ADC_ConvertedValue;
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize         = 3;
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority           = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);

    //DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);
    //NVIC->ISER[0]|=1<<11;  //enable DMA1_channel1 interrupt
     /* Enable DMA Channel1  */
    DMA_Cmd(DMA1_Channel1, ENABLE);       

    // ADC1 Configuration (ADC1CLK = 18 MHz) -----------------------------------
    ADC_InitStructure.ADC_Mode               = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode       = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                          
    ADC_InitStructure.ADC_ExternalTrigConv   = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign          = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel       = 3;
    ADC_Init(ADC1, &ADC_InitStructure);

    // ADC1 Regular Channel1 Configuration                                     
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_55Cycles5);
    ADC_StartCalibration(ADC1);
    ADC_DMACmd(ADC1, ENABLE);             
    ADC_Cmd(ADC1, ENABLE);  
    //ADC_SoftwareStartConvCmd(ADC1,ENABLE);
    
}

之后读写i2c 总线时就死掉了
沙发
香水城| | 2009-6-3 18:17 | 只看该作者

如何操作I2C总线的?哪个I2C端口?

使用特权

评论回复
板凳
brotherwen|  楼主 | 2009-6-3 21:22 | 只看该作者

初始化部分

#define I2C_REMMAP 
/*------------------- I 2 C   I N I T --------------------
【功能】:i2c接口初始化
【参数】:****
【返回】:****
【说明】:****
--------------作者:88888   2009年5月25日14:33:44-------------------------*/
void I2cInit(void)
{    
    I2C_InitTypeDef  I2C_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    /* Enable I2C1 and GPIOB clocks */    
#ifndef  I2C_REMMAP 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, DISABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    /* Configure I2C1 pins: SCL and SDA */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
#else    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
    /* Configure I2C1 pins: SCL and SDA */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);   
#endif        
    I2C_DeInit(I2C1);    
     /* I2C configuration */
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Disable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;     
    /* Apply I2C configuration after enabling it */
    I2C_Init(I2C1,&I2C_InitStructure);      
    I2C_Cmd(I2C1,ENABLE);        
}

使用特权

评论回复
地板
brotherwen|  楼主 | 2009-6-3 21:26 | 只看该作者

写部分,

/*------------------- R E A D   A   T 2 4   C 2 5 6 --------------------
【功能】:****
【参数】:****
【返回】:****
【说明】:****
--------------作者:****   2009年5月15日12:51:22-------------------------*/
void ReadAT24C256(u32 addr, u8 *ptr, u32 len)
{
//    int i;   
  
#ifndef  I2C_REMMAP     
    I2cInit();    
#endif   
    I2C_AcknowledgePolling();  
    
    I2C_GenerateSTART(I2C1,ENABLE);
    while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS);
    I2C_Send7bitAddress(I2C1,AT24_DEVICE_ADDR,I2C_Direction_Transmitter);
    while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)!=SUCCESS);
    I2C_SendData(I2C1,(addr>>8));
    while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)!=SUCCESS);
    I2C_SendData(I2C1,(addr&0xff));
    while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)!=SUCCESS);
    
    I2C_GenerateSTART(I2C1,ENABLE);
    while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS); 
    I2C_Send7bitAddress(I2C1,AT24_DEVICE_ADDR,I2C_Direction_Receiver);
    while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)!=SUCCESS);    
    for ( ; len!=1; len--)
    {
        I2C_AcknowledgeConfig(I2C1,ENABLE);
        while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)!=SUCCESS);          
        *(ptr++) = I2C_ReceiveData(I2C1);        
    }
    I2C_AcknowledgeConfig(I2C1,DISABLE);
    while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)!=SUCCESS);
    *(ptr++)=I2C_ReceiveData(I2C1); 
    I2C_GenerateSTOP(I2C1,ENABLE); 
#if 0    
    if(len>=1){
        for(i=0;i<len-1;i++){
            I2C_AcknowledgeConfig(I2C1,ENABLE);
            while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)!=SUCCESS);
            *ptr=I2C_ReceiveData(I2C1);            
            ptr++;
        }
    }
    I2C_AcknowledgeConfig(I2C1,DISABLE);
    while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)!=SUCCESS);
    *ptr=I2C_ReceiveData(I2C1);    
    I2C_GenerateSTOP(I2C1,ENABLE); 
#endif

#ifndef  I2C_REMMAP    
    I2C_Cmd(I2C1,DISABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,DISABLE);
    FSMC_SRAM_Init();
#endif   
}

使用特权

评论回复
5
brotherwen|  楼主 | 2009-6-3 21:26 | 只看该作者

望香主能明示

使用特权

评论回复
6
香水城| | 2009-6-3 22:36 | 只看该作者

STM32 I2C 封装库

STM32的I2C模块,如果自己写驱动经常会有问题,而且STM32固件库中的I2C例子也不是很好,所以我们自己写了一个高层次的封装库(见下面的帖子链接),目前用起来效果不错,你可以试试。

关于你写的程序,不经实际调试很难静态地看出毛病,实际调试我也没有这个时间,恕不能帮忙,见谅。
相关链接:https://bbs.21ic.com/club/bbs/list.asp?boardid=49&page=1&t=3194196&tp=STM32%20I2C%20%u5C01%u88C5%u5E93%uFF08%u67E5%u8BE2%u65B9%u5F0F+29%u697C%u4E2D%u65AD%u65B9%u5F0F+32%u697CDMA%u65B9%u5F0F%uFF09

使用特权

评论回复
7
brotherwen|  楼主 | 2009-6-4 09:30 | 只看该作者

有点汗啊

我觉得首先的问题是我的程序是否有所纰漏。
其实我的操作步骤是否得当。
因为许多片子也是这样玩的啊,也没有问题啊

难道用stm32的i2c一定得官方最好的封装库???

使用特权

评论回复
8
香水城| | 2009-6-4 10:24 | 只看该作者

发布封装好的库,就是为了方便大家的使用

因为我们的人力有限,肯定没有精力帮助所有用户检查程序的纰漏;否则我们也没有必要发布封装好的库了,敬请谅解。

使用特权

评论回复
9
brotherwen|  楼主 | 2009-6-4 16:19 | 只看该作者

结贴,自己搞定

本质问题是st公司和其它所有公司i2c设计思路有出入。

stm32的i2c总线接受异常情况相当脆弱

使用特权

评论回复
10
香水城| | 2009-6-4 17:04 | 只看该作者

同意10楼这样的评价

ST的I2C设计思路与其它公司有出入——每个设计师都可以有自己的思路。

10楼的第2个评价是:STM32的I2C模块接受异常情况相当脆弱。我有条件地同意这个评价,条件是如果通过软件可以处理,就属正常。


关于这个问题,我的理解是:为了减小功耗、减小硬件设计的复杂度、降低硬件的成本,应该设计一个功能简单的硬件,在通过与软件的配合完成需要的功能前提下,只要软件能够实现的功能,就不用通过硬件实现。CPU设计上RISC概念的出现,正是体现了这个精神。

我们知道复杂的系统调试和Debug是一件困难的事情,比较在时间和金钱上的花费,调试和Debug硬件要比调试和Debug软件需要几十至上百倍的时间和成本,所以我们必须降低硬件的复杂度。

另一方面讲,硬件的复杂度增加意味着硬件成本的增加,这个增加的成本是出现在每一个终端产品中,不会因为终端产品生产数量的增加而减少。而软件的开发成本却可以平摊到每一个终端产品中,每个产品中包含的软件成本会随着产品生产数量的增加而下降。因此把产品的成本从硬件转嫁软件对控制终端产品的成本是有效的。


正因为这样的设计,增加了软件的复杂度,所以更需要我们用封装库的形式帮助客户减轻负担。

使用特权

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

本版积分规则

52

主题

217

帖子

0

粉丝