求51单片机AD程序

现有一块STC15W404AS,VCC是3.3V.该单片机自带AD功能,我想用P1^4口作为模拟电压输入,然后根据P1^4口电压大小输出一个从0~50之间变化的数值.我初... 现有一块STC15W404AS , VCC是3.3V. 该单片机自带AD功能, 我想用P1^4口作为模拟电压输入, 然后根据P1^4口电压大小输出一个从0~50之间变化的数值. 我初学单片机, 基本上全是通过网络学得的知识, 求各位前辈施舍文笔给个完整简单的C程序救救我这个可怜的孩纸吧~ 展开
 我来答
百度网友5ea888d
推荐于2017-12-16 · TA获得超过979个赞
知道小有建树答主
回答量:922
采纳率:50%
帮助的人:684万
展开全部
如下程序是在 STC 官方网站 提供的。应该很有用。
////
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz
#include "reg51.h"
#include "intrins.h"
#define FOSC 18432000L
#define BAUD 9600
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define URMD 0 //0:使用定时器2作为波特率发生器
//1:使用定时器1的模式0(16位自动重载模式)作为波特率发生器
//2:使用定时器1的模式2(8位自动重载模式)作为波特率发生器
sfr T2H = 0xd6; //定时器2高8位
sfr T2L = 0xd7; //定时器2低8位
sfr AUXR = 0x8e; //辅助寄存器
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC高8位结果
sfr ADC_LOW2 = 0xBE; //ADC低2位结果
sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
#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个时钟
void InitUart();
void InitADC();
void SendData(BYTE dat);
BYTE GetADCResult(BYTE ch);
void Delay(WORD n);
void ShowResult(BYTE ch);
void main()
{
InitUart(); //初始化串口
InitADC(); //初始化ADC
while (1)
{
ShowResult(0); //显示通道0
ShowResult(1); //显示通道1
ShowResult(2); //显示通道2
ShowResult(3); //显示通道3
ShowResult(4); //显示通道4
ShowResult(5); //显示通道5
ShowResult(6); //显示通道6
ShowResult(7); //显示通道7
}
}
/*----------------------------
发送ADC结果到PC
----------------------------*/
void ShowResult(BYTE ch)
{
SendData(ch); //显示通道号
SendData(GetADCResult(ch)); //显示ADC高8位结果
// SendData(ADC_LOW2); //显示低2位结果
}
/*----------------------------
读取ADC结果
----------------------------*/
BYTE GetADCResult(BYTE ch)
{
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; //Close ADC
return ADC_RES; //返回ADC结果
}
/*----------------------------
初始化串口
----------------------------*/
void InitUart()
{
SCON = 0x5a; //设置串口为8位可变波特率
#if URMD == 0
T2L = 0xd8; //设置波特率重装值
T2H = 0xff; //115200 bps(65536-18432000/4/115200)
AUXR = 0x14; //T2为1T模式, 并启动定时器2
AUXR |= 0x01; //选择定时器2为串口1的波特率发生器
#elif URMD == 1
AUXR = 0x40; //定时器1为1T模式
TMOD = 0x00; //定时器1为模式0(16位自动重载)
TL1 = 0xd8; //设置波特率重装值
TH1 = 0xff; //115200 bps(65536-18432000/4/115200)
TR1 = 1; //定时器1开始启动
#else
TMOD = 0x20; //设置定时器1为8位自动重装载模式
AUXR = 0x40; //定时器1为1T模式
TH1 = TL1 = 0xfb; //115200 bps(256 - 18432000/32/115200)
TR1 = 1;
#endif
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
P1ASF = 0xff; //设置P1口为AD口
ADC_RES = 0; //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
Delay(2); //ADC上电并延时
}
/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
while (!TI); //等待前一个数据发送完成
TI = 0; //清除发送标志
SBUF = dat; //发送当前数据
}
/*----------------------------
软件延时
----------------------------*/
void Delay(WORD n)
{
WORD x;
while (n--)
{
x = 5000;
while (x--);
}
}
追问
能给个实际应用的例子吗?我只需操作一两个IO口就行了, 要求精度并不高. 我只想要了解基本操作方法,感觉这个比外挂AD芯片的操作复杂得多!
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式