【STC库函数】ADC模数转换器的使用

今天我们来看看ADC。

不是你游戏里的ADC哈,是模拟到数字转换器(Analog-to-Digital Converter)

STC32G12k128的ADC是12位分辨率,有15个通道。

但是遗憾的是我们的STC8G1K08A-SOP8的这款没有ADC。不过STC8G1K08A的其他封装的有,虽然只有10位六通道吧。

所以我们还是主要讲讲STC32的ADC。

讲ADC之前我们还要谈谈Vref,基准电压源。

如果芯片有这个引脚的话,我们最好是给Vref接个2.5V的基准电压源,实在不行就直接接VCC,反正不能悬空。

开源自己设计的STC核心板,集成STC32和STC8一次性学习两款芯片-CSDN博客文章浏览阅读911次,点赞23次,收藏19次。官方提供的最小系统图也就是俩电容,一个10uf以上,一个100nf,虽然说10uf以上,但是10uf应该也可以,我是因为手头上22uf的电容比较多,所以用的22uf,大家也可以根据自己的库存去决定,反正打板出来焊盘大小都是一样的,一样封装的都是可以随便替换。一个STC8G1K08A-SOP8的官方推荐零售价是0.59 + 0.1,所以小伙伴们买的时候注意价格,我买的时候是0.75,因为价格差的不多并且是从经常买的店铺里卖的,所以就不管这点差价了,总之大家买的时候别买价格太离谱的。_stc32和stc8https://blog.csdn.net/m0_63235356/article/details/144374813?spm=1001.2014.3001.5501我用的是之前开源的板子,有个2.5V的基准电压源,如果我们手上的板子没有2.5V的基准电压源,那么计算公式是不一样的,这边要注意一下。

然后ADC实际上是有16个通道,但是最后一个是内部固定的1.19V,所以我们能用的是15个通道。

这个1.19V的作用就是假设我们ADC15读出来的值是x,而其他某通道读出的是y。

我们知道不管这个x是多少,它代表的就是1.19V,所以某通道的电压就是(1.19V*y)/x

ADC转换的公式如下。

看起来有点复杂,但等等我们一边看这个公式一边看库函数就不复杂了。

ADC的转换公式如下。

上面的ADC外部参考源的电压就是Vref接的基准电压源,记得要根据自己Vref接的电压来改变计算公式。

也就是说我们ADC的电压范围就是0~Vref的电压,Vref接2.5V和Vref接5V之间精度的差别就是两倍,因为12位ADC一共就4096个数,拿4096来表示0~2.5V肯定就比拿4096去表示0~5V要更精确。

接下来看看库函数。

我们首先需要把这个文件STC32G_ADC.c加入工程里。

接下来使用下面这个函数来配置ADC。

配置用的结构体的成员都是我们上面ADC转换时间公式里出现过的。

第一个SMPduty表示ADC采样时间,范围是0~31,但是绝不能小于10,官方推荐是15,但是采样时间越长精度越高,所以我们直接拉满,填上31。

第二个Speed实际上是选择ADC工作的时钟频率,其实是选择系统时钟给ADC提供脉冲时分频的系数,可以是0~15,因为在寄存器中它是占4个bit。结合上面的公式,不管我们填多少,都先是2分频,然后再分频(Speed+1)。

也可以选择宏定义来赋值,大家看直接填数字好还是填宏定义好,挑自己喜欢的来就行。

第三个 AdjResult 是选择ADC结果对齐方式。有左对齐和右对齐两种,一般是选择右对齐。

第四个CsSetup是ADC通道选择时间控制,取值是0或1,其实还是控制ADC转换速度的,默认是0,所以我们就填0。

第五个CsHold是ADC通道选择保持时间控制,取值范围是0~3,默认选择1。

需要注意的是ADC转换时间不能超过800kHz

配置完之后就使能ADC。

使能完ADC之后需要等待1ms,等待ADC内部电源稳定下来。

接着就可以读取ADC的转换结果了,参数传入通道,0~15,通道15固定是内部的1.19V。

如果读出来的是4096,那么就表示发生错误,也就是说只有返回值小于4096的时候我们才能用ADC的转换结果。

记得把对应的GPIO口设置为高阻输入模式。

我下面示例代码中用串口3来打印转换结果的数据,小伙伴们可以看看上一篇文章,因为有些地方要修改的上一篇里都有,我这里就不赘述了。

我用的串口3的P00和P01口作为串口的TXD和RXD,这会占用ADC的俩通道,我这边是测试一下,小伙伴们使用的时候记得不要冲突了。

#include "STC32G_GPIO.h"
#include "STC32G_Delay.h"
#include "STC32G_UART.h"
#include "STC32G_NVIC.h"
#include "STC32G_Switch.h"
#include "STC32G_ADC.h"

void GPIO_Init(void){
    P0_MODE_IN_HIZ(GPIO_Pin_2);
    P0_MODE_IN_HIZ(GPIO_Pin_3);
    P0_MODE_IN_HIZ(GPIO_Pin_4);
    P0_MODE_IN_HIZ(GPIO_Pin_5);
    P0_MODE_IN_HIZ(GPIO_Pin_6);
    // 开几个意思意思.
}

void UART_Init(void){
    COMx_InitDefine initer;
    initer.BaudRateDouble = DISABLE;
    initer.Morecommunicate = DISABLE;
    initer.UART_BaudRate = 115200;
    initer.UART_BRT_Use = BRT_Timer3;
    initer.UART_Mode = UART_8bit_BRTx;
    initer.UART_RxEnable = ENABLE;

    UART_Configuration(UART3, &initer);
    NVIC_UART3_Init(ENABLE, Priority_1);

    P0_MODE_IO_PU(GPIO_Pin_0);
    P0_MODE_IO_PU(GPIO_Pin_1);

    UART3_SW(UART3_SW_P00_P01);
}

void ADC_Init(void){
    ADC_InitTypeDef initer;
    initer.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;     // 右对齐
    initer.ADC_CsHold = 1;              // 按照默认的来
    initer.ADC_CsSetup = 0;             // 按照默认的来
    initer.ADC_SMPduty = 31;            // 最大的采样时间
    initer.ADC_Speed = ADC_SPEED_2X8T;  // 折中一下

    ADC_Inilize(&initer);

    ADC_PowerControl(ENABLE);
    NVIC_ADC_Init(DISABLE, Priority_0); // 不使用中断
    delay_ms(1);        // 等待内部电源稳定
}

void main(void){
    uint8 i;
    WTST = 0;		//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXSFR();		//扩展SFR(XFR)访问使能 
    CKCON = 0;      //提高访问XRAM速度
    
    UART_Init();
    GPIO_Init();
    ADC_Init();
    
    EA = 1;
    
    while(1){
        for(i = 0; i < 16; ++i){
            printf("ADC%d is %d\r\n",i,Get_ADCResult(i));
        }
        delay_ms(1000);
    }
    return ;
}



通道15的转换结果是1948 +- 1 这样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值