zl程序教程

您现在的位置是:首页 >  其它

当前栏目

内部10位ADC

10 内部 ADC
2023-09-11 14:20:36 时间

利用查询方式:

#include "UART.H"   // 包含IAP15W4K58S4寄存器定义文件 
#define VCC 4.965   // 存放用万用表实测的单片机供电电压

unsigned int ADC_P11()
{
    unsigned int i;         // 用于软件延时程序
    unsigned char status=0; // 用于判断AD转换结束的标志
    unsigned int AD_Dat=0;  // 10位AD转换值
    ADC_CONTR|=0x80;        // 开AD转换电源,第一次使用时要打开内部模拟电源
    for (i=0;i<10000;i++);  // 适当延时等待AD转换供电稳定,一般延时1ms以内即可,为了缩短AD
                            // 调用时间,可把这2行剪切到主程序中去。
    P1ASF|=0x02;            // 选择P1.1作为AD转换通道,0x02= 0000 0010   
    ADC_CONTR=0xE1;         // 选择P1.1作为AD转换通道,最高转换速度,清转换完成标志。
    for (i=0;i<1000;i++);   // 如果是多通道模拟量进行AD转换,则更换AD转换通道后要适当延时,
// 使输入电压稳定,延时量取20μs~200μs即可,与输入电压源的内阻有关,如果输入电压信号源的内
// 阻在10K以下,可不加延时,如果是单通道模拟量转换,则不需要更换AD转换通道,也不需要加延时。
    ADC_CONTR|=0x08;        // 启动 A/D 转换,ADC_START=1。
    while(status==0)        // 等待AD转换结束。
    {
        status=ADC_CONTR&0x10;   // 判断ADC_FLAG是否等于1,0x10=0001 0000B。
    }
    ADC_CONTR&=0xE7;        // 将ADC_FLAG清0, 0xE7=1110 0111B,ADC_FLAG=0,ADC_START=0。 
    AD_Dat = (ADC_RES<<2)|(ADC_RESL&0x03);  //高低字节拼接成一个10位数。
    return AD_Dat;
}  
void main(void)
{   
    float Vin;                     // 存放计算出来的外部输入电压
    unsigned int ADvalue;          // 存放AD转换返回的结果
    UART_init();                   // 串口初始化9600/22.1184MHz
    printf("串口初始化完毕");
    while(1)
    {           
        ADvalue=ADC_P11();         // 采样P1.1口模拟输入电压
        Vin=VCC*ADvalue/1023;      // 注意是1023才正确
        printf("%.3f     ",Vin);        
        delay500ms();
    }                              // 若不用串口显示,此行可设置断点仿真观察结果
} 

利用中断方式:

#include "UART.H"   // 包含STC115F2K60S2单片机寄存器定义文件 
#define VCC 4.970   // 存放用万用表实测的单片机供电电压
unsigned int ADvalue;       // 存放AD转换返回的结果
void  ADC_P11_init()
{
    unsigned int i;         // 用于软件延时程序
    ADC_CONTR|=0x80;        // 开AD转换电源,第一次使用时要打开内部模拟电源
    for (i=0;i<10000;i++);  // 适当延时等待AD转换供电稳定,一般延时1ms以内即可,为了缩短AD
// 调用时间,可把这2行剪切到主程序中去。
    P1ASF|=0x02;            // 选择P1.1作为AD转换通道,0x02= 0000 0010   
    ADC_CONTR=0xE1;         // 选择P1.1作为AD转换通道,最高转换速度,清转换完成标志。
    for (i=0;i<1000;i++);   // 如果是多通道模拟量进行AD转换,则更换AD转换通道后要适当延时,
// 使输入电压稳定,延时量取20μs~200μs即可,与输入电压源的内阻有关,如果输入电压信号源的内
// 阻在10K以下,可不加延时,如果是单通道模拟量转换,则不需要更换AD转换通道,也不需要加延时。
    ADC_CONTR|=0x08;        // 启动 A/D 转换,ADC_START=1。
    EADC=1;
    EA=1;   
}  
void ADC(void) interrupt 5
{
//  unsigned int AD_Dat=0;    // 10位AD转换值
    unsigned char Tmp=0;      // 临时变量用于将AD转换出来的2个字节合成一个字节
    ADC_CONTR&=0xE7;          // 将ADC_FLAG清0, 0xE7=1110 0111B,ADC_FLAG=0,ADC_START=0。   
//  AD_Dat = ADC_RES;         // 默认高字节高8位。
//  AD_Dat <<= 2;
//  Tmp = ADC_RESL;           // 默认低字节低2位。
//  Tmp &= 0x03;              // 屏蔽无关位
//  AD_Dat|= Tmp;             // 高低字节拼接成一个10位数。
//  ADvalue=AD_Dat;
    ADvalue = (ADC_RES<<2)|(ADC_RESL&0x03);  //高低字节拼接成一个10位数。
    ADC_CONTR|=0x08;          // 重新启动 A/D 转换,ADC_START=1。
}
void main(void)
{   
    float Vin;                     // 存放计算出来的外部输入电压
    UART_init();                   // 串口初始化9600/22.1184MHz
    printf("串口初始化完毕");
    ADC_P11_init();
    while(1)
    {           
        Vin=VCC*ADvalue/1023;      // 注意是1023才正确
        printf("%.3f    ",Vin);     
        delay500ms();
    }                              // 若不用串口显示,此行可设置断点仿真观察结果
} 

实际调试之利用查询

#include <stc12.h>
#include <stdio.h>
#define VCC 4.95   // 存放用万用表实测的单片机供电电压

//void UART_init()//用T1作为波特率发生器
//{
//    SCON = 0X50;
//    TMOD &= 0x0F;
//    TMOD |= 0x20;
//    TH1 = 0xFD;
//    TL1 = TH1;
//    TR1 = 1;
//
//    TI = 1;
//}
void UART_init(void)//使用独立波特率发生器
{
    PCON &= 0x7F;       //波特率不倍速
    SCON = 0x50;        //8位数据,可变波特率
    AUXR &= 0xFB;       //独立波特率发生器时钟为Fosc/12,即12T
    BRT = 0xFD;     //设定独立波特率发生器重装值
    AUXR |= 0x01;       //串口1选择独立波特率发生器为波特率发生器
    AUXR |= 0x10;       //启动独立波特率发生器

    TI = 1;
}

unsigned int ADC_P11()
{
    unsigned int i;         // 用于软件延时程序
    unsigned char status=0; // 用于判断AD转换结束的标志
    unsigned int AD_Dat=0;  // 10位AD转换值
    ADC_CONTR|=0x80;        // 开AD转换电源,第一次使用时要打开内部模拟电源
    for (i=0;i<10000;i++);  // 适当延时等待AD转换供电稳定,一般延时1ms以内即可,为了缩短AD
                            // 调用时间,可把这2行剪切到主程序中去。
    P1ASF|=0x02;            // 选择P1.1作为AD转换通道,0x02= 0000 0010   
    ADC_CONTR=0xE1;         // 选择P1.1作为AD转换通道,最高转换速度,清转换完成标志。
    for (i=0;i<1000;i++);   // 如果是多通道模拟量进行AD转换,则更换AD转换通道后要适当延时,
// 使输入电压稳定,延时量取20μs~200μs即可,与输入电压源的内阻有关,如果输入电压信号源的内
// 阻在10K以下,可不加延时,如果是单通道模拟量转换,则不需要更换AD转换通道,也不需要加延时。
    ADC_CONTR|=0x08;        // 启动 A/D 转换,ADC_START=1。
    while(status==0)        // 等待AD转换结束。
    {
        status=ADC_CONTR&0x10;   // 判断ADC_FLAG是否等于1,0x10=0001 0000B。
    }
    ADC_CONTR&=0xE7;        // 将ADC_FLAG清0, 0xE7=1110 0111B,ADC_FLAG=0,ADC_START=0。 
    AD_Dat = (ADC_RES<<2)|(ADC_RESL&0x03);  //高低字节拼接成一个10位数。
    return AD_Dat;
}  

void Delay500ms()       //@11.0592MHz
{
    unsigned char i, j, k;

    i = 22;
    j = 3;
    k = 227;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

void main(void)
{   
    float Vin;                     // 存放计算出来的外部输入电压
    unsigned int ADvalue;          // 存放AD转换返回的结果
    UART_init();                   // 串口初始化9600/22.1184MHz
    printf("串口初始化完毕");
    while(1)
    {           
        ADvalue=ADC_P11();         // 采样P1.1口模拟输入电压
        Vin=VCC*ADvalue/1023;      // 注意是1023才正确
        printf("%.3f     ",Vin);        
        Delay500ms();
    }                              // 若不用串口显示,此行可设置断点仿真观察结果
} 

另一个利用中断的只需要把串口的初始化函数打印就行。