基于STM8的ADC读取---STM8-第四章

2019-12-04来源: eefocus关键字:STM8  ADC读取  数字量

1. 综诉


  想学会如何在STM8上使用ADC这个功能,我们先得了解单片机中ADC究竟是什么。


  ADC是模拟信号转成数值信号,单片机只能识别TTL电平,其实就是 1 或者 0 ,但是如果我们给它一个3.3V电压,单片机就无法识别,,若想使用单片机读取出来得时候,它必须将模拟量变成数字量。


2. 关于STM8S103手册的ADC简介

由官方的全英手册可知。


----------------------------------------------------------------------------------------------------------------------------------


STM8中ADC1和ADC2主要功能如下:


10位分辨率

单词和连续的转换模式

可编程的(转换频率的)预分频,fMASTER 可以被分频 2到18

可选择ADC专用外部中断(ADC_ETR)或者定时器触发信号(TRGO)来作为外部触发信号

模拟放大(对于具有VREF引角的型号)

转换结束时可产生中断

灵活的数据对齐方式

ADC输入电压范围:VSSA≤VIN≤VDDA

----------------------------------------------------------------------------------------------------------------------------------


ADC1具有以下拓展功能:


带缓冲的连续转换模式

单次和连续转换的扫描模式

具有上限和下限门槛的模拟看门狗

模拟看门狗时间发生可产生中断

----------------------------------------------------------------------------------------------------------------------------------


3. 例程


3.1 编译环境


  我的编译环境是IAR,这款软件是现在STM8的主流平台,比较推荐。不过我打算等到STCubeMX更新出比较方便的版本后再去使用Keil5,因为我在用STM32的时候就是利用Keil5,的确很方便,你们也可以学着用一下。


3.2 主芯片


  我的主芯片是STM8S系列中的103,其中STM8S的003、005、和103、105,配置一样(外设和CPU频率,FLASH),在代码相同的情况下均可进行烧写。


3.3 库文件的添加


  我们的工程可以在IAR的例程中复制,操作过程:打开STM8S_StdPeriph_Lib(这是一个官方的库文件,下载IAR STM8包的时候就携带,里面有库文件和相对应的例程),将Libraries文件复制到你工程所在的文件下,并将有关于ADC的库文件添加到你的工程列表当中。添加完成后,有可能你会看到一些C文件会有红色的小点报错,这是因为你选的芯片上没有该功能,你需要将其删掉才能不报错。如图。

添加成功后,我们需要将头文件添加进来,头文件的路径存放在 Libraries->STM8S_StdPeriph_Driver->inc中,如图。 

3.4 代码编写


  STM8SF003这款芯片能用的是5个AD采样通道,分别为为AIN2~AIN6。其一个通道AIN7,但在官方手册中我没找到有对其描述的,感兴趣的朋友可以去察看芯片的英文手册进行研究,也许会找到和我不一样的结果。


在ADC头文件中,将ADC1所有的ADC1_CHANNEL(ADC通道)都进行枚举,以方便调用。


 1 /* Enum ----------------------------------------------------------------------*/

 2 

 3 enum ADC1_CHANNEL

 4 {                                        //bit  8  7  6  5  4  3  2  1

 5   

 6     ADC1_CHANNEL2 = 0x01,                //     0  0  0  0  0  0  0  1

 7     ADC1_CHANNEL3 = 0x02,                //     0  0  0  0  0  0  1  0

 8     ADC1_CHANNEL4 = 0x04,                //     0  0  0  0  0  1  0  0

 9     ADC1_CHANNEL5 = 0x08,                //     0  0  0  0  1  0  0  0

10     ADC1_CHANNEL6 = 0x10                 //     0  0  0  1  0  0  0  0

11         

12 };  

 

在ADC.C文件中,分为了多个函数,降低他们的耦合性,也方便理解。


首先是ADC中引角的初始化,将你所选通道的引角进行初始化,没有选到的就不进行初始化。


 1 /*******************************************************************************

 2 * Function Name  : MX_ADC_GPIO_Init

 3 * Description    : ADC GPIO Init

 4 * Input          : ADC1_CHANNEL

 5 * Output         : None

 6 * Return         : None

 7 ********************************************************************************/

 8 

 9 void MX_ADC_GPIO_Init(uint8_t ADC1_CHANNEL)

10 {

11   switch(ADC1_CHANNEL)

12   {

13     case ADC1_CHANNEL2:  GPIO_Init(ADC_Opt_GPIOC_Port,ADC_channe2_Pin,GPIO_MODE_IN_PU_NO_IT);break;

14     case ADC1_CHANNEL3:  GPIO_Init(ADC_Opt_GPIOD_Port,ADC_channe3_Pin,GPIO_MODE_IN_PU_NO_IT);break;

15     case ADC1_CHANNEL4:  GPIO_Init(ADC_Opt_GPIOD_Port,ADC_channe4_Pin,GPIO_MODE_IN_PU_NO_IT);break; 

16     case ADC1_CHANNEL5:  GPIO_Init(ADC_Opt_GPIOD_Port,ADC_channe5_Pin,GPIO_MODE_IN_PU_NO_IT);break;

17     case ADC1_CHANNEL6:  GPIO_Init(ADC_Opt_GPIOD_Port,ADC_channe6_Pin,GPIO_MODE_IN_PU_NO_IT);break;

18   } 

19   

20 }

 

  然后是ADC1的选择通道初始化:ADC连续读取,所选的通道,二分频,外部转换触发,外部触发器不开启,数据右对齐,施密特触发,不开启。(注意:STMS8003中的串口使用了PD5和PD6,与ADC1中通道5、通道6发生冲突,故不可使用。如需使用,请将串口的TXRX引角更改换为其它的引角。)


 1 /*******************************************************************************

 2 * Function Name  : MX_ADC1_CHANNEL_Init

 3 * Description    : ADC CHANNEL Init

 4 * Input          : ADC1_CHANNEL

 5 * Output         : None

 6 * Return         : None

 7 ********************************************************************************/

 8 

 9 void MX_ADC1_CHANNEL_Init(uint8_t ADC1_CHANNEL)

10 {

11   switch(ADC1_CHANNEL)

12   {

13     case ADC1_CHANNEL2: 

14     {

15        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_2, 

16        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

17        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL2, DISABLE);break;

18     }

19     case ADC1_CHANNEL3:

20     {

21        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_3, 

22        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

23        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL3, DISABLE);break;

24     }

25     case ADC1_CHANNEL4:

26     {

27        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_4, 

28        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

29        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL4, DISABLE);break;

30     } 

31     case ADC1_CHANNEL5:

32     {

33        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_5, 

34        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

35        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL5, DISABLE);break;

36     }

37     case ADC1_CHANNEL6:

38     {

39        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_6, 

40        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

41        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL6, DISABLE);break;

42     }

43   } 

44 }


这里就是将所有的ADC初始化进行一个统一的一个归类。


 1 /*******************************************************************************

 2 * Function Name  : MX_ADC1_Init

 3 * Description    : ADC Init

 4 * Input          : ADC1_CHANNEL

 5 * Output         : None

 6 * Return         : None

 7 ********************************************************************************/

 8 void MX_ADC1_Init(uint8_t ADC1_CHANNEL)

 9 {  

10   //初始化GPIO

11   MX_ADC_GPIO_Init(ADC1_CHANNEL);

12   

13   //初始化ADC1所有寄存器

14   ADC1_DeInit();

15   

16   //配置ADC1寄存器中的参数

17   MX_ADC1_CHANNEL_Init(ADC1_CHANNEL);

18   

19   //使能ADC1

20   ADC1_Cmd(ENABLE);

21   

22   //ADC1转换开始

23   ADC1_StartConversion();

24 }

 最后就是数据获取,可以选择直接获取数据,也可以获取十次数据后取平均数。


注意:


ADC获取的值是AD值,需要将其进行代入公式中才能得到电压值。


Vin = (ADC * Vref) / 1024


VCC很明显可以使用万用表先测出来,1024是因为STM8S这款的AD是10位精度。


这里测试的VCC是3.35V,VCC另外一个意思就是单片机的供给电源。


 1 /*******************************************************************************

 2 * Function Name  : MX_ADC1_Get_Data

 3 * Description    : get VCC data

 4 * Input          : None

 5 * Output         : None

 6 * Return         : fVCC

[1] [2]
关键字:STM8  ADC读取  数字量 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic481983.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:基于STM8的TIM定时器操作---STM8-第三章
下一篇:基于STM8的IIC协议--协议篇

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32-modbus rtu 之从机程序
STM32-modbus rtu 之从机程序以前移植过freemodbus,这次是自己重新写,只实现保持寄存器的读写。一、串口这部分跟上一篇文章主机程序一样,DMA接收,直接发送。二、错误反馈/*发送 错误反馈*/void  mb_sentACK( u8 cm,u8 err){    u16 temp;    serialTXbuf_st.buf[0] = local_addr;    serialTXbuf_st.buf[1] = cm+0x80;    serialTXbuf_st.buf[2] =  err; 
发表于 2019-12-02
STM32-modbus rtu 之从机程序
STM32 堆栈的理解
1、MDK STM32的内存分配 (摘自网络)C语言上分为栈、堆、bss、data、code段。具体每个段具体是存储什么数据的,直接百度吧。重点分析一下STM32以及在MDK里面段的划分。MDK下Code,RO-data,RW-data,ZI-data这几个段:Code是存储程序代码的。RO-data是存储const常量和指令。RW-data是存储初始化值不为0的全局变量。ZI-data是存储未初始化的全局变量或初始化值为0的全局变量。Flash=Code + RO Data + RW Data;RAM= RW-data+ZI-data;这个是MDK编译之后能够得到的每个段的大小,也就能得到占用相应的FLASH和RAM的大小
发表于 2019-12-02
STM32 堆栈的理解
STM32堆栈空间大小设置
1. 设置堆栈空间大小在使用STM32编程时,一般情况下我们不会关注堆栈空间的大小,因为在STM32的启动文件中,已经帮我们预先设置好了堆栈空间的大小。如下图所示的启动代码中,Stack栈的大小为:0x400(1024Byte),Heap堆的大小为:0x200(512Byte)。这也是为什么一个基础的工程编译后,RAM的空间也占用了1.6K左右的原因,因为堆栈的空间均分配在RAM中,可在编译的map文件中查看RAM资源占用的情况。若工程中使用的局部变量较多,定义的数据长度较大时,若不调整栈的空间大小,则会导致程序出现栈溢出,程序运行结果与预期的不符或程序跑飞。这时我们就需要手动的调整栈的大小。当工程中使用了malloc动态分配
发表于 2019-12-02
STM32堆栈空间大小设置
STM32--堆栈空间
函数的局部变量,都是存放在"栈"里面,栈的英文是:STACK.STACK的大小,可以在STM32的启动文件里面设置,以战舰开发板为例,在startup_stm32f10x_hd.s里面:Stack_Size      EQU     0x00000400                  AREA    STACK, NOINIT, READWRITE, ALIGN=3Stack_Mem       SPACE  
发表于 2019-12-02
STM32的堆栈(Heap&Stack)空间
最近做的一个项目遇到一个很莫名的错误,程序运行到某一部分时便会卡死,分析后,感觉在逻辑上并无错误,但是就是会卡死,而且不是偶然。 后来在网上查找资料怀疑是内存溢出,然后调试发现是两个函数中的的局部变量申请的内存空间太大,所以错误应该是栈溢出了。将这两个变量使用malloc申请堆段空间完美解决。下面是对STM32的堆栈(Heap&Stack)小结:内存分配空间 内核保护区栈段堆段数据区代码区代码区 :静态区 常量(const) 函数代码逻辑数据区:静态区 全局变量 局部变量+static堆段:动态区,管理者是程序员 malloc申请的空间栈段:动态区,管理
发表于 2019-12-02
STM32的堆栈(Heap&Stack)空间
stm8s 定时器2测量脉冲宽度(单位 us)
void Init_Timer2(void){  GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_IN_PU_NO_IT);//输入 无中断  TIM2_TimeBaseInit(TIM2_PRESCALER_16,65536-1);       //16分频, 65ms 溢出  TIM2_Cmd(ENABLE);  }uint16_t TIM2_GetCapture(void){  /* Get the Capture  Register value */  uint16_t tmpccr = 0;&n
发表于 2019-12-02
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved