找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3740|回复: 6
收起左侧

这个STC15W408AS单片机两路测量两路AD的程序如何修改?

[复制链接]
ID:229232 发表于 2019-10-23 22:35 | 显示全部楼层 |阅读模式
200黑币
需要一个STC15W408AS单片机测量两个模拟量,测量一路的我会,我测一个用的是P1.1口我不知道怎么测量两个,我把我的一路的得参考内部电压的AD程序发出来大家帮我改改,改好的分拿走!(参考意见:好像内核就1个ADC,所以得测完一路然后计算发送给寄存器,也就是变量V是多少,然后在测量另外一路的,在重复此过程,在定义一个变量T是多少,有点像双离合)

//内部BandGap为基准测电压
//-----------------------------------------
#define  uchar unsigned char  
#define uint  unsigned int
unsigned int v;        
//ADC相关设定参数
#define ADC_POWER   0x80            //ADC电源控制位
#define ADC_FLAG    0x10            //ADC完成标志
#define ADC_START   0x08            //ADC起始控制位
#define ADC_SPEEDLL 0x00            //540个时钟
#define ADC_SPEEDL  0x20            //360个时钟
#define ADC_SPEEDH  0x40            //180个时钟
#define ADC_SPEEDHH 0x60            //90个时钟
//-----------------------------------------
//BandGap相关参数
//注意:需要在下载代码时选择"在ID号前添加重要测试参数"选项,才可在程序中获取此参数
//#define ID_ADDR_ROM 0x03f7      //1K程序空间的MCU
//#define ID_ADDR_ROM 0x07f7      //2K程序空间的MCU
//#define ID_ADDR_ROM 0x0bf7      //3K程序空间的MCU
//#define ID_ADDR_ROM 0x0ff7      //4K程序空间的MCU
//#define ID_ADDR_ROM 0x13f7      //5K程序空间的MCU
#define ID_ADDR_ROM 0x1ff7      //8K程序空间的MCU
//#define ID_ADDR_ROM 0x27f7      //10K程序空间的MCU
//#define ID_ADDR_ROM 0x2ff7      //12K程序空间的MCU
//#define ID_ADDR_ROM 0x3ff7      //16K程序空间的MCU
//#define ID_ADDR_ROM 0x4ff7      //20K程序空间的MCU
//#define ID_ADDR_ROM 0x5ff7      //24K程序空间的MCU
//#define ID_ADDR_ROM 0x6ff7      //28K程序空间的MCU
//#define ID_ADDR_ROM 0x7ff7      //32K程序空间的MCU
//#define ID_ADDR_ROM 0x9ff7      //40K程序空间的MCU
//#define ID_ADDR_ROM 0xbff7      //48K程序空间的MCU
//#define ID_ADDR_ROM 0xcff7      //52K程序空间的MCU
//#define ID_ADDR_ROM 0xdff7      //56K程序空间的MCU
//#define ID_ADDR_ROM 0xeff7      //60K程序空间的MCU


//-----------------------------------------
//声明

void Delay20ms()                //@12.000MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 1;
        j = 234;
        k = 113;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}


/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
           P1ASF = 0x02;                   //设置P1口为AD口
    ADC_RES = 0;                    //清除结果寄存器
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
        Delay20ms();
}
/*----------------------------
读取ADC结果
----------------------------*/
uint GetADCResult(uchar ch)
{
    uint ADC_10BIT_RES;
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
    _nop_();                        //等待4个NOP
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成
    ADC_CONTR &= ~ADC_FLAG;         //关闭 ADC
    ADC_10BIT_RES=ADC_RES;      //得到高8位
    ADC_10BIT_RES<<=2;
    ADC_10BIT_RES+=ADC_RESL;     //得到低2位
        
    return ADC_10BIT_RES;                 //返回ADC结果

}

/*----------------------------
发送ADC结果
----------------------------*/
void ShowResult(uchar ch)
{
    uint adc_res10,//测量设定通道adc值
    bandgap,       //bandgap预储存校准值,单位毫伏
    adc_9gallery_res; //测量第九通道(bandgap)值
    float power_voltage,        //系统供电电压,单位毫伏
    ADC_voltage;     //设定通道电压值,单位毫伏

    uchar  code *cptr; //定义ROM(代码)区指针
    //uchar  idata *iptr;//定义RAM(内存)区指针

    cptr = ID_ADDR_ROM;         //从程序区读取BandGap电压值(单位:毫伏mV)
    bandgap=*cptr++;
    bandgap<<=8;
    bandgap+=*cptr;
    /*iptr = ID_ADDR_RAM;         //从内存区读取BandGap电压值(单位:毫伏mV)
    bandgap=*iptr++;              //两种方法结果一样,上面的方法需要在下载式勾选"在ID号前添加重要测试参数"选项,才可在程序中获取此参数
    bandgap<<=8;                  //下面的方法不需要
    bandgap+=*iptr;    */
    //测量设定通道adc值
    ADC_RES = 0;                    //清除结果寄存器
    P1ASF = 0x02;                   //设置P1口为AD口
    GetADCResult(ch);
    GetADCResult(ch);                 //读三次获得稳定
    adc_res10= GetADCResult(ch);
    //测量第九通道(bandgap)值
    ADC_RES = 0;                    //清除结果寄存器
    P1ASF = 0x00;                   //设置读第九通道
    GetADCResult(0);                 //测bandgap时,调用此函数时通道数只能填0
    GetADCResult(0);                 //读三次获得稳定
    adc_9gallery_res=GetADCResult(0);
    //计算系统供电电压
    power_voltage=(float)bandgap*1024/adc_9gallery_res;
    //计算ADC通道测得电压值
    ADC_voltage=(float)bandgap*adc_res10/adc_9gallery_res;
        v=ADC_voltage;
        
}


回复

使用道具 举报

ID:213173 发表于 2019-10-24 11:00 | 显示全部楼层
测量1个ADC通道与测量8个通道是一样的,内部ADC硬件只有一套,通过控制选择开关轮流转换。
需要使用哪个通道只要把相应端口模式设为高阻:
P1M0 = 0x00
P1M1 = 0x01~0xff(1~8通道)
模拟输入通道设为:
P1ASF = 0x01~0xff(1~8通道)
再多设几个变量保存读取的数据:
adc_res10= GetADCResult(0);//第一通道
adc_res11= GetADCResult(1);
adc_res12= GetADCResult(2);
adc_res13= GetADCResult(3);
adc_res14= GetADCResult(4);
adc_res15= GetADCResult(5);
adc_res16= GetADCResult(5);
adc_res17= GetADCResult(7);//第八通道
滤波、比较、算法等函数都是共用的。
读新增第九通道内部参考电压时只要改设P1ASF = 0x00;
与GetADCResult(0);括号内参数无关,习惯填0。
回复

使用道具 举报

ID:229232 发表于 2019-10-24 17:56 | 显示全部楼层
wulin 发表于 2019-10-24 11:00
测量1个ADC通道与测量8个通道是一样的,内部ADC硬件只有一套,通过控制选择开关轮流转换。
需要使用哪个通 ...

大哥方便帮我直接把程序改好吗?
回复

使用道具 举报

ID:170318 发表于 2019-10-24 20:32 | 显示全部楼层
我一直在用STC15系列的多通道ADC检测程序,下面给一个3通道P1.0-P1.2的只取高八位的程序,可以直接使用
void get_ADC()                                //P1.0-P1.2检测
{
        uchar n;
        for(n=0;n<3;n++)
        {
                ADC_CONTR=0x80;
                ADC_CONTR=(ADC_CONTR|0x00+n);  // 设定转换的通道
                ADC_CONTR|=0x08;                   // 开始AD转换,即ADC_START=1
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                while(!(ADC_CONTR & 0x10));   //  等待转换完成 ,即ADC_FLAG=1
                ADC_CONTR&=0xE7;               //  清零 即D3位start清零,D4位转换结束标志位ADC_flag清零
                if(n==2)                                     //  取P1.2
                {
                        zs=ADC_RES;                 //  取高八位送zs               
                }
                if(n==1)                                    //  取P1.1
                {
                        Tp=ADC_RES;              //  取高八位送Tp         
                }               
                if(n==0)                                  //  取P1.0               
               {
                        Td=ADC_RES;                //  取高八位送Td
                }
        }
}                         

void InitADC()             //ADC初始化
{
        P1M0 = 0x00;     //P1.2、P1.1、P1.0高阻模式
        P1M1 = 0x07;
        P1ASF=0x07;             //P1.0\P1.1\P1.2设为输入通道
        ADC_RES=0;             //清除结果
        ADC_CONTR=ADC_POWER|ADC_SPEEDLL;
        delay1ms(2);     //延时
}
回复

使用道具 举报

ID:123289 发表于 2019-10-24 20:53 | 显示全部楼层
太呆板了吧,将你会的程序再写一遍,并将其它的采样端口改一下,相关的参数也改一下就行了。
最后让这两个程序轮流运行。
回复

使用道具 举报

ID:65956 发表于 2019-10-25 08:42 | 显示全部楼层
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
           P1ASF = 0x02;                   //设置P1口为AD口
    ADC_RES = 0;                    //清除结果寄存器
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
        Delay20ms();
}

把这个改成下面这样,这样后你的P1口8个接口都是AD口,然后在下一个函数的ch选择对应的端口0-7任一个作AD口就可以了,切记,现有P1口都作AD口了,所以不能作其它用,如要作其它用重新改这个“P1ASF = 0xFF; //设置P1口为AD口”就可以了
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
           P1ASF = 0xFF;                   //设置P1口为AD口
    ADC_RES = 0;                    //清除结果寄存器
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
        Delay20ms();
}
回复

使用道具 举报

ID:36359 发表于 2020-2-11 21:30 | 显示全部楼层
正在调试类似程序,借鉴一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表