视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
单片机内部AD的用法
2025-09-29 00:12:56 责编:小OO
文档

STC系列单片机内部AD的应用

作者:郭天祥    来源:原创    更新时间:2008-11-27 22:16:38    浏览次数:11438

    STCLE52AD、54AD、58AD、516AD这几款系列的STC单片机内部自带有8路8位的AD转换器,分布在P1口的8位上,当时钟在40MHz以下时,每17个机器周期可完成一次AD转换。

    与AD相关的几个寄存器如表1所示。

表1 STC系列单片机AD相关寄存器

名称

地址功能描述D7D6D5D4D3D2D1D0复位值
P1_ADC_EN97H允许P1.X成为AD口

AD_P17AD_P16AD_P15AD_P14AD_P13AD_P12AD_P11AD_P100000 0000
ADC_CONTRC5HAD转换控制寄存器

------ADC_FLAGADC_STARTCHS2CHS1CHS0xxx0 0000
ADC_DATAC6HAD转换结果寄存器

----------------0000 0000
    P1_ADC_EN:P1.X口的AD使能寄存器。

        相应位设置为“1”时,对应的P1. X口作为AD转换使用,内部上拉电阻自动断开。

    ADC_CONTR:AD 转换控制寄存器。

        ADC_START:AD转换启动控制位,设置为“1”时,AD开始转换。

        ADC_FLAG:AD转换结束标志位,当AD转换完成后,ADC_FLAG=1。

        CHS2、CHS1、CHS0:为模拟输入通道选择,如表2所示。

表2  STC系列单片机AD模拟通道选择设置

CHS2CHS1CHS0模拟输入通道选择
000选择P1.0作为AD输入来用

001选择P1.1作为AD输入来用

010选择P1.2作为AD输入来用

011选择P1.3作为AD输入来用

100选择P1.4作为AD输入来用

101选择P1.5作为AD输入来用

110选择P1.6作为AD输入来用

111选择P1.7作为AD输入来用

    ADC_DATA:AD 转换结果寄存器。模拟/数字转换结果计算公式如下:

结果=256×Vin / Vcc

    Vin为模拟输入通道输入电压,Vcc为单片机实际工作电压,用单片机工作电压作为模拟参考电压。

    下面一个例程演示STCLE516AD/X2系列单片机的A/D转换功能。 时钟11.0592MHz, 转换结果以16进制形式输出到串行口,可以用串行口调试程序观察输出结果。(本代码摘自宏晶科技芯片手册,经作者调试可正常运行)。

    新建文件part3.4.5.c,程序代码如下:

        #include 

#include

// 定义与 ADC 有关的特殊功能寄存器

sfr P1_ADC_EN = 0x97; //A/D转换功能允许寄存器

sfr ADC_CONTR = 0xC5; //A/D转换控制寄存器

sfr ADC_DATA = 0xC6;  //A/D转换结果寄存器

typedef unsigned char INT8U;

typedef unsigned int INT16U;

void delay(INT8U delay_time) // 延时函数

{

    INT8U n;

    INT16U m;

for (n=0;n        {

            for(m=0;m<10000;m++);

        }

}

void initiate_RS232(void)  //串口初始化

{

    ES = 0;          // 禁止串口中断

    SCON = 0x50;   // 0101,0000 8 位数据位, 无奇偶校验

    T2CON = 0x34;  // 0011,0100, 由T2 作为波特率发生器

    RCAP2H = 0xFF; // 时钟11.0592MHz, 9600 波特率

    RCAP2L = 0xDB;

    ES = 1;        // 允许串口中断

}

void Send_Byte(INT8U one_byte) // 发送一个字节

{

    TI = 0;     // 清零串口发送中断标志

    SBUF = one_byte;

    while (TI == 0);

    TI = 0;     // 清零串口发送中断标志

}

INT8U get_AD_result(INT8U channel)

{

    INT8U AD_finished = 0; // 存储 A/D 转换标志

    ADC_DATA = 0;

    ADC_CONTR = channel; // 选择 A/D 当前通道

    delay(1);             //使输入电压达到稳定

    ADC_CONTR |= 0x08; //0000,1000 令 ADC_START = 1, 启动A/D 转换

    AD_finished = 0;

    while ( AD_finished == 0 ) // 等待A/D 转换结束

    {

        AD_finished = (ADC_CONTR & 0x10); //0001,0000, ADC_FLAG ==1测试A/D转                  换结束否

    }

    ADC_CONTR &= 0xF7; //1111,0111 令 ADC_START = 0, 关闭A/D 转换,

    return (ADC_DATA); // 返回 A/D 转换结果

}

void main()

{

    initiate_RS232();

    P1 = P1 | 0x63; // 0110,0011,要设置为 A/D 转换的P1.x 口,先设为高

    P1_ADC_EN = 0x63; //0110,0011, P1 的P1.0,P1.1,P1.5,P1.6 设置为 A/D 转换输入脚

    // 断开P1.0,P1.1,P1.5,P1.6 内部上拉电阻

    while(1)

    {

        Send_Byte(get_AD_result(0)); //P1.0 为 A/D 当前通道, 测量并发送结果

        delay(0x200);

        Send_Byte(get_AD_result(1)); //P1.1 为 A/D 当前通道, 测量并发送结果

        delay(0x200);

        Send_Byte(get_AD_result(5)); //P1.5 为 A/D 当前通道, 测量并发送结果

        delay(0x200);

        Send_Byte(get_AD_result(6)); //P1.6 为 A/D 当前通道, 测量并发送结果

        delay(0x200);

        Send_Byte(0); // 连续发送 4 个 00H, 便于观察输出显示

        Send_Byte(0);

        Send_Byte(0);

        Send_Byte(0);

        delay(0x200); // 延时

        delay(0x200);

        delay(0x200);

        delay(0x200);

        delay(0x200);

        delay(0x200);

    }

}

    知识点:typedef与#define的区别

        typedef:类型定义,其功能是用户为已有数据类型取“别名”。

        如:typedef  int  INT; 意思是将int重新定义为INT,以后使用INT a;就相当于int     a;

    用typedef定义数组、指针、结构等类型将带来很大的方便,不仅使程序书写简单,而且使意义更为明确,因而增强了可读性。例如:typedef int a[10];表示a是整型数组类型,数组长度为10,然后就可用a定义变量,如:a s1,s2;完全等效于:int s1[10],s2[10];

define:宏定义。

    如:#define PI 3.14 意思是以后程序中出现PI的地方将用3.14代替,这个替换是在编译预处理阶段完成的,注意#define最后没有分号,否则编译时将分号一同带入PI中。

下载本文
显示全文
专题