STM32----------ADC和DMA(附:完整USART输出程序)
来源:互联网 发布:android编程权威指南3 编辑:程序博客网 时间:2024/05/17 19:23
ADC的输入时钟不得超过14MHZ,它是由PCLK2经分频产生。
如果被ADC转换的模拟电压低于低阀值或高于高阀值,AWD模拟看门狗状态位被设置。
ADC通常要与DMA一起使用 这里只是简单的用库配置ADC 不断扫描来实现ADC的应用。
Injected Channels 为注入组,Regular Channel 为规则组(好比家里的10个温度传感器用来实时显示温度,此10个传感器放在规则组,另外2个室外传感器的偶尔看一下数据,这两个放在注入组),规则组相当于执行的程序,注入组相当于中断,注入组转换可以打断规则通道的转换,注入通道转换完成之后,规则通道继续转换
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AIN; // 模拟输入
GPIO_Init(GPIOB,&GPIO_InitStructure); // 默认速度为两兆
配置ADC的运行:
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式 ,ADC1和ADC2的关系
ADC_InitStructure.ADC_ScanConvMode =DISABLE; //连续多通道模式 开关,设置为ENABLE,通道数为1,则仍然还是单通道
ADC_InitStructure.ADC_ContinuousConvMode =ENABLE; //连续转换 还是单次转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换不受外界决定
ADC_InitStructure.ADC_DataAlign =ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_NbrOfChannel =1; //扫描通道数
ADC_Init(ADC1,&ADC_InitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_9, 1,ADC_SampleTime_1Cycles5); //通道X,采样时间为1.5周期,1代表规则通道第1个这个1是啥意思我不太清楚只有是1的时候我的ADC才正常。
ADC_Cmd (ADC1,ENABLE); //使能或者失能指定的ADC
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能或者失能指定的ADC的软件转换启动功能
//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
//ADC1,ADC通道x,规则采样顺序值为y,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5 ); // 通道0 ,顺序为第 1 周期为239.5(采样周期越长越准确)
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239Cycles5 );
注意:为了能够正确地配置每一个ADC通道,用户在调用ADC_Init()之后,必须调用ADC_ChannelConfig()来配置每个所使用通道的转换次序和采样时间。
然后就是不停的读;
u16 TestAdc(void)
{
u16 adc;
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET); //检查制定ADC标志位置1与否 ADC_FLAG_EOC 转换结束标志位
adc=ADC_GetConversionValue(ADC1);
return adc;//返回最近一次ADCx规则组的转换结果
}
完整程序:
#include "stm32f10x.h" #include "stm32f10x_adc.h"#include "stm32f10x_dma.h"#include "stm32f10x_rcc.h"#include "stm32f10x_gpio.h"#include "stm32f10x_usart.h" #include "misc.h"#include <stdarg.h> // 这个头文件用于后面USART的输出函数中有 不定参数 ...#define ADC1_DR_Address ((u32)0x4001244C) static unsigned long ticks;unsigned char Clock1s;vu16 ADC_ConvertedValue;void RCC_Configuration(void); void ADC_Configuration(void); void Usart1_Init(void);void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...);int main(void){ RCC_Configuration(); Usart1_Init(); ADC_Configuration(); USART_OUT(USART1,"\r\n USART1 print AD_value -------------------------- \r\n"); while(1) { if (ticks++ >= 900000) { //每隔一段时间发送一次数据 ticks = 0; Clock1s = 1; } if (Clock1s) { Clock1s = 0; USART_OUT(USART1,"The current AD value = %d \r\n", ADC_ConvertedValue); } }}void ADC_Configuration(void){ADC_InitTypeDef ADC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;DMA_InitTypeDef DMA_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure);/* Enable DMA clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Enable ADC1 and GPIOC clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);DMA_DeInit(DMA1_Channel1);DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 1; //DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init(DMA1_Channel1, &DMA_InitStructure); //DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);DMA_Cmd(DMA1_Channel1, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = ENABLE;ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5); ADC_DMACmd(ADC1, ENABLE); //使能 ADC DMAADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1); //<span style="color: rgb(102, 102, 102); font-family: 'Courier New'; line-height: 25.98958396911621px; text-indent: 28px;"><span style="font-size:12px;">执行复位校准</span></span>while(ADC_GetResetCalibrationStatus(ADC1)); //等待校准结束ADC_StartCalibration(ADC1); //执行ADC校准while(ADC_GetCalibrationStatus(ADC1));ADC_SoftwareStartConvCmd(ADC1, ENABLE);<span style="font-family: Arial, Helvetica, sans-serif;">}</span>void RCC_Configuration(void){ SystemInit(); RCC_ADCCLKConfig(RCC_PCLK2_Div6); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);}void Usart1_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 , ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //开漏输入 GPIO_Init(GPIOA, &GPIO_InitStructure); // 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; /* Configure USART1 */ USART_Init(USART1, &USART_InitStructure); /* Enable the USART1 */ USART_Cmd(USART1, ENABLE); }char *itoa(int value, char *string, int radix){ int i, d; int flag = 0; char *ptr = string; /* This implementation only works for decimal numbers. 非10进制的转换为0 */ if (radix != 10) { *ptr = 0; return string; } if (!value) { *ptr++ = 0x30; // 0x30就是 字符 '0' 0x31 是 字符 ’1‘ (ASCII码) *ptr = 0; return string; } /* if this is a negative value insert the minus sign. */ if (value < 0) { *ptr++ = '-'; /* Make the value positive. */ value *= -1; } for (i = 10000; i > 0; i /= 10) { d = value / i; if (d || flag) { *ptr++ = (char)(d + 0x30); value -= (d * i); flag = 1; } } /* Null terminate the string. */ *ptr = 0; return string;} /* NCL_Itoa */
- STM32----------ADC和DMA(附:完整USART输出程序)
- STM32 DMA USART ADC
- STM32笔记(三)ADC、DMA、USART的综合练习
- STM32--ADC(DMA)
- STM32 USART DMA
- STM32的创新, 附usart程序
- stm32-10ADC实验(DMA方式)
- ADC-DMA For STM32
- STM32 USART 串口 DMA 接收和发送的源码详解!
- STM32 USART串口DMA接收和发送模式
- STM32 USART 串口 DMA 接收和发送的源码详解!
- STM32 USART 串口 DMA 接收和发送的源码详解!
- STM32之ADC 一个8通道DMA程序
- STM32之ADC 一个8通道DMA程序
- STM32中USART的DMA 实现(转)
- 实现STM32中USART的DMA(转)
- STM32笔记(四)DMA、USART的演示
- Stm32使用Usart代码例子(轮询、中断、DMA)
- Python爬虫入门(6):Cookie的使用
- 【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)
- 使用gcc和cmake编译工具编辑opencv例子
- Sublime Text的一些实用快捷键
- hdu 1038 Biker's Trip Odometer(水题)
- STM32----------ADC和DMA(附:完整USART输出程序)
- IIemaGpmuJ.45
- 兔子出生总数问题
- C#之数组、集合与泛型
- 转折后的总结--2014年找工作
- ubuntu下安装RemixOS双系统(Android x86)
- SSH中的权限拦截器
- JZWC【Day4】题解&总结
- 2014找工作总结-机会往往留给有准备的人