硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1372|回复: 6
收起左侧

[技术讨论] STM32407+AD7606 FSMC驱动问题

[复制链接]

1

主题

2

回帖

5

积分

新手上路

积分
5
发表于 2025-1-7 16:43:37 | 显示全部楼层 |阅读模式
各位大神好,请教问题如下:

基于V5开发板的手册和代码,将例程中的AD7606 FSMC代码根据我手上的板子进行了移植。基于软件定时器进行的采集,其中CH1外部接了函数信号发生器(输出+1V),数据输出不正确(如下图)
1.png
然后使用示波器查看了转换时序波形,也和V5手册中的转换时序图不一致(实测如下图)
2.png
也对照了代码,不知道是配置哪里出了问题,麻烦各位大神帮忙看下(感谢!)
1、GPIO引脚配置
[C] 纯文本查看 复制代码
void AD7606_GPIO_Config( void )
{
    //FSMC引脚
    {
        GPIO_InitTypeDef gpio_init_structure;		
		
        /* 使能FMC时钟 */
        __HAL_RCC_FSMC_CLK_ENABLE();
		
        __HAL_RCC_GPIOD_CLK_ENABLE();	//FSMC_Dx、FSMC_NOE
        __HAL_RCC_GPIOE_CLK_ENABLE();	//FSMC_Dx	
		__HAL_RCC_GPIOF_CLK_ENABLE();				
        __HAL_RCC_GPIOG_CLK_ENABLE();	//FSMC_NE4

        /* 设置 GPIOD 相关的IO为复用推挽输出 */
        gpio_init_structure.Mode        = GPIO_MODE_AF_PP;
        gpio_init_structure.Pull        = GPIO_PULLUP;
        gpio_init_structure.Speed       = GPIO_SPEED_FREQ_VERY_HIGH;
        gpio_init_structure.Alternate   = GPIO_AF12_FSMC;

        /* 配置GPIOD */
        gpio_init_structure.Pin =   GPIO_PIN_0 |    //FSMC_D2
                                    GPIO_PIN_1 |    //FSMC_D3
                                    GPIO_PIN_4 |    //FSMC_NOE
                                    GPIO_PIN_5 |    //FSMC_NWE
                                    GPIO_PIN_8 |    //FSMC_D13
                                    GPIO_PIN_9 |    //FSMC_D14
                                    GPIO_PIN_10 |   //FSMC_D15
                                    GPIO_PIN_14 |   //FSMC_D0
                                    GPIO_PIN_15;    //FSMC_D1
        HAL_GPIO_Init( GPIOD, &gpio_init_structure );

        /* 配置GPIOE */
        gpio_init_structure.Pin =   GPIO_PIN_7 |    //FSMC_D4
                                    GPIO_PIN_8 |    //FSMC_D5
                                    GPIO_PIN_9 |    //FSMC_D6
                                    GPIO_PIN_10 |   //FSMC_D7
                                    GPIO_PIN_11 |   //FSMC_D8
                                    GPIO_PIN_12 |   //FSMC_D9
                                    GPIO_PIN_13 |   //FSMC_D10
                                    GPIO_PIN_14 |   //FSMC_D11
                                    GPIO_PIN_15;    //FSMC_D12
        HAL_GPIO_Init( GPIOE, &gpio_init_structure );
		
		//配置GPIOF
		gpio_init_structure.Pin=GPIO_PIN_0;
		HAL_GPIO_Init(GPIOF,&gpio_init_structure);

        /* 配置GPIOG */
        gpio_init_structure.Pin =   GPIO_PIN_12;     //FSMC_NE4
        HAL_GPIO_Init( GPIOG, &gpio_init_structure );
    }
	
	//BUSY引脚
    {
        GPIO_InitTypeDef   GPIO_InitStructure;

        __HAL_RCC_SYSCFG_CLK_ENABLE();
		
        BUSY_RCC_GPIO_CLK_ENABLE();

        GPIO_InitStructure.Mode = GPIO_MODE_INPUT;      //设置输入
        GPIO_InitStructure.Pull = GPIO_NOPULL;          //无上下拉
        GPIO_InitStructure.Pin  = BUSY_PIN;
        HAL_GPIO_Init( BUSY_PORT, &GPIO_InitStructure );
    }

    //过采样模式控制信号OS0、OS1、OS2, 启动AD转换控制信号CA、CB, 复位RST
    {
        //启动AD转换控制信号
        GPIO_InitTypeDef   GPIO_InitStructure;

        ALL_OS_GPIO_CLK_ENABLE();
        RST_RCC_GPIO_CLK_ENABLE();
        CONVST_RCC_GPIO_CLK_ENABLE();
		RANGE_RCC_GPIO_CLK_ENABLE();
        
        GPIO_InitStructure.Mode     = GPIO_MODE_OUTPUT_PP;      //推挽输出
        GPIO_InitStructure.Pull     = GPIO_PULLUP;              //上拉
        GPIO_InitStructure.Speed    = GPIO_SPEED_FREQ_HIGH;     //GPIO速度等级高速

		GPIO_InitStructure.Pin      = CONVST_PIN;				//CONVST引脚
        HAL_GPIO_Init( CONVST_PORT, &GPIO_InitStructure );

        GPIO_InitStructure.Pin = OS0_PIN;
        GPIO_InitStructure.Pin = OS1_PIN;
        GPIO_InitStructure.Pin = OS2_PIN;
        HAL_GPIO_Init( OS_PORT, &GPIO_InitStructure );

        GPIO_InitStructure.Pin = RST_PIN;
        HAL_GPIO_Init( RST_PORT, &GPIO_InitStructure );
		
		GPIO_InitStructure.Pin = RANGE_PIN;
        HAL_GPIO_Init( RANGE_PORT, &GPIO_InitStructure );
    } 
}

2、FSMC配置
[C] 纯文本查看 复制代码
void AD7606_FSMC_Config( void )
{
	SRAM_HandleTypeDef          AD7606_Handler;
	FMC_NORSRAM_TimingTypeDef   AD7606_Timing;
    /*
    AD7606规格书要求(3.3V通信电平下): RD读信号低电平脉宽最短21ns, 对应FMC的DataSetupTime
    CS片选和RD读信号独立方式的高电平最短脉宽15ns,CS片选和RD读信号并联方式的高电平最短脉宽22ns,此处按22ns, 对应FMC的AddressSetupTime
    */
    AD7606_Handler.Instance             	= FMC_NORSRAM_DEVICE;
    AD7606_Handler.Extended             	= FMC_NORSRAM_EXTENDED_DEVICE;

    AD7606_Handler.Init.NSBank              = FSMC_NORSRAM_BANK4;               //使用BANK2,即使用的片选FSMC_NE2
    AD7606_Handler.Init.DataAddressMux      = FSMC_DATA_ADDRESS_MUX_DISABLE;    //禁止地址数据复用
    AD7606_Handler.Init.MemoryType          = FSMC_MEMORY_TYPE_SRAM;            //存储器类型SRAM
    AD7606_Handler.Init.MemoryDataWidth     = FSMC_NORSRAM_MEM_BUS_WIDTH_16;    //16位总线宽度
    AD7606_Handler.Init.BurstAccessMode     = FSMC_BURST_ACCESS_MODE_DISABLE;   //关闭突发模式
    AD7606_Handler.Init.WaitSignalPolarity  = FSMC_WAIT_SIGNAL_POLARITY_LOW;    //关闭突发模式,此参数无效
    AD7606_Handler.Init.WaitSignalActive    = FSMC_WAIT_TIMING_BEFORE_WS;       //关闭突发模式,此参数无效
    AD7606_Handler.Init.WriteOperation      = FSMC_WRITE_OPERATION_ENABLE;     	//使能写保护
    
	AD7606_Handler.Init.WaitSignal          = FSMC_WAIT_SIGNAL_DISABLE;         //关闭突发模式,此参数无效
    AD7606_Handler.Init.ExtendedMode        = FSMC_EXTENDED_MODE_DISABLE;       //禁止扩展模式
    AD7606_Handler.Init.AsynchronousWait    = FSMC_ASYNCHRONOUS_WAIT_DISABLE;   //用于异步传输时间,使能或禁止等待信号,此处禁止
    AD7606_Handler.Init.WriteBurst          = FSMC_WRITE_BURST_DISABLE;         //禁止写突发
    AD7606_Handler.Init.ContinuousClock     = FSMC_CONTINUOUS_CLOCK_SYNC_ONLY;  //仅同步模式才做时钟输出
    AD7606_Handler.Init.WriteFifo           = FSMC_WRITE_FIFO_ENABLE;           //使能写FIFO
	
	//FMC读时序
    //FMC使用HCLK,主频168MHz,1个FMC时钟周期5.95ns
    AD7606_Timing.AddressSetupTime          = 4;                                //地址建立时间,4*5.95ns=23.8ns
    AD7606_Timing.AddressHoldTime           = 0;                               	//地址保持时间,模式A不适用
    AD7606_Timing.DataSetupTime             = 6;                                //数据保持时间,6*5.95ns=35.7ns
    AD7606_Timing.BusTurnAroundDuration     = 1;                                //不适用
    AD7606_Timing.CLKDivision               = 0;                               	//不适用
    AD7606_Timing.DataLatency               = 0;                               	//不适用
    AD7606_Timing.AccessMode                = FSMC_ACCESS_MODE_A;               //模式A
	
    //初始化SRAM控制器
    if ( HAL_SRAM_Init( &AD7606_Handler, &AD7606_Timing, NULL ) != HAL_OK )
    {
        //初始化错误
        Error_Handler( "HAL_SRAM_Init(file %s, function %s())\r\n", __FILE__, __LINE__ );
    }
}

3、AD7606初始化
[C] 纯文本查看 复制代码
void bsp_InitAD7606( void )
{ 	
	AD7606_GPIO_Config();                   //AD7606 GPIO引脚配置
    AD7606_FSMC_Config();                   //AD7606 FSMC通信配置

    AD7606_SetOS( AD_OS_NO );               //默认无过采样
    AD7606_SetInputRange( RANGE_10V );      //默认量程±10V
    AD7606_Reset();                         //复位
    CONVST_1();                             //启动转换的IO电平,默认设置为高
}

4、主函数
[C] 纯文本查看 复制代码
void demo_ad7606( void )
{
    uint8_t ucRefresh = 0;

    AD7606_SetOS( AD_OS_NO );
    AD7606_SetInputRange( RANGE_10V );
    AD7606_StartConvst();

    LED0( ON );
    LED1( OFF );

    bsp_StartAutoTimer( SoftTimer_LED, 200 );       //启动1个500ms自动重装的定时器
    bsp_StartAutoTimer( SoftTimer_AD7606, 500 );    //启动1个500ms自动重装的定时器

    while ( 1 )
    {
        bsp_Idle();

        if ( bsp_CheckTimer( SoftTimer_LED ) )
        {
            LED0_TOGGLE();
            LED1_TOGGLE();
        }

        if ( bsp_CheckTimer( SoftTimer_AD7606 ) )
        {
            AD7606_ReadNowAdc();
            AD7606_StartConvst();
            ucRefresh = 1;
        }

        if ( ucRefresh == 1 )
        {
            ucRefresh = 0;
            AD7606_Mak();
            AD7606_VoltDisp();
        }
    }
}

回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2025-1-7 16:49:57 | 显示全部楼层

首次发帖紧张了,补充接线方案如下:
[C] 纯文本查看 复制代码
接线方案:
		STM32F407     				AD7606模块
		5V         		-->      	+5V
        GND        		-->      	GND
		
		PD14/FSMC_D0	-->			D0
		PD15/FSMC_D1	-->			D1
		PD0/FSMC_D2		-->			D2
		PD1/FSMC_D3		-->			D3
		PE7/FSMC_D4		-->			D4
		PE8/FSMC_D5		-->			D5
		PE9/FSMC_D6		-->			D6
		PE10/FSMC_D7	-->			D7
		PE11/FSMC_D8	-->			D8
		PE12/FSMC_D9	-->			D9
		PE13/FSMC_D10	-->			D10
		PE14/FSMC_D11	-->			D11
		PE15/FSMC_D12	-->			D12
		PD8/FSMC_D13	-->			D13
		PD9/FSMC_D14	-->			D14
		PD10/FSMC_D15	-->			D15
		
		PD4/FSMC_NOE	<--      	RD
		PD5/FSMC_NWE
		PG9/FSMC_NE2    -->      	CS
		
		PB0        		-->      	OS0
		PB1        		-->      	OS1
		PB15        	-->      	OS2		
		PG6         	-->      	RST		
		PG7        		-->      	BUSY
		PG8				-->			RANGE
		
		PA3        		-->      	CA
		PA3        		-->      	CB

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-1-8 07:54:25 | 显示全部楼层
方便的话,把你的原理图接口这部分截图下,这个要首先核对。
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2025-1-8 09:24:58 | 显示全部楼层
eric2013 发表于 2025-1-8 07:54
方便的话,把你的原理图接口这部分截图下,这个要首先核对。

您好,原理图如下:
Snipaste_2025-01-08_09-23-51.png
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-1-9 07:07:16 | 显示全部楼层
liubin 发表于 2025-1-8 09:24
您好,原理图如下:

你这里实际用的NE2和NE4,你的接线说明和你的实际配置不符

  PG9/FSMC_NE2    -->          CS
AD7606_Handler.Init.NSBank              = FSMC_NORSRAM_BANK4;
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2025-1-9 09:10:50 | 显示全部楼层
eric2013 发表于 2025-1-9 07:07
你这里实际用的NE2和NE4,你的接线说明和你的实际配置不符

  PG9/FSMC_NE2    -->          CS

您好,确实是。接线说明中写的NE2,此处未更新与实际的代码不对应。代码中GPIO配置使用的PG12,对应NE4,FSMC初始化配置的时候用的BANK4,GPIO配置和FSMC配置应该是对应的。
读地址如下
[C] 纯文本查看 复制代码
//AD7606 FSMC总线地址,只读
#define AD7606_RESULT() *(__IO uint16_t *)0x6C000000  //FSMC_NE4对应的地址

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-1-10 07:53:50 | 显示全部楼层
liubin 发表于 2025-1-9 09:10
您好,确实是。接线说明中写的NE2,此处未更新与实际的代码不对应。代码中GPIO配置使用的PG12,对应NE4, ...

这个地方也对了之后,别的地方没有要特别注意的了,你再找找
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 08:53 , Processed in 0.049741 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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