OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5439|回复: 5

ADC采集问题,使用AD7606芯片采集电压,当输入负电压时采集不正常???

[复制链接]

13

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
288
金钱
288
注册时间
2018-10-30
在线时间
26 小时
发表于 2019-10-30 09:39:48 | 显示全部楼层 |阅读模式
2金钱
使用AD7606模数芯片采集电压,输入电压范围是-10V~+10V,输入为正电压时采集值正常,输入负压时,采集到的值始终不能为负值,求解???代码如下:


#include "adc7606.h"
#include "delay.h"

//-----------------------------------------------------------*
//左AD7606,右STM32
//*DB[0...15]-->fsmc_d[0...15]: 并行输出数据位接口
//*RD/CLK-->D4_FSMC_NOE:                并行数据读取控制输入口,低电平启动输出总线
//*CS-->G12_FSMC_NE4:                        片选,低电平使能数据传输(RD/CS均低电平时使转换结果输出在总线)
//*BUSY-->E2:                                        高电平为转换状态,下降沿转换数据被锁存至数据寄存器
//*RESET-->E3:                                        复位输入,设置高电平,上升沿复位,转换期间加脉冲转换中断,读取期间加脉冲输出寄存器内容复位至0
//*OS[0..2]-->F13/14/15:                过采样模式,用于选择过采样倍率
//*CONVST_A/B-->C7(TIM3-CH2):                        用于(上升沿)启动模拟输入通道转换(采样控制)

//更改:
//*RD/CLK-->D4_FSMC_NOE:
//*CS-->G12_FSMC_NE4:——>D7
//*BUSY-->E2:——>PD3
//*RESET-->PE3:——>PD5
//*OS[0..2]-->PF13/14/15:——>PB5/6/7
//*CONVST_A/B-->PC7(TIM3-CH2):——>PC8
//*FRSTDATAD2
//-----------------------------------------------------------*


//*--------------------------过采样IO--------------------
#define adc_os0_1() GPIO_SetBits(GPIOB,GPIO_Pin_5)
#define adc_os0_0() GPIO_ResetBits(GPIOB,GPIO_Pin_5)
#define adc_os1_1() GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define adc_os1_0() GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define adc_os2_1() GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define adc_os2_0() GPIO_SetBits(GPIOB,GPIO_Pin_7)

//*------------------------复位IO-----------------------
#define adc_reset_1()   GPIO_SetBits(GPIOD,GPIO_Pin_5)                       //高电平复位
#define adc_reset_0()   GPIO_ResetBits(GPIOD,GPIO_Pin_5)

//*-----------------------ADC转换启动IO-----------------
#define convstAB_1() GPIO_SetBits(GPIOC,GPIO_Pin_8)  
#define convstAB_0() GPIO_ResetBits(GPIOC,GPIO_Pin_8)  

//*-----------------------RD读数据控制IO-----------------
#define adc_RD_1() GPIO_SetBits(GPIOD,GPIO_Pin_4)  
#define adc_RD_0() GPIO_ResetBits(GPIOD,GPIO_Pin_4)  

//*--------------------bank1,sector1起始地址---------------
#define FSMC_Base ((u32)(0x60000000))

//*------------采集值读取保存------------------------------
int16_t Read_FSMCData[8] = {0};

//*-------------已读取值转换保存---------------------------
float Data_save[8];

//*-------------------函数---------------------------------------------------

//ADC过采样设置函数
void Adc_7606_SetOS(void)
{
        //100,过采样倍率为16
        adc_os2_1();
        adc_os1_0();
        adc_os0_0();

}

//ADC硬件复位函数
void Adc_7606_Reset(void)
{
        adc_reset_0();        // 退出复位状态
        adc_reset_1();        // 进入复位状态
        delay_us(100);   // 仅用于延迟。 RESET复位高电平脉冲宽度最小50ns。
        adc_reset_0();  // 退出复位状态

}


//ADC硬件初始化设置函数
void Adc_7606_Init(void)
{
        //1.设置过采样
        Adc_7606_SetOS();
       
        //2.硬件复位
        Adc_7606_Reset();
       
        //3.设置启动转换初始状态
        convstAB_1();
       
        //4.启动PWM驱动
        Adc_CONVST_AB_Pwm();
}


//初始化
//*DB[0...15]-->fsmc_d[0...15]:
//*RD/CLK-->PD4_FSMC_NOE:               
//*CS-->PG12:-->PD7                               
void Adc_FSMC_GPIOInit(void)
{
       
        GPIO_InitTypeDef GPIO_InitStruct;
       
        //1.使能GPIO时钟
        RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE );//PD,PE,PG
        //2.使能FSMC时钟
        RCC_AHB3PeriphClockCmd( RCC_AHB3Periph_FSMC, ENABLE );
       
        //3.GPIO初始化
       
        //数据线 PD0,1,8,9,10,14,15(7606DB),读信号线 PD4(7606RD-fsmc_NOE)
        GPIO_InitStruct.GPIO_Mode          = GPIO_Mode_AF;//复用模式
        GPIO_InitStruct.GPIO_OType         = GPIO_OType_PP;//推挽输出
        GPIO_InitStruct.GPIO_PuPd          = GPIO_PuPd_UP;//上拉
        GPIO_InitStruct.GPIO_Speed   = GPIO_Speed_100MHz;//速度
        GPIO_InitStruct.GPIO_Pin         = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_4;//端口
        GPIO_Init( GPIOD, &GPIO_InitStruct );//初始化端口配置
       
        //数据线 PE7~PE15(7606DB)
        GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF;//复用输出
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_UP;//上拉
        GPIO_InitStruct.GPIO_Pin   = ( 0X1FF<<7 );//PE7~15,AF OUT
    GPIO_Init( GPIOE, &GPIO_InitStruct );//初始化  
       
        //片选控制线 (7606CS-fsmc_NE1)
        GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF;//复用输出
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_UP;//上拉
        GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_7;//PD7
    GPIO_Init( GPIOD, &GPIO_InitStruct );//初始化  
        GPIO_ResetBits(GPIOD,GPIO_Pin_7);  //片选始终低电平选择
       
        //4.端口复用映射配置
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource14, GPIO_AF_FSMC ); //DB0
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource15, GPIO_AF_FSMC ); //DB1
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource0, GPIO_AF_FSMC ); //DB2
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource1, GPIO_AF_FSMC ); //DB3
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource7, GPIO_AF_FSMC ); //DB4
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource8, GPIO_AF_FSMC ); //DB5
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource9, GPIO_AF_FSMC ); //DB6
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource10, GPIO_AF_FSMC ); //DB7
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource11, GPIO_AF_FSMC ); //DB8
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource12, GPIO_AF_FSMC ); //DB9
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource13, GPIO_AF_FSMC ); //DB10
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource14, GPIO_AF_FSMC ); //DB11
        GPIO_PinAFConfig( GPIOE, GPIO_PinSource15, GPIO_AF_FSMC ); //DB12
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource8, GPIO_AF_FSMC ); //DB13
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource9, GPIO_AF_FSMC ); //DB14
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource10, GPIO_AF_FSMC ); //DB15
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource4, GPIO_AF_FSMC ); //RD
        GPIO_PinAFConfig( GPIOD, GPIO_PinSource7, GPIO_AF_FSMC ); //CS
       
}

//FSCM配置
void Adc_FSMC_Config(void)
{
        FSMC_NORSRAMTimingInitTypeDef FSMC_ReadWriteTimingStruct;
        FSMC_NORSRAMInitTypeDef        FSMC_NORSRAMInitStruct;
       
        Adc_FSMC_GPIOInit();
       
        //--------------读写时序设置-----------------------
        FSMC_ReadWriteTimingStruct.FSMC_AddressSetupTime          = 3;//地址建立时间,最短15ns,1HCLK=1/168Mhz=5.952ns,需至少3*1HCLK
        FSMC_ReadWriteTimingStruct.FSMC_AddressHoldTime           = 0;//地址保持时间
        FSMC_ReadWriteTimingStruct.FSMC_DataSetupTime                   = 5;//数据建立时间,最短21ns,需至少4*1HCLK
        FSMC_ReadWriteTimingStruct.FSMC_BusTurnAroundDuration = 1;//读操作后在总线上的延迟,最短6ns,需至少1HCLK
        FSMC_ReadWriteTimingStruct.FSMC_CLKDivision           = 0;//定义CLK时钟输出信号的周期
        FSMC_ReadWriteTimingStruct.FSMC_DataLatency                          = 0;
        FSMC_ReadWriteTimingStruct.FSMC_AccessMode                           = FSMC_AccessMode_A;//访问时序模式

        //1.初始化FSMC存储器配置
        FSMC_NORSRAMInitStruct.FSMC_Bank                                             = FSMC_Bank1_NORSRAM1;//存储块标号与区号       
        FSMC_NORSRAMInitStruct.FSMC_DataAddressMux                                 = FSMC_DataAddressMux_Disable;//地址/数据复用使能,若使能地址和数据有共用数据总线的部分
        FSMC_NORSRAMInitStruct.FSMC_MemoryType                                  = FSMC_MemoryType_SRAM;//存储器类型
        FSMC_NORSRAMInitStruct.FSMC_MemoryDataWidth                          = FSMC_MemoryDataWidth_16b;//数据宽度
        FSMC_NORSRAMInitStruct.FSMC_BurstAccessMode                          = FSMC_BurstAccessMode_Disable;
        FSMC_NORSRAMInitStruct.FSMC_AsynchronousWait                  = FSMC_AsynchronousWait_Disable;
        FSMC_NORSRAMInitStruct.FSMC_WaitSignalPolarity                   = FSMC_WaitSignalPolarity_Low;
        FSMC_NORSRAMInitStruct.FSMC_WrapMode                                  = FSMC_WrapMode_Disable;
        FSMC_NORSRAMInitStruct.FSMC_WaitSignalActive                          = FSMC_WaitSignalActive_BeforeWaitState;
        FSMC_NORSRAMInitStruct.FSMC_WriteOperation                          = FSMC_WriteOperation_Enable;//写使能设置
        FSMC_NORSRAMInitStruct.FSMC_WaitSignal                                  = FSMC_WaitSignal_Disable;
        FSMC_NORSRAMInitStruct.FSMC_ExtendedMode                          = FSMC_ExtendedMode_Disable;//扩展模式时序使能设置(只有读时序不需要扩展)
        FSMC_NORSRAMInitStruct.FSMC_WriteBurst                                  = FSMC_WriteBurst_Disable;
        FSMC_NORSRAMInitStruct.FSMC_ReadWriteTimingStruct          = &FSMC_ReadWriteTimingStruct;//读时序配置指针
        FSMC_NORSRAMInitStruct.FSMC_WriteTimingStruct                  = &FSMC_ReadWriteTimingStruct;//写时序配置指针
        FSMC_NORSRAMInit( &FSMC_NORSRAMInitStruct );        //初始化配置
       
        //使能Bank1
        FSMC_NORSRAMCmd( FSMC_Bank1_NORSRAM1, ENABLE );
       
}

//初始化
//*RESET-->PE3:        -->PD5                        复位输入,设置高电平,上升沿复位,转换期间加脉冲转换中断,读取期间加脉冲输出寄存器内容复位至0
//*OS[0..2]-->PF13/14/15:                过采样模式,用于选择过采样倍率-->PB5/6/7
void Adc_OtherCtrl_GPIOInit(void)
{
       
        GPIO_InitTypeDef GPIO_InitStruct;
       
        //1.使能GPIO时钟
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD,ENABLE );
       
        //2.初始化端口模式
       
        //RESET
        GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_OUT;//普通输出模式
        GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
        GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_DOWN;//下拉
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
        GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_5;//端口
        GPIO_Init( GPIOD, &GPIO_InitStruct );//初始化配置
       
        GPIO_ResetBits( GPIOD, GPIO_Pin_5 );//复位端口默认电平
       
        //OS[0..2]
        GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_OUT;//普通输出模式
        GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
        GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_DOWN;//下拉
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
        GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;//端口
        GPIO_Init( GPIOB, &GPIO_InitStruct );//初始化配置

}


//pwm波启动转换
//*CONVST_A/B-->PC7(TIM3-CH2):        用于(上升沿)启动模拟输入通道转换(采样控制)-->PC8(TIM3-CH3)
void Adc_CONVST_AB_Pwm(void)
{

        GPIO_InitTypeDef GPIO_InitStruct;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
        TIM_OCInitTypeDef TIM_OCInitStruct;
       
        TIM_DeInit( TIM3 );//定时器复位
       
        //1.使能GPIO时钟和定时器时钟
        RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOC, ENABLE );//GPIO时钟使能
        RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE);//定时器时钟使能
       
        //2.端口模式初始化(复用功能)
        GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF;
        GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_UP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_8;
        GPIO_Init( GPIOC, &GPIO_InitStruct );
       
        //3.复用映射配置
        GPIO_PinAFConfig( GPIOC,GPIO_PinSource8, GPIO_AF_TIM3 );
       
        //4.定时器初始化
        TIM_TimeBaseInitStruct.TIM_Period                  = 2000-1;//重装载值,200ms采样(驱动)一次
        TIM_TimeBaseInitStruct.TIM_Prescaler          = 8400-1;        //预分频84MHz/8400 = 100us
        TIM_TimeBaseInitStruct.TIM_CounterMode   = TIM_CounterMode_Up;//计数模式(向上);
        TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStruct );//初始化配置
       
       
        //5.PWM模式配置(TIM3_CH3)
        TIM_OCInitStruct.TIM_OCMode                  = TIM_OCMode_PWM2;//模式设置(输出比较/PWM)通道3       
        TIM_OCInitStruct.TIM_OutputState  = TIM_OutputState_Enable;//输出使能
        TIM_OCInitStruct.TIM_OCPolarity   = TIM_OCPolarity_Low;//输出极性
        TIM_OCInitStruct.TIM_Pulse                  = 1000;//占空比设置(重装载值的一半)
        TIM_OC3Init( TIM3, &TIM_OCInitStruct );//初始化
       
        //6.定时器使能
        TIM_OC3PreloadConfig( TIM3, TIM_OCPreload_Enable );
        TIM_ARRPreloadConfig( TIM3, ENABLE );
        TIM_Cmd(TIM3,ENABLE);

}


//外部中断控制线初始化
//*BUSY-->PE2:  -->PD3                高电平为转换状态,下降沿转换数据被锁存至数据寄存器
//在转换期间读取数据
void Adc_Busy_ExtiInit(void)
{

        GPIO_InitTypeDef GPIO_InitStruct;
        EXTI_InitTypeDef EXTI_InitStruct;
        NVIC_InitTypeDef NVIC_InitStruct;
       
        //1.使能GPIO时钟
        RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOD, ENABLE );
       
        //2.初始化端口为输入模式
        GPIO_InitStruct.GPIO_Mode         = GPIO_Mode_IN;//输入模式
        GPIO_InitStruct.GPIO_OType         = GPIO_OType_PP;//
        GPIO_InitStruct.GPIO_PuPd          = GPIO_PuPd_UP;//上拉
        GPIO_InitStruct.GPIO_Speed          = GPIO_Speed_100MHz;//速度
        GPIO_InitStruct.GPIO_Pin         = GPIO_Pin_3;//端口
        GPIO_Init( GPIOD, &GPIO_InitStruct );
       
        //3.开启系统SYSCFG时钟,设置IO中断映射
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);//开启SYSCFG时钟
        SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOD, EXTI_PinSource3 );//设置外部中断映射
       
        //4.初始化线上中断,设置中断触发条件()
        EXTI_InitStruct.EXTI_Mode         =  EXTI_Mode_Interrupt;//中断模式
        EXTI_InitStruct.EXTI_Trigger =  EXTI_Trigger_Rising;//触发边沿(上升沿)
        EXTI_InitStruct.EXTI_Line         =  EXTI_Line3;//中断线       
        EXTI_InitStruct.EXTI_LineCmd = ENABLE;//使能
        EXTI_Init( &EXTI_InitStruct );
       
        //5.配置中断(NVIC)分组优先级
        NVIC_InitStruct.NVIC_IRQChannel                                           =  EXTI3_IRQn; //中断通道
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority  =  2;//抢占优先级
        NVIC_InitStruct.NVIC_IRQChannelSubPriority                   =  1; //响应优先级
        NVIC_InitStruct.NVIC_IRQChannelCmd                                   =  ENABLE; //使能
        NVIC_Init( &NVIC_InitStruct );
       
}



//外部中断服务函数
//读转换数据
u8 ReadData_Flag = 0;
void EXTI3_IRQHandler(void)
{
        u8 i;
        if( EXTI_GetITStatus( EXTI_Line3 )!=RESET )
        {
            //从FSMC读取转换值
                for( i = 0; i<8; i++ )
                {
//                   adc_RD_0( );//RD拉低,FSMC自动控制
                   Read_FSMCData = *( u16 * ) ( FSMC_Base );//16位数据宽度,HADDR[0]没有用到
//                   adc_RD_1( );//RD拉高,FSMC自动控制
                }
                ReadData_Flag = 1;//读取转换值标志位置位
        }
        EXTI_ClearITPendingBit( EXTI_Line3 );//清除外部中断标志位
}


//采集的数字信号值转换为模拟信号值函数
void Adc_7606_Value(void)
{
        //8个通道
        Data_save[0] =  Read_FSMCData[0] *( 10.0/32767 ) ;
        Data_save[1] =  Read_FSMCData[0] *( 10.0/32767 ) ;
        Data_save[2] =  Read_FSMCData[0] *( 10.0/32767 ) ;
        Data_save[3] =  Read_FSMCData[0] *( 10.0/32767 ) ;
        Data_save[4] =  Read_FSMCData[0] *( 10.0/32767 ) ;
        Data_save[5] =  Read_FSMCData[0] *( 10.0/32767 ) ;
        Data_save[6] =  Read_FSMCData[0] *( 10.0/32767 ) ;
        Data_save[7] =  Read_FSMCData[0] *( 10.0/32767 ) ;

}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2019-10-31 02:46:42 | 显示全部楼层
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2019-11-15
在线时间
5 小时
发表于 2020-5-4 21:30:53 | 显示全部楼层
负是从最大1111 1111 1111 1111开始,-10/-5为1000 0000 0000 0000
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2019-12-2
在线时间
11 小时
发表于 2020-10-28 22:12:21 | 显示全部楼层
您好,可以分享一下完整例程吗,有偿,非常感谢!!!!
回复

使用道具 举报

0

主题

9

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2020-12-2
在线时间
2 小时
发表于 2020-12-2 17:26:10 来自手机 | 显示全部楼层
你好,您好,可以分享一下完整例程吗,有偿,非常感谢!!!!
回复

使用道具 举报

0

主题

9

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2020-12-2
在线时间
2 小时
发表于 2020-12-2 17:26:33 来自手机 | 显示全部楼层
vaeiiiiiloveyou 发表于 2020-10-28 22:12
您好,可以分享一下完整例程吗,有偿,非常感谢!!!!

请问你弄好了么?
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-30 04:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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