专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
51单片机
求最简单的A/D转换程序
2020-02-01 16:28
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
51单片机
5844
40
40
本人刚学单片机不久,自学《十天学会单片机和C语言》,现在学到A/D,D/A转换,这方面想了大半天都看不懂例程序,求最简单的A/D转换程序,要加说明
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
40条回答
Tliang
2020-02-03 05:25
李鸿鸿 发表于 2012-12-2 21:42
那么这个程序怎么改呢?
你先看IIC协议,在看芯片数据手册就可以写出来了。
//-----------------------函数声明,变量定义--------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
sbit SDA=P2^1; // 将p1.0口模拟数据口
sbit SCL=P2^0; // 将p1.1口模拟时钟口
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
bit bdata SystemError; // 从机错误标志位
//-----------------------PCF8591专用变量定义--------------------------------------------------------
#define PCF8591_WRITE 0x90
#define PCF8591_READ 0x91
#define NUM 4 // 接收和发送缓存区的深度
unsigned char idata receivebuf[NUM]; // 数据接收缓冲区
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_start()
// 函数功能: 启动I2C总线子程序
//--------------------------------------------------------------------------------------------------
void iic_start(void)
{ EA=0; //时钟保持高,数据线从高到低一次跳变,I2C通信开始
SDA = 1;
SCL = 1;
delayNOP(); // 延时5us
SDA = 0;
delayNOP();
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_stop()
// 函数功能: 停止I2C总线数据传送子程序
//--------------------------------------------------------------------------------------------------
void iic_stop(void)
{
SDA = 0; //时钟保持高,数据线从低到高一次跳变,I2C通信停止
SCL = 1;
delayNOP();
SDA = 1;
delayNOP();
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_ACK
// 函数功能: 从机发送应答位子程序
//--------------------------------------------------------------------------------------------------
void slave_ACK(void)
{
SDA = 0;
SCL = 1;
delayNOP();
SDA = 1;
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_NOACK
// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void slave_NOACK(void)
{
SDA = 1;
SCL = 1;
delayNOP();
SDA = 0;
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: check_ACK
// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void check_ACK(void)
{
SDA = 1; // 将p1.0设置成输入,必须先向端口写1
SCL = 1;
F0 = 0;
if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志F0
F0 = 1;
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: IICSendByte
// 入口参数: ch
// 函数功能: 发送一个字节
//--------------------------------------------------------------------------------------------------
void IICSendByte(unsigned char ch)
{
unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位
while(n--)
{
if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
{
SDA = 1; // 传送位1
SCL = 1;
delayNOP();
SDA = 0;
SCL = 0;
}
else
{
SDA = 0; // 否则传送位0
SCL = 1;
delayNOP();
SCL = 0;
}
ch = ch<<1; // 数据左移一位
}
}
//--------------------------------------------------------------------------------------------------
// 函数名称: IICreceiveByte
// 返回接收的数据
// 函数功能: 接收一字节子程序
//--------------------------------------------------------------------------------------------------
unsigned char IICreceiveByte(void)
{
unsigned char idata n=8; // 从SDA线上读取一上数据字节,共八位
unsigned char tdata;
while(n--)
{
SDA = 1;
SCL = 1;
tdata = tdata<<1; // 左移一位,或_crol_(temp,1)
if(SDA == 1)
tdata = tdata|0x01; // 若接收到的位为1,则数据的最后一位置1
else
tdata = tdata&0xfe; // 否则数据的最后一位置0
SCL=0;
}
return(tdata);
}
//--------------------------------------------------------------------------------------------------
// 函数名称: DAC_PCF8591
// 入口参数: slave_add从机地址,n要发送的数据个数
// 函数功能: 发送n位数据子程序
//--------------------------------------------------------------------------------------------------
void DAC_PCF8591(unsigned char controlbyte,unsigned char wdata)
{
iic_start(); // 启动I2C
IICSendByte(PCF8591_WRITE); // 发送地址位
check_ACK(); // 检查应答位
if(F0 == 1)
{
SystemError = 1;
return; // 若非应答表明器件错误或已坏,置错误标志位SystemError
}
IICSendByte(controlbyte&0x77); //Control byte
check_ACK(); // 检查应答位
if(F0 == 1)
{
SystemError = 1;
return; // 若非应答表明器件错误或已坏,置错误标志位SystemError
}
IICSendByte(wdata); //data byte
check_ACK(); // 检查应答位
if(F0 == 1)
{
SystemError = 1;
return; // 若非应答表明器件错误或已坏,置错误标志位SystemError
}
iic_stop(); // 全部发完则停止
delayNOP();
delayNOP();
delayNOP();
delayNOP();
}
//--------------------------------------------------------------------------------------------------
// 函数名称: ADC_PCF8591
// 入口参数: controlbyte控制字
// 函数功能: 连续读入4路通道的A/D转换结果到receivebuf
//--------------------------------------------------------------------------------------------------
void ADC_PCF8591(unsigned char controlbyte)
{
unsigned char idata receive_da,i=0;
iic_start();
IICSendByte(PCF8591_WRITE); //控制字
check_ACK();
if(F0 == 1)
{
SystemError = 1;
return;
}
IICSendByte(controlbyte); //控制字
check_ACK();
if(F0 == 1)
{
SystemError = 1;
return;
}
iic_start(); //重新发送开始命令
IICSendByte(PCF8591_READ); //控制字
check_ACK();
if(F0 == 1)
{
SystemError = 1;
return;
}
while(i<4)
{
receive_da=IICreceiveByte();
receivebuf[i++]=receive_da;
slave_ACK(); // 收到一个字节后发送一个应答位
}
slave_NOACK(); // 收到最后一个字节后发送一个非应答位
iic_stop();
}
//--------------------------------------------------------------------------------------------------
// 函数名称: main
// 函数功能: 主程序
//--------------------------------------------------------------------------------------------------
void main(void)
{
DAC_PCF8591(0x40,0); //控制字为0100 0000,允许模拟量输出
while(1); //零值点输出测试
DAC_PCF8591(0x40,0xff); //控制字为0100 0000,允许模拟量输出
//满值点输入测试
ADC_PCF8591(0x40);
}
复制代码
从网上下的。能不能用我不知道。一百度就出来了
加载中...
查看其它40个回答
一周热门
更多
>
相关问题
【东软载波ESF0654 PDS开发板活动】开箱
1 个回答
东软载波ESF0654 PDS开发板外部中断
1 个回答
东软载波ESF0654 PDS开发板高级控制定时器AD16C4T
1 个回答
用串口调试助手为什么只能在hex模式接收发送而在文本模式不行
9 个回答
触摸芯片SC02B/SC04B在地砖灯的设计方案
1 个回答
相关文章
51单片机与蓝牙模块连接
0个评论
51单片机的硬件结构
0个评论
基于51单片机的无线遥控器制作
0个评论
51单片机 AD转换
0个评论
51单片机数码管递增显示
0个评论
如何实现对单片机寄存器的访问
0个评论
基于51单片机的指纹密码锁
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
51单片机
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
你先看IIC协议,在看芯片数据手册就可以写出来了。
- //-----------------------函数声明,变量定义--------------------------------------------------------
- #include <reg51.h>
- #include <intrins.h>
- sbit SDA=P2^1; // 将p1.0口模拟数据口
- sbit SCL=P2^0; // 将p1.1口模拟时钟口
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
- bit bdata SystemError; // 从机错误标志位
- //-----------------------PCF8591专用变量定义--------------------------------------------------------
- #define PCF8591_WRITE 0x90
- #define PCF8591_READ 0x91
- #define NUM 4 // 接收和发送缓存区的深度
- unsigned char idata receivebuf[NUM]; // 数据接收缓冲区
- //--------------------------------------------------------------------------------------------------
- // 函数名称: iic_start()
- // 函数功能: 启动I2C总线子程序
- //--------------------------------------------------------------------------------------------------
- void iic_start(void)
- { EA=0; //时钟保持高,数据线从高到低一次跳变,I2C通信开始
- SDA = 1;
- SCL = 1;
- delayNOP(); // 延时5us
- SDA = 0;
- delayNOP();
- SCL = 0;
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: iic_stop()
- // 函数功能: 停止I2C总线数据传送子程序
- //--------------------------------------------------------------------------------------------------
- void iic_stop(void)
- {
- SDA = 0; //时钟保持高,数据线从低到高一次跳变,I2C通信停止
- SCL = 1;
- delayNOP();
- SDA = 1;
- delayNOP();
- SCL = 0;
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: slave_ACK
- // 函数功能: 从机发送应答位子程序
- //--------------------------------------------------------------------------------------------------
- void slave_ACK(void)
- {
- SDA = 0;
- SCL = 1;
- delayNOP();
- SDA = 1;
- SCL = 0;
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: slave_NOACK
- // 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
- //--------------------------------------------------------------------------------------------------
- void slave_NOACK(void)
- {
- SDA = 1;
- SCL = 1;
- delayNOP();
- SDA = 0;
- SCL = 0;
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: check_ACK
- // 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
- //--------------------------------------------------------------------------------------------------
- void check_ACK(void)
- {
- SDA = 1; // 将p1.0设置成输入,必须先向端口写1
- SCL = 1;
- F0 = 0;
- if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志F0
- F0 = 1;
- SCL = 0;
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: IICSendByte
- // 入口参数: ch
- // 函数功能: 发送一个字节
- //--------------------------------------------------------------------------------------------------
- void IICSendByte(unsigned char ch)
- {
- unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位
- while(n--)
- {
- if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
- {
- SDA = 1; // 传送位1
- SCL = 1;
- delayNOP();
- SDA = 0;
- SCL = 0;
- }
- else
- {
- SDA = 0; // 否则传送位0
- SCL = 1;
- delayNOP();
- SCL = 0;
- }
- ch = ch<<1; // 数据左移一位
- }
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: IICreceiveByte
- // 返回接收的数据
- // 函数功能: 接收一字节子程序
- //--------------------------------------------------------------------------------------------------
- unsigned char IICreceiveByte(void)
- {
- unsigned char idata n=8; // 从SDA线上读取一上数据字节,共八位
- unsigned char tdata;
- while(n--)
- {
- SDA = 1;
- SCL = 1;
- tdata = tdata<<1; // 左移一位,或_crol_(temp,1)
- if(SDA == 1)
- tdata = tdata|0x01; // 若接收到的位为1,则数据的最后一位置1
- else
- tdata = tdata&0xfe; // 否则数据的最后一位置0
- SCL=0;
- }
- return(tdata);
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: DAC_PCF8591
- // 入口参数: slave_add从机地址,n要发送的数据个数
- // 函数功能: 发送n位数据子程序
- //--------------------------------------------------------------------------------------------------
- void DAC_PCF8591(unsigned char controlbyte,unsigned char wdata)
- {
- iic_start(); // 启动I2C
- IICSendByte(PCF8591_WRITE); // 发送地址位
- check_ACK(); // 检查应答位
- if(F0 == 1)
- {
- SystemError = 1;
- return; // 若非应答表明器件错误或已坏,置错误标志位SystemError
- }
- IICSendByte(controlbyte&0x77); //Control byte
- check_ACK(); // 检查应答位
- if(F0 == 1)
- {
- SystemError = 1;
- return; // 若非应答表明器件错误或已坏,置错误标志位SystemError
- }
- IICSendByte(wdata); //data byte
- check_ACK(); // 检查应答位
- if(F0 == 1)
- {
- SystemError = 1;
- return; // 若非应答表明器件错误或已坏,置错误标志位SystemError
- }
- iic_stop(); // 全部发完则停止
- delayNOP();
- delayNOP();
- delayNOP();
- delayNOP();
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: ADC_PCF8591
- // 入口参数: controlbyte控制字
- // 函数功能: 连续读入4路通道的A/D转换结果到receivebuf
- //--------------------------------------------------------------------------------------------------
- void ADC_PCF8591(unsigned char controlbyte)
- {
- unsigned char idata receive_da,i=0;
- iic_start();
- IICSendByte(PCF8591_WRITE); //控制字
- check_ACK();
- if(F0 == 1)
- {
- SystemError = 1;
- return;
- }
- IICSendByte(controlbyte); //控制字
- check_ACK();
- if(F0 == 1)
- {
- SystemError = 1;
- return;
- }
- iic_start(); //重新发送开始命令
- IICSendByte(PCF8591_READ); //控制字
- check_ACK();
- if(F0 == 1)
- {
- SystemError = 1;
- return;
- }
- while(i<4)
- {
- receive_da=IICreceiveByte();
- receivebuf[i++]=receive_da;
- slave_ACK(); // 收到一个字节后发送一个应答位
- }
- slave_NOACK(); // 收到最后一个字节后发送一个非应答位
- iic_stop();
- }
- //--------------------------------------------------------------------------------------------------
- // 函数名称: main
- // 函数功能: 主程序
- //--------------------------------------------------------------------------------------------------
- void main(void)
- {
- DAC_PCF8591(0x40,0); //控制字为0100 0000,允许模拟量输出
- while(1); //零值点输出测试
- DAC_PCF8591(0x40,0xff); //控制字为0100 0000,允许模拟量输出
- //满值点输入测试
- ADC_PCF8591(0x40);
- }
-
-
复制代码从网上下的。能不能用我不知道。一百度就出来了一周热门 更多>