using a timer to count pulses on STM32F7 - timer

I have a question about using a timer to count pulses form a encoder (only one pin) I don't care about the direction.
I'm tryning to use Timer 3, but I'm not sure how to set it up in CubeMx.
picture and text
I start it with:
HAL_TIM_Base_Start( mpEncoderTim );
And read with:
count = mpEncoderTim->Instance->CNT;
Hope anyone of you, have done this before, so you can give me a hint
thanks in advance and best regards
panduro..

Thanks.
I found the error, the timer period was set to 0, so the timer would never count higher than 0 :-(
best regards..

I'v had some kind of similar issue with stepper motor. I'v made a stepper driver code for (DRV8825, A4899 chips) , code is iRQ based and with maths for motor acceleration, speed and etc. But I had to test if it is accurate, so I had to count steps.
For testing case I configured concrete pin as ETR(external trigger input) - it is input pin,my stepper output pin goes to that input,(as for sure goes to motor too). And each rising or lowering edge(depends on configuration) generates an irq, so at irq I can set counter of steps, in your case pulses.
I am not familiar with cubeMX stuff, most of the time I write directly to register or using old SPL(standard peripherial drivers). I will show how it works with SPL as it should be more readable for cubeMX users.
Anyway I just try to show basic idea how to do it.This concrete code works on STM32f030
Firstly configure input pin (read datasheet just few pins can work as external triggers and with concrete timers)
void digital_input_config (void){
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_2);
}
Now you need a timer configuration, each timer has different pins with ETR, so it depends on your STM32 MCU.You have to read data sheet accurately.
void enable_capture_TIM1(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_ETRClockMode2Config(TIM1,TIM_ExtTRGPSC_DIV_NONE,TIM_ExtTRGPolarity_NonInverted,0x00);
TIM_SelectInputTrigger(TIM1,TIM_TS_ETRF);
TIM_SelectSlaveMode(TIM1,TIM_SlaveMode_Trigger);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM1_BRK_UP_TRG_COM_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM1, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_Trigger, ENABLE);
}
And at the IRQ you can do pulse counting.
void TIM1_BRK_UP_TRG_COM_IRQHandler(void){
if(TIM_GetITStatus(TIM1, TIM_IT_Trigger) != RESET) {
TIM_ClearITPendingBit(TIM1, TIM_IT_Trigger);
PulseCNT++;
}
}
I'v tested this code with pulse generator and it's really accurate, it can be used for pulse count, or frequency measuring.

Related

STM32L0 Freeze on setting NVIC/GPIO

I'm working with an STM32L073RZ CPU running MbedOS 5.11.2. Eventually I aim to get this working in a very low-power mode (STOP mode) that will be awoken with either an RTC interrupt or an interrupt from a peripheral device on pin PA_0 (WAKEUP_PIN_1). At the moment I am simply attempting to setup PA_0 as an interrupt using the STM32 HAL API. Please see my code below:
#include "mbed.h"
#define LOG(...) pc.printf(__VA_ARGS__); pc.printf("\r\n");
DigitalOut led(LED1);
Serial pc(USBTX, USBRX);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
led = !led;
}
int main()
{
pc.baud(9600);
led = 1;
// GPIO SETUP
LOG("Enabling GPIO port A clock");
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
LOG("Initialising PA_0");
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// NVIC SETUP
LOG("Setting IRQ Priority");
HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 1); // Priorities can be 0, 1, 2, 3 with lowest being highest prio
LOG("Enabling IRQ");
HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
LOG("Going into STOP mode");
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
}
As you can see, the code is broken into two sections: GPIO setup and NVIC setup. My issue is as follows:
If I perform GPIO setup before NVIC setup then the program seems to hang on HAL_NVIC_SetPriority(), however, if I perform NVIC setup before GPIO setup then the code seems to hang on HAL_NVIC_EnableIRQ().
I am completely stumped as to what is causing this. Any insight is greatly appreciated.
You don't need to do this manually. As long as you run Mbed OS in tickless mode (set MBED_TICKLESS=1 macro in your mbed_app.json) the MCU will automatically enter stop mode whenever all threads are idle. If you want to wake up you can either use an InterruptIn on the pin or use a LowPowerTicker.
If you're looking for the absolute lowest power modes, you can use the standby feature (without RAM retention) for which there's a library here: stm32-standby-rtc-wakeup.

STM32F401RE Nucleo board, cannot toggle user LED

I am trying to figure out how to toggle an LED on the Nucleo board and I just don't see the User LED toggle. Looking online it seems this is all you have to do. Has anyone else encountered this issue?
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
int main(void)
{
int counter = 0;
SystemInit();
GPIO_InitTypeDef temp;
temp.GPIO_Mode = GPIO_Mode_OUT;
temp.GPIO_OType = GPIO_OType_PP; // Push Pull
temp.GPIO_Pin = GPIO_Pin_5;
temp.GPIO_Speed = GPIO_Low_Speed;
temp.GPIO_PuPd = GPIO_PuPd_NOPULL;
RCC_APB2PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_Init( GPIOA, &temp );
while( 1 )
{
if ( counter++ > 10000 )
{
GPIO_ToggleBits( GPIOA, GPIO_Pin_5 );
counter = 0;
}
}
}
You have to write
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
in order to enable GPIOA.
You cannot enable an AHB1 peripheral clock using the AHB2 clock control.
RCC_APB2PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
^^^^ ^^^
"I just don't see the User LED toggle."
Even when you correctly enable the GPIO clock, you are toggling the output very fast (MHz order) and counter serves no obvious purpose. If a flashing LED was your aim, that will not do it; you'll just see an LED at somewhat less than full brightness - you need a delay between each toggle.
Clifford is absolutely right, the LED is "toggling" way to fast. The STM32F401RE supposedly is running at 168Mhz. Change your counter value from 10.000 to e.g. 50.000.000 to see the LED toggling at an appropriate rate.

STM32F4 interrupt handler for capture its not called

The code below uses the capture compare feature of TIM1 channel 3 to capture rising edge on PE10, but its not working, the interrupt handler its not called. I am not that good at this embedded stuff, so can somebody tell me if I am settings this correctly ?
#include "STM32/stm32f4xx_tim.h"
void TIM1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
/* TIM1 channel 3 pin (PE.10) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Connect TIM pins to AF2 */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_TIM1);
/* Enable the TIM1 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM1, &TIM_ICInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
/* Enable the CC3 Interrupt Request */
TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
}
void TIM1_CC_IRQHandler(void)
{
// .................
}
int StartCapture()
{
TIM1_Config();
while(1); /* Infinite loop */
}
If your TIM1_CC_IRQHandler() is getting called ONCE, then Dracog71's answer is correct. However, if your IRQHandler() is never firing, then there's something wrong in the initialization.
Here's a list of things you have to get right or the IRQ won't fire.
1) Make sure that the GPIO[A:E] clock is enabled for the pin you are using.
2) Likewise, make sure the clock is enabled for the TIMx you are using. Check where your TIMx lives. If you call RCC_APB2PeriphClockCmd() for a timer that lives on APB1, the compiler won't throw an error, but your timer will never work.
3) Double-check your pin's AF matches the datasheet's Alternative Function Mapping table (eg. AF1 == TIM1_CH3).
4) In your TIM_ICInitStructure, make sure TIM_Channel matches the channel you have chosen (in your case TIM_Channel_3).
5) Configure and enable the correct IRQ channel in the NVIC, eg. NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
6) Enable the interrupt: TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
7) Enable your timer: TIM_Cmd(TIM1, ENABLE);
Well, I guess my answer isn't required after 6 years. But maybe somebody else facing same problem will find it.
There may be a name conflict if you write in c++. If original prototype of interupt function is defined like C-function, and your implementation is C++function so it's just two different functions with the same name, and interupt will try to call an empty C-function or even may stack in endless loop. So that is why your c++ function may be newer called.
To solve this, just define your function like extern "C".
Maybe the interrupt enters the functions but does not know what to do, or enter ant he flag is still active and just enters once, you're missing the clear interrupt flag, try this:
/**
* #brief Capture Compare Handler
* #param None
* #retval None
*/
void TIM1_CC_IRQHandler()
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC3) != RESET) <-- Add this
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC3); <-- This is important!
//TODO
}
}

How to initialize I2C on STM32F0?

Recently I've been trying to get the I2C bus working on the STM32F030F4P6 MCU, but with little luck.
I'm using an STM32F0 module and have found plenty of resources for the STM32F1 module I2C initialization, but nothing specific about the STM32F0 initialization/transfer process.
Here's my initialization code:
void i2c_init(uint8_t ownAddress)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// Enable GPIOA clocks
RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
// Configure I2C1 clock and GPIO
GPIO_StructInit(&GPIO_InitStructure);
/* I2C1 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* I2C1 SDA and SCL configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* I2C1 Reset */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
/* Configure I2C1 */
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
//I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = ownAddress;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
//I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
In order to test to see if my setup was correct I designed some I2C transmission code that would transfer data in a never ending loop. Here's the code for that:
while(1)
{
I2C_SlaveAddressConfig(I2C1, RegName);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_NumberOfBytesConfig(I2C1, 8);
I2C_SendData(I2C1,0b00000000);
I2C_GenerateSTOP(I2C1, ENABLE);
}
Where:
RegName = 0x75
SDA = GPIO_PIN_10 on GPIOA
SCL = GPIO_PIN_9 on GPIOA
I2C = I2C1
ownAdrress = 0x68
When I scope the I2C lines after I start this code I get a floating voltage around 160mV. When I step through the code every one of the I2C function calls happen and complete, so that's why I was thinking that it had something more so to do with my initialization of the pins themselves.
My problem is very similar to this thread, but was never answered:
https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F0%20I2C%20code%20doesn%27t%20work&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=1342
Edit 1: Here's my latest code; still not working (Edit 2: Updated to what I currently have; moved things into more correct locations):
void i2c_init(uint8_t ownAddress)
{
/* TypeDefs for GPIOA and I2C1 */
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/* Enable GPIOA clocks and I2C1 clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Configure I2C1 clock and GPIO */
GPIO_StructInit(&GPIO_InitStructure);
/* I2C1 SDA and SCL configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //UP
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
/* GPIO AF Configuration -> GPIO_AF_1: USART2, CEC, Tim3, USART1, USART2,EVENTOUT, I2C1, I2C2, TIM15 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* I2C1 Reset */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
//I2C_DeInit(I2C1);
/* Configure I2C1 */
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1 = ownAddress;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
//I2C_AcknowledgeConfig(I2C1, ENABLE);
}
As you can see I added the two lines GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); and GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); where I found that GPIO_AF_1 had the alternate function of I2C1 from the STM32F0 Standard Peripheral bibliotheek.
Any other ideas? I've been playing around with the clocks to see if that changed anything and have been adding snippets of other people's code just to see if that has any effect on the output of my device.
Edit 3: I have tried pulling both the SDA and SCL lines up to VCC with a 1kohm resistor as instructed by this guide: https://electronics.stackexchange.com/questions/57121/i2c-pullup-resistor-calculations
->(3.3V-0.4)/3mA ~= 1kohm
Edit 4: After going through my code line by line I tried outputting various flag bit registers. Specifically these registers: isr = I2C1->ISR;, cr1 = I2C1->CR1;, and cr2 = I2C1->CR2;
The flag I get after initiating the I2C transfer handling with I2C_TransferHandling(I2C1, 0x02, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); was 0x8001 which can be deciphered down to two errors:
#define I2C_ISR_BUSY ((uint32_t)0x00008000) /*!< Bus busy */
and
#define I2C_ISR_TXE ((uint32_t)0x00000001) /*!< Transmit data register empty */
I've found some work arounds at this link here (remove the space after https: to go to the link -> stack overflow won't let me post more than 1 link for some reason): https: //my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FSTM32L151RB%20I2C%20Busy%20flag%20always%20set&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=690 that I'm looking to implement and will report back as soon as I try them out.
I have I2C working as master and slave on the F0. The main issue I can see with your code is that in master mode you absolutely must set the I2C_Timing initialisation structure member. See RM0091 for sample values that correspond to the frequency you want to generate on SCL. In slave mode the clock is recovered from the master so the timing member doesn't appear to be used.
As the others have said, external pullups to Vcc on SCL and SDA are not optional and must be present once per bus not per peripheral as you incorrectly stated in a comment. You were right to use the calculator to choose suitable values because the internal pullups in the STM32 at about 30-50K are far too weak for use as I2C pullups.
The problem is that you don't configure proper AF (Alternate Function) source for I2C pins. After reset registers that configure AF are all 0, and I2C's function is 1, so your I2C peripheral is in fact disconnected from the GPIOs.
Technically it makes no difference when you configure that, but it's best to do that before GPIO configuration to minimize any unwanted transitions on the pins.
Edit: You MUST have the pullups on the I2C pins - without them you have "low" level there, and I2C peripheral detects that as bus error, which obviously prevents it from working properly. Either connect external resistors, or at least enable internal pullups instead of "no pullups/no pulldowns" configuration.
Moreover - it's just not possible for an "open drain" pin to work properly without pullup.
The Core of Cortex M0 is different then Core of Cortex M3, STM32f030f4 has AHB and APB1 (bridged) only. The C code of STM32f1xx never be run under STM32f0xx.
Use STM32F0xx_Snippets_Package for solve your key problems.
I just noticed this too:
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
So you have disabled the clock after you enabled it. I don't see where you have re-enabled it later.
I notice that you are mapping the pins to AF_1 and that is for the UART function.
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
You need to map them to AF_4 to use the I2C function.
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_4);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_4);

Analogue input pins PA8, PA11 and PA12 not working on STM32F103RB

Working on a simple ADC project reading voltages from a potential divider on a number of channels. I am using the STM32f103rb on a commercial and well made PCB. I am reading pins on PORTA and the following pins work and return a voltage:
PA0, PA1, PA4, PA5, PA6, PA7.
However the following pins do not work and return a raw value of around 2000-2700 approx:
PA8, PA11 and PA12.
The nature of the project and the fact that the PCB is of a fixed design means that we are stuck with these pin selections. The datasheet is quite specific about these pins being usable as AIN. All set-up and config is as per standard STM32, taken from basic example code and modified for our purposes. The included code is a debugging version we made in an attempt to find the cause but to no avail.
Voltage at the pins has been measured and is correct for the type of voltage divider.
Any help would be greatly appreciated on this.
/* 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);
}
//*****************************************************************************
I have never worked with this chip, but after looking at the hardware data sheet for 5 minutes I came up with the following naive conclusions:
The chip has 2 ADCs with 8 channels each, a total of 16.
PA0, PA1, PA4, PA5, PA6, PA7 sounds as if they will belong to the first ADC.
I then assume that PA8, PA11 and PA12 belong to the second ADC, called ADC2 by ST.
Your code seems to only ever mention and initialize ADC1. No trace of ADC2.
Maybe these pins don't work because you haven't even initialized or activated the ADC they belong to?
Also, you should check the data sheet for contention due to those pins being used as "Alternate Function".
Typically, they will list what needs to be done/disconnected in order to utilize the pins without contention (e.g. disconnect some resistor)

Resources