ADC de conversion unique sur STM32
Je suis étudiant en ADC programmation des microcontrôleurs STM32 F103x et en commençant par le cas le plus simple - simple conversion.
Le capteur de température interne (ADC1) la valeur est mesurée et de l'envoyer à port COM en utilisant USART. Un objectif semble clair, mais quand j'essaie de télécharger le code source de flash, il n'envoie pas toutes les données pour le port COM. USART fonction fonctionne bien, je pense que les problèmes viennent de l'ADC configuration de la partie parce que je suis d'être pendu dans la boucle d'attente conversion complète:
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //Wail for conversion complete
Voici mon code source si loin.
/* Includes ------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>
uint16_t AD_value;
const uint16_t V25 = 1750; //when V25=1.41V
const uint16_t Avg_Slope = 5; //when avg_slc
uint16_t TemperatureC;
//Define output device
PUTCHAR_PROTOTYPE
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{}
return ch;
}
void Usart1Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
/* COnfig PA9 for USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* COnfig PA10 for USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USARTx configured as follow:
- BaudRate = 9600 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* USART configuration */
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
int main(void)
{
ADC_InitTypeDef ADC_InitStructure;
Usart1Init();
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADCCLK = PCLK22/6 = 72/6=12MHz
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //Enable ADC1 Clock
/* ADC1 configuration */
ADC_DeInit(ADC1); //Power-on default
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //Independent conversion mode (single)
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //Convert single channel only
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //Convert 1 time
ADC_InitStructure.ADC_ExternalTrigConv = DISABLE; //No external triggering
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //Right 12-bit data alignment
ADC_InitStructure.ADC_NbrOfChannel = 1; //single channel conversion
ADC_Init(ADC1, &ADC_InitStructure);
ADC_TempSensorVrefintCmd(ENABLE); //wake up temperature sensor
ADC_Cmd(ADC1, ENABLE); //Enable ADC1
ADC_ResetCalibration(ADC1); //Enable ADC1 reset calibration register
while(ADC_GetResetCalibrationStatus(ADC1)); //check the end of ADC1 reset calibration register
ADC_StartCalibration(ADC1); //Start ADC1 calibration
while(ADC_GetCalibrationStatus(ADC1)); //Check the end of ADC1 calibration
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_1Cycles5); //Select 1.5 cycles conversion for channel 16
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //Start ADC1 software conversion
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //Wail for conversion complete
AD_value = ADC_GetConversionValue(ADC1); //Read ADC value
ADC_ClearFlag(ADC1, ADC_FLAG_EOC); //Clear EOC flag
printf("\r\n ADC value: %d \r\n", AD_value);
TemperatureC = (uint16_t)((V25-AD_value)/Avg_Slope+25);
printf("Temperature: %d%cC\r\n", TemperatureC, 176);
while (1)
{}
}
Toutes les idées sont appréciées!
OriginalL'auteur lft | 2015-02-04
Vous devez vous connecter pour publier un commentaire.
je vais essayer d'expliquer ce qui se passe avec le code source.
1 - définition de la désactiver est de zéro :
typedef enum {DISABLE = 0, ENABLE = !DÉSACTIVER} FunctionalState;
2 - donc, lorsque vous écrivez "ADC_InitStructure.ADC_ExternalTrigConv = DÉSACTIVER;" vous attribuer à zéro, comme ce "ADC_InitStructure.ADC_ExternalTrigConv = 0;
3 - cela signifie que votre affectation de la EXTSEL de ADC_CR2 registre à zéro.
4-si EXTSEL est égal à zéro, le connecteur de conversion dépend de la minuterie pour commencer.
5-si vous voulez adc d'être lancé par le logiciel, EXTSEL doit être 0x000E0000;
6 - et comme vous pouvez le deviner la valeur de "ADC_ExternalTrigConv_None" est défini comme 0x000E0000;
donc while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); code raccroché ici, car il dépend des minuteries pour commencer, il ne peut prendre fin si elle n'est pas démarré.
OriginalL'auteur kenan bilen
Problème résolu!
C'est de ma faute pour désactiver le déclencheur externe. Au lieu d'utiliser:
Il devrait être comme ceci:
Quel idiot!
OriginalL'auteur lft
Je ne vais pas inventer une roue ici par saing que vous êtes dans l'une de ces trois
while()
boucles. Faire partie de la sortie, avant chacun de puis ensuite, vous saurez où vous êtes suspendu.Si vous avez débogueur (il est présent sur tous les SAINT-conseil de développement, et peut-être que vous utilisez pour télécharger le programme) n'hésitez pas à l'utiliser 🙂
OriginalL'auteur BeginEnd