woshi_ziyu
发表于: 2021-1-4 10:22:57 | 显示全部楼层

在本篇文章中,我们将学习如何使用STM8S103F3P6微控制器的ADC功能。 ADC是微控制器上非常有用的外围设备,嵌入式编程人员经常使用ADC来测量不断变化的单元,例如不断变化的电压、电流、温度、湿度等。


众所周知,“我们生活在具有数字设备的模拟世界中”,这意味着我们周围的一切(例如风速、光强度、温度)以及我们处理的所有事物(如速度、速度、压力等)本质上都是模拟的。但是我们的微控制器和微处理器是数字设备,如果没有一个称为模数转换器(ADC)的重要外设,它们将无法测量这些参数。因此,在本文中,我们将学习如何基于COMIC C编译器和TM8S微控制器使用ADC。


所需的组件

●    STM8S103F3P6开发板

●    ST-Link V2编程器

●    1602 LCD

●    电位器

●    连接线

●    1K电阻


STM8S103F3P6上的ADC

ADC有多种类型,每个微控制器都有自己的规格性能。在STM8S103F3P6上,有一个具有5通道的10位分辨率ADC。分辨率为10位时,我们将能够测量0到1024之间的数字值,而5通道ADC则表明微控制器上有5个引脚可以支持ADC,这5个引脚在下图中突出显示。

ADC-on-STM8S103F3P6.png


如上图所示,所有这五个引脚(AIN2、AIN3、AIN4、AIN5和AIN6)都与其他外设复用,这意味着它们不仅可以用作ADC引脚,还可以用于执行其他通信,例如,引脚2和3(AIN5和AIN 6)不仅可以用于ADC,还可以用于串行通信和GPIO功能。请注意,将这三个功能不能使用同一引脚,因此,如果我们将这两个引脚用于ADC,则将无法执行串行通信。下表是数据手册中其他重要的STM8S103P36 ADC特性。

ADC-Characteristics.png


在上表中,Vdd表示工作电压,Vss表示接地。因此,在开发板上,我们的微控制器工作于3.3V。以3.3V作为工作电压,我们的ADC时钟频率可以设置为1至4MHz,转换电压范围为0V至3.3V。这意味着我们的10位ADC在提供0V(Vss)时将读取0,而在提供3.3V(Vdd)时将读取最大值1024。


读取STM8S上ADC值并在LCD上显示的电路图

下面给出了该项目中使用的完整电路图。

ADC-on-STM8S-Microcontroller-Circuit.png


如您所见,除了LCD之外,仅有的其他组件是两个电位器POT_1和POT_2。这些电位器连接到端口PC4和PD6,它们是ANI2和ANI6引脚,如前面的引脚图所示。


电位器的连接方式使我们在改变电位器时会在模拟引脚上获得0-5 V的电压。我们将对控制器进行编程,以读取该模拟电压的数字值(0到1024)并将其显示在LCD屏幕上。然后,我们还将计算等效电压值并将其显示在LCD上,请记住我们的控制器由3.3V供电,因此,即使我们向ADC引脚提供5V电压,它也只能读取0V至3.3V的电压。 。


连接完成后,我的硬件如下所示。您可以在右侧看到两个电位器,在左侧看到ST-link编程器。

STM8S-Microcontroller-with-Cosmic-C-Compiler.jpg


STM8S103F3P6的ADC库

为了在STM8S上编程ADC功能,我们将使用Cosmic C编译器和SPL库。但是为了简化流程,我制作了另一个头文件,可以在GitHub上找到以下链接。STM8S103F3P6的ADC库


您可以使用上面的代码创建一个头文件,并将其添加到项目页面上的“ include files”目录中。设置完成后,您的IDE应具有以下头文件,至少包含用红色圈起来的头文件。

Library-for-STM8S103F3P6.png

上面的头文件包含一个称为ADC_Read()的函数。可以在主程序中调用此函数以获取任意引脚上的ADC值。例如,ADC_Read(AN2)将返回引脚AN2上的ADC值。函数如下所示。

  1. unsigned int ADC_Read(ADC_CHANNEL_TypeDef ADC_Channel_Number)
  2. {
  3.    unsigned int result = 0;
  4. ADC1_DeInit();
  5. ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,
  6.              ADC_Channel_Number,
  7.              ADC1_PRESSEL_FCPU_D18,
  8.              ADC1_EXTTRIG_TIM,
  9.              DISABLE,
  10.              ADC1_ALIGN_RIGHT,
  11.              ADC1_SCHMITTTRIG_ALL,
  12.              DISABLE);
  13.    ADC1_Cmd(ENABLE);
  14. ADC1_StartConversion();
  15. while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == FALSE);
  16.   result = ADC1_GetConversionValue();
  17.   ADC1_ClearFlag(ADC1_FLAG_EOC);
  18. ADC1_DeInit();
复制代码

如您所见,我们可以将八个参数传递给该函数,这定义了ADC的配置方式。在上面的库代码中,我们将转换模式设置为连续,然后通过参数获取通道号。然后,我们必须设置控制器的CPU频率,默认情况下,您的STM8S可以与16Mhz内部振荡器一起工作。因此,我们已经提到“ ADC1_PRESSEL_FCPU_D18”作为预分频值。在此函数内部,我们正在使用SPL stm8s_adc1.h头文件定义的其他方法。我们先取消初始化ADC引脚,然后再使用初始化ADC1_Init()以初始化ADC外设。下面显示了SPL用户手册中此函数的定义。

ADC-Peripheral.jpg


接下来,我们将使用计时器设置外部触发器,并禁用外部触发器,因为此处将不再使用它。然后我们在右边设置了对齐方式,最后两个参数用于设置施密特触发器,但是在本文中我们将禁用它。因此,简而言之,我们将使ADC在所需的ADC引脚上以连续转换模式工作,并禁用外部触发和施密特触发器。


STM8S程序读取模拟电压并在LCD上显示

添加所需的头文件和源文件后,您应该能够直接编译主文件。主文件中的代码说明如下。


该代码的目的是从两个引脚读取ADC值并将其转换为电压值。我们还将在LCD上同时显示ADC值和电压值。因此,我使用了一个名为LCD_Print Var的函数,该函数采用整数格式的变量并将其转换为字符,以便在LCD上显示。我们使用了简单的模数(%)和除法(/)运算符从变量中获取每个数字,并放入变量d1、d2、d3和d4,如下所示。然后,我们可以使用LCD_Print_Char函数在LCD上显示这些字符。

  1. void LCD_Print_Var (int var)
  2. {
  3. char d4,d3,d2,d1;
  4. d4 = var%10 + '0';
  5. d3 = (var/10)%10 + '0';
  6. d2 = (var/100)%10 + '0';
  7. d1 = (var/1000) + '0';
  8. Lcd_Print_Char(d1);
  9. Lcd_Print_Char(d2);
  10. Lcd_Print_Char(d3);
  11. Lcd_Print_Char(d4);
  12. }
复制代码

接下来在main函数下,我们声明了四个变量。其中两个用于保存ADC值(0至1024),另外两个用于获取实际电压值。

  1. unsigned int ADC_value_1 = 0;
  2. unsigned int ADC_value_2 = 0;
  3. int ADC_voltage_1 = 0;
  4. int ADC_voltage_2 = 0;
复制代码

接下来,我们必须准备GPIO引脚和时钟配置以读取模拟电压。在这里,我们将从AIN2和AIN6引脚(分别是PC4和PD6引脚)读取模拟电压。我们必须将这些引脚定义为浮动状态,如下所示。我们还将为ADC启用时钟外设。

  1. CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE); //Enable Peripheral Clock for ADC
  2. GPIO_Init (GPIOC, GPIO_PIN_4, GPIO_MODE_IN_FL_IT);
  3. GPIO_Init (GPIOC, GPIO_PIN_4, GPIO_MODE_IN_FL_IT);
复制代码

现在引脚已准备就绪,我们必须进入无限while循环以读取模拟电压。由于有了头文件,因此可以使用下面的几行轻松地从AIN2和AIN 6引脚读取模拟电压。

  1. ADC_value_1 = ADC_Read (AIN2);
  2. ADC_value_2 = ADC_Read (AIN6);
复制代码

下一步是将该ADC读数(0至1023)转换为模拟电压。这样,我们可以显示提供给引脚AIN2和AIN6的确切电压值。计算模拟电压的公式可由下式给出:

  1. Analog Voltage  = ADC Reading * (3300/1023)
复制代码

就STM8S103F3控制器而言,我们有一个10位分辨率的ADC,因此我们使用1023(2 ^ 10)。同样在开发板上,控制器的3.3V电压为3300,因此在上述公式中我们将3300除以1023。因此在本文中,我们有以下几行代码使用ADC电压来测量实际ADC电压。

  1. ADC_voltage_1 = ADC_value_1 * (3.226); //(3300/1023 =~ 3.226)convert ADC value 1 to 0 to 3300mV
  2. ADC_voltage_2 = ADC_value_2 * (3.226);  //convert ADC value 1 to 0 to 3300mV
复制代码

该代码的其余部分仅用于在LCD屏幕上显示这四个值。我们也加上了500毫秒的延迟,因此LCD每500毫秒就会更新一次。


使用STM8S从两个电位计读取模拟电压

编译代码并将其上传到开发板。如果遇到任何编译错误,请确保已添加所有头文件和源文件,如前所述。上载代码后,您将看到一条小的欢迎消息,提示“ ADC on STM8S”,然后您将看到以下界面。

Interface-16x2-LCD-with-STM8s.jpg


值D1和D2分别表示来自引脚Ain2和AIN6的ADC值。在右侧,我们还显示了等效电压值。此值应分别等于引脚AIN2和AIN6上出现的电压。我们可以使用万用表进行检查,也可以改变电位器以检查电压值是否也相应变化。

ADC-on-STM8S-using-Cosmic-C-Compiler.jpg


希望您喜欢本教程并学到了一些有用的东西,如果有任何疑问,请在本帖下面回复。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 12 | 回复: 16



手机版|

GMT+8, 2024-11-21 20:13 , Processed in 0.041824 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表