我是靠谱客的博主 现实期待,这篇文章主要介绍STM32 ADC输入采集电压Verf:Vref就是指输入的模拟电压的最大值, 用于比较输入电压, ADC的输入的有效范围:0-Vref, 如果是10bit ADC,Vref=5v, 2^10(1024):5v, 那么ADC的分辨率为5/1024=0.00488v,现在分享给大家,希望可以做个参考。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255#include "stm32f10x.h" // Device header #include "stdio.h" #include "delay.h" /*********************串口调试输出**********************/ void led()//led PE5初始化 { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOE,&GPIO_InitStruct); } void CUSART_init()//串口初始化函数 { GPIO_InitTypeDef GPIO_InitStruct;//GPIO结构体 USART_InitTypeDef USART_InitStruct;//USART结构体 NVIC_InitTypeDef NVIC_InitStruct;//中断结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;// GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;//设置RX,TX端口串口使能 GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//设置端口浮空输入 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;//设置RX,TX端口串口使能 GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); USART_InitStruct.USART_BaudRate=9600;//波特率 USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流设置 USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx;//设置串口模式 USART_InitStruct.USART_Parity=USART_Parity_No;//不使用奇偶校验 USART_InitStruct.USART_StopBits=USART_StopBits_1;//设置停止位 1 USART_InitStruct.USART_WordLength=USART_WordLength_8b;//传输或接受传输数据位 USART_Init(USART1,&USART_InitStruct); USART_Cmd(USART1,ENABLE);//使能串口 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接受中断 NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStruct.NVIC_IRQChannelSubPriority=1; NVIC_Init(&NVIC_InitStruct); } #define USAERT_REC_LEN 200 unsigned char USART_RX_BUF[USAERT_REC_LEN]; //接受缓冲 unsigned int USART_RX_STA =0; //接受状态标志位 /* USART_RX_STA 定义为一个 16进制的标志位 接收到 0x8000 为 1000 0000 0000 0000 最高位(第15位)接收到1,表示接受完成 接收到 0x4000 同上第14位接收到1,表示接受到0x0d 0d 表示回车 oa 表示换行 以0d,0a结尾表示接收完成 注意:蓝牙和STM32的波特率必须一致 如需使用蓝牙app与MCU通信将TX接到RX */ void USART1_IRQHandler()//串口一中断服务函数 { unsigned char res; //将接受的数据存放data if(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET)//接受的数据以0x0d,0x0a结尾 { res=USART_ReceiveData(USART1);//读取接受数据 if((USART_RX_STA&0x8000)==0)//接受未完成 { if(USART_RX_STA&0x4000)//接收到0x0d { if(res != 0x0a)//如果未接受到0x0a { USART_RX_STA=0; } else { USART_RX_STA|=0x8000;//接收完成 } } else//如果未接受到0x0d { if(res==0x0d)//接收到了 { USART_RX_STA|=0x4000; } else { USART_RX_BUF[USART_RX_STA&0x3ffff]=res;// 0011 1111 1111 1111,储存数据个数 USART_RX_STA++;//接受到的有效数据个数+1 GPIO_SetBits(GPIOE,GPIO_Pin_6);//关闭led if(res== 0x45)//HC-05接收到0x45这个数据 { GPIO_SetBits(GPIOE,GPIO_Pin_5);//关闭led } if(USART_RX_STA>(USAERT_REC_LEN-1))//接收数据出错,重新开始接受 { USART_RX_STA=0; } } } } USART_SendData(USART1,res);//将储存的数据发送出去 } } // 发送数据 int fputc(int ch, FILE *f) { USART_SendData(USART1, (unsigned char) ch);// USART1 可以换成 USART2 等 while (!(USART1->SR & USART_FLAG_TXE)); return (ch); } // 接收数据 int GetKey (void) { while (!(USART1->SR & USART_FLAG_RXNE)); return ((int)(USART1->DR & 0x1FF)); } /****************************ADC转换********************************************/ void Adc_cfg() { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟 //PA1 作为模拟通道输入引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式 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数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目 ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1 ADC_ResetCalibration(ADC1); //使能复位校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 ADC_StartCalibration(ADC1); //开启AD校准 while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束 // ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能 } //获得ADC值 //ch:通道值 0~3 u16 Get_Adc(u8 ch) { //设置指定ADC的规则组通道,一个序列,采样时间 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 Count_AdcVal(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;; } int main() { float temp; u16 value; Adc_cfg(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); CUSART_init(); led(); GPIO_ResetBits(GPIOE,GPIO_Pin_5); printf("Set OK!n"); while(1) { Delay_ms(500); value=Count_AdcVal(ADC_Channel_1,20); temp=(float)value * 3.3/4096; printf("%2.2ft",temp); Delay_ms(500); } }
接线:ADC1电压采集端口PA1
坑:程序无问题,如遇到PA1接GND不为0V,只需将Verf接至3.3V,作为芯片的外部参考基准输入。把这两者连接,就是使用Vref作为参考基准
Verf:Vref就是指输入的模拟电压的最大值, 用于比较输入电压, ADC的输入的有效范围:0-Vref, 如果是10bit ADC,Vref=5v, 2^10(1024):5v, 那么ADC的分辨率为5/1024=0.00488v
最后
以上就是现实期待最近收集整理的关于STM32 ADC输入采集电压Verf:Vref就是指输入的模拟电压的最大值, 用于比较输入电压, ADC的输入的有效范围:0-Vref, 如果是10bit ADC,Vref=5v, 2^10(1024):5v, 那么ADC的分辨率为5/1024=0.00488v的全部内容,更多相关STM32内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复