谁有单片机STC12C5A60S2_AD

谁有单片机STC12C5A60S2_AD,第1张

附上以前写过的AD转换的子程序,希望对你有用,数码管显示的程序网上多的是,这里就不附了

/

函数功能: ADC初始化

/

void InitSTCADC(unsigned char channel)

{

P1ASF = 0x01 << channel; //Set P_channel as analog input port

ADC_RES = 0; //Clear previous result

ADC_RESL = 0;

ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag 不能位寻址

ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | channel;

//EADC = 1; //Set ADC interrupt

Delay100us(500); //ADC power-on delay and Start A/D conversion

ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag 不能位寻址

ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | channel;

Delay100us(50); //第一个数据不准,要延时一段时间再测

}

/

函数功能: 读AD的电压值

/

unsigned int ReadADC(unsigned char channel)

{

unsigned int adl = 0;

unsigned int adh = 0;

if((ADC_CONTR & ADC_FLAG) == ADC_FLAG)

{

ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag 不能位寻址

adh = ADC_RES; //Get ADC high 8-bit result

adl = ADC_RESL; //Get ADC low 2-bit result

adh = adh << 2;

adh = adh + adl; //Get ADC all 10-bit result

ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | channel; }

return(adh);}

好吧,先声明我也正在学单片机,回答可能不专业,因为AD问题我只接触过一次。以下结论来着STC12的手册。

1转换的引脚由ADC_CONTG的低3位CHS2、CHS1和CHS0控制,三位二进制能表示0~7八个数,与P1口一一对应。ADC的结构决定了它一次只能转换一个口,但是STC的转换速度达到10万次/秒,依次转换P10和P11与同时转换差别不大。设置P10时,ch=0x00设置P11时,ch=0x01

2是按照一个字节读的,直接读ADC_RES的话只能读到数据的高八位。只用8位ADC转换的话,读ADC_RES就可以了。要想得到10位数据必须加上SendData(ADC_LOW2);

3既然send函数提到了SBUF,那么说明转换结果是通过串口传到电脑上,用STC下载工具的串口调试应该可以看到转换结果。

4连续读取可以用函数循环或定时器循环来调用转换函数。例子嘛,定时器我还不会用而你给的值定时器中断法。所以我说下函数的方法,大概是这样:

void main{

InitADC();//初始化ADC

while(1){//死循环

adc_isr();//转换函数

delay(xx);//延时一段时间,否则转换太快,数据量太大。

}

}

5UART是一种通用串行数据总线,在这里是用于与电脑进行串口通信的。

你的程序中 ADC_COUNTR|=0x08;  之后,没有添加延时。

//给你一个例子

#include "reg51h"

#include "intrinsh"

#define FOSC    11059200L

#define BAUD    9600

typedef unsigned char BYTE;

typedef unsigned int WORD;

sfr ADC_CONTR   =   0xBC;           //ADC control register

sfr ADC_RES     =   0xBD;           //ADC high 8-bit result register

sfr ADC_LOW2    =   0xBE;           //ADC low 2-bit result register

sfr P1ASF       =   0x9D;           //P1 secondary function control register

#define ADC_POWER   0x80            //ADC power control bit

#define ADC_FLAG    0x10            //ADC complete flag

#define ADC_START   0x08            //ADC start control bit

#define ADC_SPEEDLL 0x00            //420 clocks

#define ADC_SPEEDL  0x20            //280 clocks

#define ADC_SPEEDH  0x40            //140 clocks

#define ADC_SPEEDHH 0x60            //70 clocks

void InitUart();

void InitADC();

void SendData(BYTE dat);

BYTE GetADCResult(BYTE ch);

void Delay(WORD n);

void ShowResult(BYTE ch);

void main()

{

    InitUart();                     //Init UART, use to show ADC result

    InitADC();                      //Init ADC sfr

    while (1)

    {

        ShowResult(0);              //Show Channel0

        ShowResult(1);              //Show Channel1

        ShowResult(2);              //Show Channel2

        ShowResult(3);              //Show Channel3

        ShowResult(4);              //Show Channel4

        ShowResult(5);              //Show Channel5

        ShowResult(6);              //Show Channel6

        ShowResult(7);              //Show Channel7

    }

}

void ShowResult(BYTE ch)

{

    SendData(ch);                   //Show Channel NO

    SendData(GetADCResult(ch));     //Show ADC high 8-bit result

}

BYTE GetADCResult(BYTE ch)

{

    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;

    _nop_();                        //Must wait before inquiry  //注意你这里没有添加延时

    _nop_();

    _nop_();

    _nop_();

    while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag

    ADC_CONTR &= ~ADC_FLAG;         //Close ADC

    return ADC_RES;                 //Return ADC result

}

void InitUart()

{

    SCON = 0x5a;                    //8 bit data ,no parity bit

    TMOD = 0x20;                    //T1 as 8-bit auto reload

    TH1 = TL1 = -(FOSC/12/32/BAUD); //Set Uart baudrate

    TR1 = 1;                        //T1 start running

}

void InitADC()

{

    P1ASF = 0xff;                   //Open 8 channels ADC function

    ADC_RES = 0;                    //Clear previous result

    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;

    Delay(2);                       //ADC power-on and delay

}

void SendData(BYTE dat)

{

    while (!TI);                    //Wait for the previous data is sent

    TI = 0;                         //Clear TI flag

    SBUF = dat;                     //Send current data

}

void Delay(WORD n)

{

    WORD x;

    while (n--)

    {

        x = 5000;

        while (x--);

    }

}

能说具体点吗,这个单片机的AD和pwm控制舵机我都用过就是不知道你要什么功能,实在不行我把AD的和控制舵机的程序分别发给你?能说具体点吗,这个单片机的AD和pwm控制舵机我都用过就是不知道你要什么功能,实在不行我把AD的和控制舵机的程序分别发给你?

chs0 chs1 chs2,是三位二进制数,0~7,对应P1口的引脚号P10~P17,如P11作模拟量输入,则 chs2 chs1 chs0 =001,这是在启动转换和读转换结果时要写到ADC_CONTR寄存器的值。

而P1ASF是用8个位对应每个引脚,则P1ASF=0000 0010,即P11作模拟量输入。

想把测到的电压转换之后通过P2口输出,接到LED,是想用8个LED显示吗,这显示的是8位二进制数,而A/D转换的结果是10位二进制数,即是00 0000 0000~11 1111 1111,对应的十进制数是0-1023。所以,最好还是用4位数码管直接显示这十进制数更直观。

做A/D转换时,先初始化P1ASF寄存器。

实现A/D转换要写一个子程序:

unsigned int adc_in(unsigned char n)//n为模拟量输入位通道值,即chs2 chs1 chs0

三位二进制数的值,0~7

{ ADC_CONTR = 0xe8 + n; //启动转换,设置转换速度

while((ADC_CONTR&0x10)==0) ; //等待转换结束

return(ADC_RES4+ADC_RESL); //读转换结果

}

子程序返回无符号的整形数,即转换结果。

再定义转换结果的变量:

unsigned int ADCX;

在主程序中调用:

ADCX=adc_in(n); //这个n 就是chs2 chs1 chs0的值

调用子程序后得到的转换结果就在ADCX中。

以上就是关于谁有单片机STC12C5A60S2_AD全部的内容,包括:谁有单片机STC12C5A60S2_AD、51单片机程序问题 stc12c5a60s2 的a/d转换问题..、stc12c5a60s2单片机AD转换结果总是全零 先初始化 P1ASF=0X80; ADC_COUNTR=0X80; DELAY(等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9359594.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存