12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。
模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。
ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。
ADC 主要特征
● 12位分辨率
● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
● 单次和连续转换模式
● 从通道0到通道n的自动扫描模式
● 自校准
● 带内嵌数据一致性的数据对齐
● 采样间隔可以按通道分别编程
● 规则转换和注入转换均有外部触发选项
● 间断模式
● 双重模式(带2个或以上ADC的器件)
下面就用代码演示如何设置ADC单次转换模式
void ADCx_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5; //PA1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //规则转换ADC通道数
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE); //使能ADC1
ADC_ResetCalibration(ADC1); //复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
}
首先初始化IO口,这里的初始化的是ADC抓换通道的0–5,对应的IO口PA0到PA5,将这6个IO口这是为模拟输入模式。接下来在将这几个口设置为ADC口,在设置之前首先将ADC模式复位,然后将ADC设置为单通道单词转换模式,也就是每次只转换一个通道,转换一次后就停止转换,直到接收到下一次转换命令为止。开始转换的命令是由软件来设置的。
ADC口初始化好之后,还需要一个读取转换结果的函数,用于读取指定通道的转换值。
//获取ADC值
//ch:通道号
u16 Get_Adc( u8 ch )
{
ADC_RegularChannelConfig( ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd( ADC1, ENABLE ); //使能ADC1软件启动转换
while( !ADC_GetFlagStatus( ADC1, ADC_FLAG_EOC ) ); //等待转换结束
return ADC_GetConversionValue( ADC1 ); //返回最近一次ADC1规则组的转换结果
}
u16 Get_Adc_Average( u8 ch, u8 times )
{
u32 temp_val = 0;
u8 t;
for( t = 0; t < times; t++ )
{
temp_val += Get_Adc( ch );
delay_ms( 5 );
}
return temp_val / times;
}
Get_Adc()函数用于读取指定通道的ADC转换值,这里的通道必须是初始化函数中初始化过的通道,这个函数每次只读取一次通道值,为了确保转换结果的正确性,需要多次读取通道值取平均值,所以这里Get_Adc_Average()函数就是用来设置多次读取指定通道值,然后取平均值后返回。比如可以设置读取通道1,100次然后取平均值。ADC相关的设置函数就初始化好了,接下来在主函数中调用Get_Adc_Average()函数就可以读取通道值了。
int main(void)
{
u16 adcx = 0;
float temp;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
LED_Init();
LED0 = 1;
LED1 = 1;
delay_ms(500);
LED0 = 0;
LED1 = 0;
ADCx_Init();
printf("ADC test!!!rn");
while(1)
{
adcx = Get_Adc_Average(ADC_Channel_0, 10);
printf("ch0 num: %drn", adcx);
temp = (float)adcx * (3.3 / 4096);
adcx = temp * 1000;
printf("ch0 adc value: %drn", adcx);
adcx = Get_Adc_Average(ADC_Channel_1, 10);
printf("ch1 num: %drn", adcx);
temp = (float)adcx * (3.3 / 4096);
adcx = temp * 1000;
printf("ch1 adc value: %drn", adcx);
adcx = Get_Adc_Average(ADC_Channel_2, 10);
printf("ch2 num: %drn", adcx);
temp = (float)adcx * (3.3 / 4096);
adcx = temp * 1000;
printf("ch2 adc value: %drn", adcx);
adcx = Get_Adc_Average(ADC_Channel_3, 10);
printf("ch3 num: %drn", adcx);
temp = (float)adcx * (3.3 / 4096);
adcx = temp * 1000;
printf("ch3 adc value: %drn", adcx);
adcx = Get_Adc_Average(ADC_Channel_4, 10);
printf("ch4 num: %drn", adcx);
temp = (float)adcx * (3.3 / 4096);
adcx = temp * 1000;
printf("ch4 adc value: %drn", adcx);
adcx = Get_Adc_Average(ADC_Channel_5, 10);
printf("ch5 num: %drn", adcx);
temp = (float)adcx * (3.3 / 4096);
adcx = temp * 1000;
printf("ch5 adc value: %drn", adcx);
LED0 = !LED0;
delay_ms(500);
}
}
在主函数中依次读取通道0到通道5的值,读取10次取平均值,然后将转换后的值打印出来。由于ADC为12位,所以转换后的最大值为4096,对应的最大电压值为3.3V,为了方便观察,将转换后的值换换位电压值。
上一篇:STM32F103单片机驱动蜂鸣器
下一篇:STM32单片机实现DMA+ADC+UART功能
推荐阅读最新更新时间:2024-11-10 12:52
推荐帖子
- MSP432 开箱+energytrace技术初体验
- 从X宝上购买的MSP432launchpad已经到货,大家分享一下。MSP432最大的优点是32位M4F核心+低功耗,launchpad上使用了XDS110调试器,可以支持energytrace技术,对功率进行测量。废话不说了,放图片大家欣赏一下。安装IDE,使用的是CCS6,默认安装了enerytrace软件。安装CCS完毕后,发现驱动已经更新成功打开CCS,选择了最简单的blink程序,进行调试。在调试窗口会看到energytrace的图标。点开后出现如下界面该界面
- flyword 微控制器 MCU
- 通过USB向单片机传输信号可行吗?
- 通过USB向单片机传输信号可行吗?我想通过USB向单片机传入某一信号,再由单片机传出相应的电平信号,这个设想可行吗?有没有什么具体的实行方法?通过USB向单片机传输信号可行吗?一般使用usb供电,没见过使用usb传输信号,使用单片机的两个I/O引脚就可以实现,剩下的工作就是你的程序编写的事情了!输出的电平信号不是返还电脑,是给其他设备的,也就是说我想通过单片机把USB信号转换为电平信号!51单片机能做到这点吗?在51前加一D12,最终信号由51给电平信号我在网上查资料说D12会出现丢
- lcllcl20031 嵌入式系统
- 学习嵌入式操作系统需要什么条件
- 我想先学一学嵌入式操作系统,但不知道学哪一个好,可能会先Linux吧。更重要的是,我不知道学习Linux需什么条件,特别是硬件,是不是只需要一台电脑就行呢?我就只有一台电脑,这样可以学Linux了吗?我还是个菜鸟,希望大家能给我一些建议,不胜感激!学习嵌入式操作系统需要什么条件应该有块开发板
- www2900 嵌入式系统
- PADS9.1下载
- PADS9.1下载PADS9.1下载怎么上传不上去呢:Q最大可以支持15M,如果超过这个可能要分成几个包了回复沙发毛承玲的帖子谢谢,我知道了,;P;P;P文件太大了点回复沙发毛承玲的帖子這個文件至少上百M,建議找個地方上傳後,再把連結貼出來
- 毛承玲 PCB设计
- 恳求WinCE.Net下ASP调用文本文件方法
- 求WinCE.Net下ASP页面调用文本文件方法。小弟已试过在WinCE.NetASP页面中不能创建Scripting.FileSystemObject对象和ADODB.Stream对象,请问各位大侠还有没有别的方法在ASP中调用文本文件?先谢过了恳求WinCE.Net下ASP调用文本文件方法期待中
- iyj WindowsCE
- [BearPi-Pico H2821]测评 ⑥丢包及连接稳定性测试
- 上两篇我们查了一下SLEserver和client端的demo,怎么运行的,收发应该调用那些接口已经清楚了,就可以开始做丢包及连接稳定性测试了测试方案server端代码不用动,client端连接server后,创建一个TASK,定时用SLE向server发数据,并计数,发送到最大次数后,停止发送,摧毁task。然后提取双方日志,查看中途是否有断连、收发次数是否有缺少1.client端代码修改1.1发送函数参照之前找到的发送函数sle_ua
- 不爱胡萝卜的仓鼠 RF/无线
设计资源 培训 开发板 精华推荐
- 微软、腾讯、英特尔“不务正业”种黄瓜,是因为人工智能
- 郭明錤下调iPhone XR出货量,但恐遭供应链打脸!
- 微软 Windows 10 十月更新仍未重新上线,但四月更新调整到支
- 取代刘海屏指日可待?美国专利商标局公布苹果屏下摄像头
- 拆解对比:Apple苹果 Lightning与USB-C to 3.5mm转换器
- 东风日产全新劲客首次搭载BOSE PERSONAL PLUS音响系统
- 地平线与大陆集团合资公司落户上海,加速汽车智能化技术商业落地
- 通用汽车新软件平台Ultifi:将推出OTA、车内订阅乃至面部识别
- 碳化硅时代来临,各大供应商怎么看
- 瑞萨电子宣布将全面支持面向未来汽车级MCU和SoC的ISO/SAE 21434标准