历史上的今天

今天是:2024年09月15日(星期日)

2021年09月15日 | STM8学习笔记---ADC多通道采样

发布者:东土大唐88 来源: eefocus关键字:STM8  ADC  多通道采样 手机看文章 扫描二维码
随时随地手机看文章

STM8S003单片机ADC采样通道总共有5个,从AIN2---AIN6,多通道采样时需要将ADC转换设置为单次转换模式,每次切换采样通道后,需要重新初始化 ADC,采样结果在中断中读取。


IO口初始化代码


//AD通道引脚初始化

void ADC_GPIO_Init( void )

{

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

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

    

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

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

    

    PC_DDR &= ~( 1 << 4 );              //PC4 设置为输入      AIN2

    PC_CR1 &= ~( 1 << 4 );              //PC4 设置为悬空输入

    

    PD_DDR &= ~( 1 << 5 );              //PD5 设置为输入     AIN5 

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

    

    PD_DDR &= ~( 1 << 6 );              //PD6 设置为输入     AIN6 

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

    

}

将ADC的IO口都设置为输入模式,悬空输入。


下来初始化ADC功能


void ADC_CH_Init( u8 ch )

{

    char l = 0;

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

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

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

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

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

    ADC_CSR |= 0x20;                    //EOCIE 使能转换结束中断  EOC中断使能

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

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

}

将ADC设置为单次转换模式,每次转换时需要手动将CR1寄存器最低位置1.


在中断中读取转换成功后的数据。


#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

}

中断中将转换后的采样值存储在DATAH,和DATAL中,并置位采样结束标志位ADC_flag,采样函数判断标志位为1时,就去读取ADC采样值。


采样值读取函数:


//采集PC4电压值  AIN2

u16 ReadVol_CH2( void )

{

    u16 voltage = 0;

    ADC_CH_Init( 1 );

    while( ADC_flag == 0 );

    if( ADC_flag )

    {

        ADC_flag = 0;

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

        //ADC_CR1 = ADC_CR1 | 0x01;               // 再次将CR1寄存器的最低位置1  启动下一次转换

    };

    return voltage;

}

单片机有些引脚的功能需要通过选项字开启,通过ST Visual Programmer软件设置选项字方法如下:

在AFR7中,将选项字中将PC4设置为AIN2功能。


adc完整代码如下:


#include "adc.h"

#include "main.h"

 

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

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

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

 

 

//AD通道引脚初始化

void ADC_GPIO_Init( void )

{

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

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

    

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

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

    

    PC_DDR &= ~( 1 << 4 );              //PC4 设置为输入      AIN2

    PC_CR1 &= ~( 1 << 4 );              //PC4 设置为悬空输入

    

    PD_DDR &= ~( 1 << 5 );              //PD5 设置为输入     AIN5 

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

    

    PD_DDR &= ~( 1 << 6 );              //PD6 设置为输入     AIN6 

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

    

}

 

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

void ADC_CH_Init( u8 ch )

{

    char l = 0;

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

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

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

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

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

    ADC_CSR |= 0x20;                    //EOCIE 使能转换结束中断  EOC中断使能

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

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

}

 

 

//采集PC4电压值  AIN2

u16 ReadVol_CH2( void )

{

    u16 voltage = 0;

    ADC_CH_Init( 1 );

    while( ADC_flag == 0 );

    if( ADC_flag )

    {

        ADC_flag = 0;

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

        //ADC_CR1 = ADC_CR1 | 0x01;               // 再次将CR1寄存器的最低位置1  启动下一次转换

    };

    return voltage;

}

 

//采集PD2电压值  AIN3

u16 ReadVol_CH3( void )

{

    u16 voltage = 0;

    ADC_CH_Init( 2 );

    while( ADC_flag == 0 );

    if( ADC_flag )

    {

        ADC_flag = 0;

        voltage = ( DATAH << 2 ) + DATAL ;

        //ADC_CR1 = ADC_CR1 | 0x01;              //当通道不需要切换时,只需初始化一次,以后每次读取完数据后,需要手动开启下一次转换

    };

    return voltage;

}

//采集PD3电压值  AIN4

u16 ReadVol_CH4( void )

{

    u16 voltage = 0;

    ADC_CH_Init( 3 );

    while( ADC_flag == 0 );

    if( ADC_flag )

    {

        ADC_flag = 0;

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

        //ADC_CR1 = ADC_CR1 | 0x01;              // 再次将CR1寄存器的最低位置1  启动下一次转换

    };

    return voltage;

}

 

//采集PD5电压值  AIN5

u16 ReadVol_CH5( void )

{

    u16 voltage = 0;

    ADC_CH_Init( 4 );

    if( ADC_flag )

    {

        ADC_flag = 0;

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

        //ADC_CR1 = ADC_CR1 | 0x01;          //再次将CR1寄存器的最低位置1  启动下一次转换

    };

    return voltage;

}

 

//采集PD6电压值  AIN6

u16 ReadVol_CH6( void )

{

    u16 voltage = 0;

    ADC_CH_Init( 5 );

    if( ADC_flag )

    {

        ADC_flag = 0;

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

        //ADC_CR1 = ADC_CR1 | 0x01;          //再次将CR1寄存器的最低位置1  启动下一次转换

    };

    return voltage;

}

 

//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位

[1] [2]
关键字:STM8  ADC  多通道采样 引用地址:STM8学习笔记---ADC多通道采样

上一篇:STM8学习笔记---Modbus通信协议简单移植
下一篇:STM8单片机ADC模拟看门狗功能实现

推荐阅读

   昨日,网络上出现OPPO致供应商的一封信,内容提到“因汇顶科技迫于其他客户压力,推迟向OPPO某款手机提供指纹芯片,给公司造成巨大损失。因此OPPO将汇顶科技列入供应商禁用名单,为期5年。”今天,集微网联系到了OPPO与汇顶科技了解,双方分别对此事做出回应。汇顶科技在官方网站公布《关于汇顶科技工作失误的相关声明》,首先承认失误并对OPPO表示...
单片机源程序如下:#define MAIN_Fosc 24000000L //定义主时钟#include "STC15Fxxxx.H"#include "T_SineTable.h"#define PWM_DeadZone 12 /* 死区时钟数, 6 ~ 24之间 *//************* 功能说明 *********...
实际上,互感器测试仪的精度并非其最重要的指标,在互感器计量检定标准规范中,规定整个回路所产生的测试误差值不超过被测互感器等级的20%,事实上,规定测试仪在实际工作中所显示的数据必需真实可信。实验时的常见技术问题:1.选频滤波性能互感器计量检定是对基波的精确测量,因为标准规定和被测互感器的二次工作电流的误差值工作电流波形图二、三次畸变...

史海拾趣

问答坊 | AI 解惑

摄像头的寿命有多久?

:这要看摄像头本身的电路设计而定,如有些以COMS为基础的摄像头使用上一般都比以CCD为基础的摄像头寿命要短;COMS的摄像头有些甚至使用几个月便告终正寝,而CCD摄像头若配合品质优良的供电器皆可持续通电使用几个月,甚至数年都没什么问题。    ...…

查看全部问答∨

这样的干扰怎么解决?请赐教

本人设计的工业仪表,遇到这样的问题:输入信号0-20MV。当用手触摸输入端子的时候,显示值会波动,这是什么干扰(好象是串模干扰),如何解决?注明:信号是经过了2个模拟开关(CD4051),由OP07放大 再采样。…

查看全部问答∨

我们是一群平凡的硬件工程师

我们是一群平凡的硬件工程师,平均做嵌入式硬件开发10多年了,在外企工作的同时对单片机爱好者进行系统的单片机嵌入式硬件培训,我们相信成功只属于努力的人! 只要有你们的支持我们就会成功.只要你努力了,你也一样会成功。无论学生多少,不管学生 ...…

查看全部问答∨

关于KernelIoControl

KernelIoControl的第一个参数IOCTL_HAL_RELEASE_SYSINTR与IOCTL_HAL_REQUEST_SYSINTR有什么区别: 即 KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pHardwareContext->dwSysintrSDMMC, sizeof(DWORD), NULL, 0, NULL)与 KernelIoControl(IOCTL_ ...…

查看全部问答∨

ARM&WINCE 多通道数据采集驱动实现思路(求高手指点)

本人要编一个多通道数据采集的驱动程序,硬件采用S3C2410A,操作系统是wince,开发工具是PB。第一次接触这些东西,思路有些乱:      数据采集的频率由S3C2410A自带的PWM Timer实现,通过设置PMW寄存器的预分频值、分频值、TC ...…

查看全部问答∨

请教一些DSP编程中不解的问题

刚有机会接触一个做DSP开发的公司,遇到许多不明白的问题,想来请教一下这里的高手。 他们的产品大多数用的TI的DSP芯片。他们的程序在eclipse里开发,却不在那里调试,全部要到DOS环境下编译运行,要做许多的make文件,看得头很晕。开发出的程序却 ...…

查看全部问答∨

高人指点一下

嵌入式跟一般的软件编程有什么不同? 不要笑我 新手…

查看全部问答∨

宏 CONTAINING_RECORD 的具体作用和用法?

关于CONTAINING_RECORD的具体意义和用法本人不甚了解,请各位高人指点!…

查看全部问答∨

s3c2451的wince6.0的block0img.nb0生成不能用问题

我在wince6.0上遇到这样问题的:s3c2450在VS2005中编译出来的blockimg0.nb0不能使用,请问有没有遇到这样的问题呀? 我怀疑是.bib文件中设置的问题,可修改也没什么实质性的变化?…

查看全部问答∨

LM3S8962开发的软件使用基础

论坛要搞活动了,我来上传点初学需要的资料,初学者可以看看这两个文档,从安装程序,运行demo到新建工程都有讲解。…

查看全部问答∨
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

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