STM8单片机ADC采样功能通过定时器触发

最新更新时间:2022-01-15来源: eefocus关键字:STM8  单片机  定时器触发 手机看文章 扫描二维码
随时随地手机看文章

  在使用STM8单片机的ADC功能时,读取ADC数据时一般有两种方式,一种是通常不断地读取采样标志位,来判断ADC采样是否结束,一种是通过中断的方式来通知系统采样是否结束。


  有时候采样ADC数据的时候,需要按照一定的时间间隔,定点的去采样数据。一般使用的方式就是通过定时器定时,然后在定时中断函数中再去读取ADC采样的数据。但是这种方式采样的时间是不固定的,比如进入定时器中断后,ADC采样刚结束,就可以直接使用当前采样到的数据。但是如果运气不好的话,进入定时中断后,ADC采样刚开始,那么此时就需要等到ADC采样结束后,才能使用数据。这样就好导致每次读取ADC数据时还会有随机的一段等到ADC数据的延时。


  通常查阅STM8单片机的手册发现,ADC采样可以通过定时器来触发。

在这里插入图片描述

  通过定时器来触发ADC采样时,定时器的定时时间是固定的,采样时间也是固定的,这样采样数据的间隔也就是固定的。这样通过定时器来触发ADC的采样时间,就能完全保证每次读取ADC采样数据的时间间隔都是一样的,从而避免了数据的误差。


  数据手册中对于开启ADC触发功能描述如下:

在这里插入图片描述

  对于如何通过代码来设置ADC触发,官方也没有详细的说明,在网上也没有找到相关例程。所以只能自己摸索,还好通过自己的一番摸索,成功的通过定时器的TRGO事件触发了ADC的启动。


  关于ADC相关寄存器的设置,基本就是上面说的6条。接下来需要设置的就是定时器的相关寄存器。

在这里插入图片描述

  关于定时器只需要设置CR2寄存器中的 MMS位就可以了。


  接下来就通过代码来实现。


#include "adc.h"

#include "main.h"

#include "led.h"


u16  DATAH = 0;                          //ADC转换值高8位

u16  DATAL = 0;                          //ADC转换值低8位

_Bool ADC_flag = 0;                      //ADC转换成功标志


u16 adc_cnt = 0;

//AD通道引脚初始化

void ADC_GPIO_Init( void )

{

    PD_DDR &= ~( 1 << 2 );              //PD2 设置为输入     

    PD_CR1 &= ~( 1 << 2 );              //PD2 设置为悬空输入

    PD_DDR &= ~( 1 << 3 );              //PD3 设置为输入     

    PD_CR1 &= ~( 1 << 3 );              //PD3 设置为悬空输入

}

//ch 为单片机的ADC 通道

//ADC输入通道初始化入口参数表示通道选择

void ADC_CH_Init( u8 ch )

{

    char l = 0;

    ADC_CR1  = 0x00;                    //fADC = fMASTER/2, 8Mhz  单次转换,禁止转换

    ADC_CR2  = 0x00;                    //默认左对齐 读数据时先读高在读低

    

    ADC_CR2 |= ( 1 << 6 );              //外部触发使能


    ADC_CSR  |= ch;                     //控制状态寄存器 选择要 AD输入通道  如:PD2(AIN3)

    ADC_TDRL = ( 1 << ch  );            //禁止相应通道 施密特触发功能 1左移ch位

    ADC_CR1 |= 0x01;                    //使能ADC并开始转换

    ADC_CSR |= ( 1 << 5 );              //EOCIE 使能转换结束中断  EOC中断使能

    for( l = 0; l < 100; l++ );         //延时,保证ADC模块的上电完成 至少7us

    ADC_CR1 = ADC_CR1 | 0x01;           //再次将CR1寄存器的最低位置1 使能ADC 并开始转换

}


u16 value = 0;

//AD中断服务函数 中断号22

#pragma vector = 24                              // IAR中的中断号,要在STVD中的中断号上加2

__interrupt void ADC_Handle( void )

{

    ADC_CSR &= ~0x80;                            // 转换结束标志位清零  EOC

    //默认左对齐 读数据时先读高高8位 再读低8位

    DATAH = ADC_DRH;                             // 读出ADC结果的高8位

    DATAL = ADC_DRL;                             // 读出ADC结果的低8位

    ADC_flag = 1;                                // ADC中断标志 置1

    value = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据  0--1024

    adc_cnt++;

    LED = !LED;

}


  在ADC代码中,相比普通的ADC初始化方式,这里只需要增加一句对ADC_CR2寄存器的设置。


ADC_CR2 |= ( 1 << 6 ); //外部触发使能

在这里插入图片描述

  在ADC_CR2寄存器中 使能外部触发转换功能,设置外部触发事件为 内部定时器1 TRG事件。


  这里ADC使用的是单次触发模式,开启外部触发功能,开启ADC转换中断,当ADC转换完成之后,就会进入到ADC中断中,在中断中读取采样的数据,然后翻转LED的状态,通过示波器观察LED引脚电平的变化,就可以知道ADC中断进入的频率了。


  接下来编写定时器初始化代码。


unsigned long time_cnt = 0;

// 使用 定时器触发 ADC采样

void tim1_init( void )

{

    TIM1_ARRH = ( unsigned char )( 1000 >> 8 );         //定时1ms

    TIM1_ARRL = ( unsigned char )( 1000 );

    TIM1_PSCRH = ( unsigned char )( 0x0F >> 8 );        // 16M / (1+15) =1M

    TIM1_PSCRL = ( unsigned char )( 0x0F );

    TIM1_RCR = 0x00;                                    //重复计数器值

    TIM1_SR1 = ( ~0x01 );                        //清除更新中断标志


    TIM1_CR2 |= ( 2 << 4 );                             //使能信号,用于触发输出(TRGO)

    

    TIM1_CR1 |= 0x01;                                   //使能计数器

    TIM1_IER |= 0x01;                            //更新中断使能

}


#pragma vector  =  13                            //IAR中的中断号,要在STVD中的中断号上加2

__interrupt void Timer1_Handle( void )          //1ms 定时中断

{

    TIM1_SR1 = ( ~0x01 );                        //清除更新中断标志

    time_cnt++;

}


  定时器的初始化代码,也比正常情况下初始化代码多了一行。


TIM1_CR2 |= ( 2 << 4 ); //使能信号,用于触发输出(TRGO)


  用来开启定时的的TRG功能。

在这里插入图片描述

  经过测试,这里定时器CR2寄存器中的值 只能设置为 010 或者 011,设置为其他值时,不能触发ADC采样。最开始测试的时候按照芯片资料上这个说明,MMS的值设置的是 001,ADC总是触发不了,还以为是方法的问题,最后才发现是MMS值设置的问题。


  ADC和定时器初始化代码设置完成之后,接下来在主函数中初始化这两个函数就行了,按照资料上说的,首先初始化完ADC之后,再初始化定时器。


void main( void )

{


    __asm( "sim" );                             //禁止中断

    SysClkInit();

    delay_init( 16 );

    LED_GPIO_Init();

     ADC_GPIO_Init();

    ADC_CH_Init(3);

    tim1_init();

    __asm( "rim" );                             //开启中断

    while( 1 )

    {

       

    }

}

  接下来运行程序。

在这里插入图片描述

  分别在ADC中断中和定时器中断中用一个变量来统计中断执行的次数,通过变量变量观察窗口可以看到,ADC中断的次数比定时器中断的次数多了1次。这是因为ADC在初始化的时候,已经运行了一次。


  然后通过示波器观察LED口的电平。

在这里插入图片描述

  定时器的定时时间是1ms,LED的高低电平时间也是1ms,说明通过定时器触发ADC采样功能是正常运行的。


  为了减小系统进入中断的次数,可以将定时器的中断功能关闭掉。定时器中断功能关闭后,ADC的触发功能依然可以正常使用。

在这里插入图片描述

  这样只需要开启一个ADC中断,再加上定时器的TRG触发功能后,就可以实现ADC定时采样的功能了。

关键字:STM8  单片机  定时器触发 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic558809.html

上一篇:STM8单片机通过PWM触发ADC同步采样
下一篇:单片机快速将库函数版代码移植为寄存器代码方法

推荐阅读

利用定时器使单片机输出方波
在P1^0口输出方波。 废话不多说,直接上代码。#include <reg52.h>sbit FB = P1^0;void Init_ET_0()//定时器初始化函数{ TMOD = 0x01;//启用定时器 0 ,工作模式为 模式1 。 EA = 1;//开总中断 ET0 = 1;//开定时器开关 TR0 = 1;//启动定时器 TH0 = (65536 - 500)/256;//给高八位赋初值 TL0 = (65536 - 500)%256;//给低八位赋初值}void Servoce_ET_0() interrupt 1 //定时器服务函数{ TH0 = (65536 - 500)/256;//重装高八位 TL0
发表于 2022-08-11
利用<font color='red'>定时器</font>使<font color='red'>单片机</font>输出方波
51单片机外接ADC0808制作简易电压表
main.c#include<reg52.h>#define uchar unsigned char#define uint unsigned int sbit Start = P3^0;sbit EOC=P3^1; //sbit OE=P3^2 ; //uchar code table [] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//段选uchar code table_SMG [] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//位选 //------------------------变量区-
发表于 2022-08-11
51<font color='red'>单片机</font>外接ADC0808制作简易电压表
新唐N76E003+GPRS 单片机复位故障排除手记
应用场景GPRS模块采用AIR202/AIR208,电源方案是JW5033;单片机采用新唐N76E003,双串口,18K flash,电源与GPRS的DCDC 即JW5033共用一个5V输入电源。问题描述GPRS联网时或联网成功后收发数据的数据,新唐单片机复位重启。故障排除1、单片机电源前增加电容初步怀疑是供电不足,使用示波器观察后排除此原因,如果真的是供电不足,GPRS模块也应该会同时重启,实际上单片机模块重启时GPRS模块一直正常工作。2、设置单片机P2.0引脚为输入模式而非复位模式将P2.0引脚由复位引脚更改为输入引脚后,故障排除。我的理解是更改为输入引脚后,射频干扰不足以引起单片机复位了,深层次的原因不详。
发表于 2022-08-10
新唐N76E003+GPRS <font color='red'>单片机</font>复位故障排除手记
关于51单片机的地址空间溢出以及解决方法的个人看法(proteus无法仿真)
在51单片机程序编写中,当变量过多而且数据类型过大的话,容易在编译的时候出现以下的问题,具体表现为: *** ERROR L107: ADDRESS SPACE OVERFLOWSPACE: DATA SEGMENT: _DATA_GROUP_LENGTH: 0019HProgram Size: data=130.0 xdata=7 code=3267Target not created.这样子也就是所谓的编译失败,不能生成HEX文件,更加无法烧写到程序中去,那么如何解决这个问题呢,我在网上找到了解法,网上的具体步骤如下:1.先点击这个图标2.在其中的memory model 将small改成compact选项,那么即可编译通过。3
发表于 2022-08-10
关于51<font color='red'>单片机</font>的地址空间溢出以及解决方法的个人看法(proteus无法仿真)
51单片机脉冲信号的计数和LCD显示
设计目标和思路在个人剂量仪开发的过程中,从探头输出的核脉冲信号经过后期放大,成形,滤波以及甄别之后,成为一系列脉冲信号输出,这种脉冲信号由于衰变的随机性,并不是固定频率的脉冲信号。我们本次设计就是针对这种脉冲进形脉冲信号的计数以及在LCD1602显示屏上面的显示。这是C语言的代码部分#include"reg51.h" #include <stdio.h>#include <math.h>#include <string.h>#include <intrins.h>#define uint8_t unsigned char //0-255#define uint16
发表于 2022-08-10
51<font color='red'>单片机</font>脉冲信号的计数和LCD显示
51单片机之74HC138译码器控制数码管进行100s计数
/** I use a timer in my code to control the time I use 138decoder int the hardware**/#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;uchar code tab_1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};uchar tab_2[2];uchar counter=0,time=0,counter_T
发表于 2022-08-10

推荐帖子

印制电路板的电磁兼容性
电路的合理布局 􀁡地线的设计 􀁡信号走线的设计 􀁡线路板层数的选择 􀁡器件的安排 PCB的EMC分析基本定律 􀁡克希霍夫定律:任何时域信号由源到负载的传输都必须构成一个完 整的回路,一个频域信号由源到负载的传输都必须有一个 最低阻抗的路径。 印制电路板的电磁兼容性
czf0408 LED专区
看maychang“整流杂谈”,学习整流知识
看maychang“整流杂谈”,大家一起来学习整流知识吧~~ [index] [#483778,1981397]整流杂谈(一) [#484435,1985100]整流杂谈(二) [#484851,1987685]整流杂谈(三) [#486297,1996348]整流杂谈(四) [#521937,2138147]整流杂谈(五) [#536154,2180222]整流杂谈(六) [/index] 看maychang“整流杂谈”,学习整流知识
okhxyyo 电源技术
20种常用模拟电路
本帖最后由paulhyde于2014-9-1509:08编辑20常用的模拟电路,大家捧个场啊 20种常用模拟电路
非雪之悠 电子竞赛
用mega16+L298N驱动直流电机遇到的问题
我在制作一个遥控小车。负责无线通信的是24L01,MEGA16为主控芯片,PWM信号经过与非门驱动L298控制直流电机。24L01的程序应经调试成功。现在的问题是接通启动电机,会对MEGA16的IO口产生影响,貌似有某种规律的杂波,并且对24L01的数据读写造成影响,不能正常工作。可是,事实是电机,L298与单片机之间即使只是共地,还是会有这样。电机不工作的时候,都是很正常的。搞不懂。请问哪位大哥做过这方面的东西,指教一下。应该如何改正?用mega16+L298N驱动直流电机遇到的问题
hy5239 RF/无线
逆变资料
本帖最后由paulhyde于2014-9-1503:03编辑给大家传个逆变资料哦 呵呵 逆变资料
beautygj 电子竞赛
art格式的gerber转换成PCB文件
再百度上找了些教程,按照上面说的,AD中新建CAM文件,导入文化和钻孔文件,结果钻孔文件和走线的文件都不重合了,就不知道怎么做了,求指导art格式的gerber转换成PCB文件
麻袋 PCB设计
小广播
实战 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved