中级会员
 
- 积分
- 288
- 金钱
- 288
- 注册时间
- 2018-10-30
- 在线时间
- 26 小时
|
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
//*FRSTDATA D2
//-----------------------------------------------------------*
//*--------------------------过采样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 ) ;
}
|
|