STM32 Keil 应用篇一---------基于F030F4P6的超低成本ADC采集系统(串口输出)

STM32 Keil 应用篇一----------------基于F030F4P6的超低成本ADC采集系统(串口输出)

最近STM芯片涨价比较厉害,有没有一种低成本的方案可以完成项目,并且又不需要花大量时间修改,学习新方案呢?笔者最近刷某宝时候无意中刚好找到一款,分享给大家:

首先,上图:F030F4P6 48M主频,16K ROM,价格上甚至比51还低,1.1的价格屠夫让传统的51单片机何去何从?
在这里插入图片描述

废话不多说,F030芯片资料稍微有点少(相比M3,M4主流芯片),工程代码搜集了2、3天,资源分享给大家:ADC-UART 功能 实现 main.c:

#include "stm32f0xx.h"
#include "LED.h"
#include "USART1.h"
#include "KEY.h"      // KEYÇý¶¯Í·Îļþ
#include "ADC1.h"
//º¯ÊýÉùÃ÷

//=============================================================================
//ÎļþÃû³Æ£ºDelay
//=============================================================================
void  Delay (uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

//=============================================================================
//ÎļþÃû³Æ£ºmain
//=============================================================================
int main(void)
{
  /* LED³õʼ»¯ */
  LED_Init();
  /* USART1³õʼ»¯ */
  USART1_Init();	
	ADC1_DMA_Init();
	
  printf("´®¿Ú·¢ËÍÓÉPA1¿Ú²É¼¯µÄµçѹֵ\r\n"); 
  KEY_EXTI_Init();
  while(1)
  { 
		printf("PA1¿Ú²É¼¯µÄµçѹÊýÖµ£º%d\r\n",RegularConvData_Tab[0]); 
		Delay(0xfffff);
  }
}

uart.c:

include "USART1.h"

/* USART³õʼ»¯ */
void USART1_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStruct;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  //ʹÄÜGPIOAµÄʱÖÓ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//ʹÄÜUSARTµÄʱÖÓ
	/* USART1µÄ¶Ë¿ÚÅäÖà */
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);//ÅäÖÃPA9³ÉµÚ¶þ¹¦ÄÜÒý½Å	TX
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);//ÅäÖÃPA10³ÉµÚ¶þ¹¦ÄÜÒý½Å  RX	

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	

	/* USART1µÄ»ù±¾ÅäÖà */
	USART_InitStructure.USART_BaudRate = 115200;              //²¨ÌØÂÊ
	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_Init(USART1, &USART_InitStructure);		
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);           //ʹÄܽÓÊÕÖжÏ
	USART_Cmd(USART1, ENABLE);                             //ʹÄÜUSART1
	
	/* USART1µÄNVICÖжÏÅäÖà */
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPriority = 0x02;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);
				
}

//=============================================================================
//ÎļþÃû³Æ£º
//=============================================================================
void USART1_IRQHandler(void)
{
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{
   USART_SendData(USART1,USART_ReceiveData(USART1));
	 while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
	}
			
}


/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

uart.h:

#ifndef __BSP_USART1_H
#define __BSP_USART1_H

#include "stm32f0xx.h"
#include <stdio.h>

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

void USART1_Init(void);

#endif

ADC.c:


#include "ADC1.h"

 __IO uint32_t TempSensVoltmv=0;
 __IO uint32_t VrefIntVoltmv=0;
 __IO uint32_t PC3Voltmv=0; 
 __IO uint32_t VbatVoltmv=0; 
 
 uint16_t RegularConvData_Tab[4];



void ADC1_DMA_Init(void)
{
	GPIO_InitTypeDef    GPIO_InitStructure;
	DMA_InitTypeDef     DMA_InitStructure;
	ADC_InitTypeDef     ADC_InitStructure;

	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
   GPIO_Init(GPIOA, &GPIO_InitStructure);	
		
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);		
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
	
	ADC_DeInit(ADC1);//ADC»Ö¸´Ä¬ÈÏÉèÖÃ		

  DMA_DeInit(DMA1_Channel1);	/* DMA1 Channel1 Config */
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;//ÍâÉèµØÖ·
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;//ÄÚ´æµØÖ·
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//ÍâÉè×÷ΪÊý¾Ý´«ÊäµÄÀ´Ô´
  DMA_InitStructure.DMA_BufferSize = 4;//
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//ÍâÉèµØÖ·¼Ä´æÆ÷²»±ä
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//ÄÚ´æµØÖ·¼Ä´æÆ÷²»±ä
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//Êý¾Ý¿í¶ÈΪ16λ
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//Êý¾Ý¿í¶ÈΪ16λ
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA_PriorityÉ趨DMAͨµÀxµÄÈí¼þÓÅÏȼ¶
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//DMAͨµÀxûÓÐÉèÖÃΪÄÚ´æµ½ÄÚ´æ´«Êä
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
		  
  
	
	DMA_Cmd(DMA1_Channel1, ENABLE);/* DMA1 Channel1 enable */			
	ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); /* Enable ADC_DMA */	
  ADC_DMACmd(ADC1, ENABLE);  
	
		

	ADC_StructInit(&ADC_InitStructure);//³õʼ»¯ADC½á¹¹
	
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12λ¾«¶È
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //¹æ¶¨Ä£Ê½×°»»¹¤×÷ÔÚÁ¬Ðøģʽ
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; 
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//Êý¾Ý¶ÔÆäΪÓÒ¶ÔÆë
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward; //ADCµÄɨÃè·½Ïò
  ADC_Init(ADC1, &ADC_InitStructure); 
	 
  ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_239_5Cycles); /* Convert the ADC1 Channel 11 with 239.5 Cycles as sampling time */  

  ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint ,ADC_SampleTime_239_5Cycles); 
  ADC_VrefintCmd(ENABLE);
	
	ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor ,ADC_SampleTime_239_5Cycles);
	ADC_TempSensorCmd(ENABLE);
	
	ADC_ChannelConfig(ADC1, ADC_Channel_Vbat ,ADC_SampleTime_239_5Cycles);
	ADC_VbatCmd(ENABLE);
	
	ADC_GetCalibrationFactor(ADC1); /* ADC Calibration */  
  ADC_Cmd(ADC1, ENABLE);  /* Enable ADCperipheral[PerIdx] */	  
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); /* Wait the ADCEN falg */
  ADC_StartOfConversion(ADC1); /* ADC1 regular Software Start Conv */ 
			
}


ADC.h

#ifndef __ADC1_H
#define __ADC1_H

#include "stm32f0xx.h"

#define ADC1_DR_Address                0x40012440

extern  __IO uint32_t TempSensVoltmv;
extern  __IO uint32_t VrefIntVoltmv ;
extern  __IO uint32_t PC3Voltmv ;
extern  __IO uint32_t VbatVoltmv ;
extern  uint16_t RegularConvData_Tab[4];

void ADC1_DMA_Init(void);

#endif

工程在开发板上已验证OK,源码如下:
链接:https://pan.baidu.com/s/1V1Fj0G4ShdQZ32GZqms5Vw
提取码:xw3j

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ADC DMA采集是指利用STM32F030F4P6微控制器中的外设——模数转换器(ADC)和直接存储器访问(DMA)功能进行数据采集和传输。 首先,ADC是一种用于将模拟电压转换为数字数据的外设。在STM32F030F4P6中,它具有多个通道,可以同时采集多个模拟信号。通过配置ADC的参数,设置采样分辨率,采样速率等,可以满足不同实际应用的需求。 然而,当需要采集大量数据时,频繁的CPU干预可能会导致系统的性能下降。为了解决这个问题,可以使用DMA功能。DMA可以通过直接传输数据而无需CPU干预,从而提高系统的效率。通过配置DMA的参数,设置传输方向,传输大小等,可以使得ADC采集数据直接传输到内存中。 具体操作步骤如下: 1. 配置ADC模块:选择和配置ADC通道、采样分辨率、采样速率等参数。 2. 配置DMA模块:选择和配置DMA通道、传输方向(从ADC到内存)、传输大小等参数。 3. 配置中断(可选):如果需要采集完成后触发中断,可以配置ADC和DMA的中断功能。 4. 启动ADC和DMA:使能ADC和DMA的时钟,并启动ADC和DMA的工作。 5. 等待采集完成:可以通过查询ADC状态寄存器或等待ADC中断来判断采集是否完成。 6. 数据处理:采集完成后,可以通过访问存储在内存中的数据进行处理或后续操作。 总结来说,ADC DMA采集是通过配置ADC和DMA模块,设置参数并启动工作,实现数据的快速采集。这种方法可以减少CPU的干预,提高系统的效率和准确性,适用于对实时性要求较高的应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值