首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >模拟输入引脚PA8、PA11和PA12不工作在STM32F103RB上

模拟输入引脚PA8、PA11和PA12不工作在STM32F103RB上
EN

Stack Overflow用户
提问于 2014-02-13 11:56:01
回答 2查看 3.1K关注 0票数 2

在一个简单的ADC项目上工作,从多个通道上的电位分配器读取电压。我使用的STM32f103rb在一个商业和良好的印刷电路板。我正在读取PORTA上的引脚,下面的引脚工作并返回一个电压:

PA0,PA1,PA4,PA5,PA6,PA7。

但是,下列引脚不工作,并返回大约2000-2700左右的原始值:

PA8,PA11和PA12。

该项目的性质和事实,PCB是一个固定的设计,这意味着我们坚持这些针的选择。数据表非常具体地说明这些引脚可以作为AIN使用。所有的设置和配置都按照标准的STM32,从基本示例代码中提取,并为我们的目的进行了修改。所包含的代码是我们尝试查找原因的调试版本,但没有结果。

在引脚处的电压已经被测量,并且对分压器的类型是正确的。

如果能提供任何帮助,我们将不胜感激。

代码语言:javascript
运行
复制
    /* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stdio.h"
#include "stdlib.h"

// Standard STM peripheral config functions
void RCC_Configuration(void);
void GPIO_Configuration(void);

// ADC config - STM example code
void NEW_ADC_Configuration(void);

// Function to read ADC channel and output value
u16 NEW_readADC1(u8 channel);


// Variables
double voltage_su;          // Variable to store supply voltage
double voltage7;
double voltage8;

//*****************************************************************************
// Main program
int main(void)
{
    // Initialise peripheral modules
    RCC_Configuration();
    GPIO_Configuration();
    NEW_ADC_Configuration();

    // Infinate loop
    while (1)
    {       

        // Get value of supply voltage and convert
        voltage_su =  (((3.3 * NEW_readADC1(ADC_Channel_12)) / 4095));

    }
}
//*****************************************************************************
// STM RCC config
void RCC_Configuration(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);   // Connect PORTC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   // Connect PORTB...
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   // Connect PORTA...
}
//*****************************************************************************
// STM GPIO config
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;    // Value for setting up the pins

    // Sup
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

}
//*****************************************************************************
void NEW_ADC_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    ADC_InitTypeDef ADC_InitStructure;  // Varibale used to setup the ADC
    RCC_ADCCLKConfig(RCC_PCLK2_Div4);   // Set ADC clock to /4

    // Enable ADC 1 so we can use it
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    // Conenct the port A to peripheral clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    // Restore to defaults
    ADC_DeInit(ADC1);

    /* ADC1 Configuration ----------------------------------------------------*/
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    // Scan 1 at a time
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    // No continuous conversions - do them on demand
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    // Start conversion on software request - not bu external trigger
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    // Conversions are 12 bit - put them in the lower 12 bits of the result 
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    // How many channels are to be sued by the sequencer
    ADC_InitStructure.ADC_NbrOfChannel = 1;

    // Setup ADC
    ADC_Init(ADC1, &ADC_InitStructure);
    // Enable ADC 1
    ADC_Cmd(ADC1, ENABLE);

    // Enable ADC1 reset calibaration register
    ADC_ResetCalibration(ADC1);
    // Check end of reset calib reg
    while(ADC_GetResetCalibrationStatus(ADC1));
    //Start ADC1 calib
    ADC_StartCalibration(ADC1);
    // Check the end of ADC1 calib
    while(ADC_GetCalibrationStatus(ADC1));
}
//*****************************************************************************
// Function to return the value of ADC ch
u16 NEW_readADC1(u8 channel)
{
    // Config the channel to be sampled
    ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);
    // Start the conversion
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    // Wait until conversion complete
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
    // Get the conversion value
    return ADC_GetConversionValue(ADC1);
}
//*****************************************************************************
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-13 12:57:56

我从来没有使用过这个芯片,但是在看了5分钟的硬件data sheet之后,我得出了以下天真的结论:

  • 该芯片有2个模数转换器,每个通道有8个通道,共有16个通道。
  • PA0,PA1,PA4,PA5,PA6,PA7听起来好像是属于第一个ADC。
  • 然后,我假设PA8、PA11和PA12属于第二个ADC,ST称为ADC2。
  • 您的代码似乎只提到并初始化了ADC1。没有ADC2的痕迹。

也许这些引脚不起作用是因为你还没有初始化或激活它们所属的ADC?

票数 5
EN

Stack Overflow用户

发布于 2014-02-14 06:34:09

此外,您应该检查数据表的争用,因为这些引脚被用作“备用函数”。

通常,它们会列出需要做什么/断开连接才能使用引脚而没有争用(例如断开一些电阻器)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21753553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档