附上以前写过的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(等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)