求最简单的A/D转换程序

2020-02-01 16:28发布

本人刚学单片机不久,自学《十天学会单片机和C语言》,现在学到A/D,D/A转换,这方面想了大半天都看不懂例程序,求最简单的A/D转换程序,要加说明
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
40条回答
Tliang
2020-02-03 05:25
李鸿鸿 发表于 2012-12-2 21:42
那么这个程序怎么改呢?

你先看IIC协议,在看芯片数据手册就可以写出来了。
  1. //-----------------------函数声明,变量定义--------------------------------------------------------
  2. #include <reg51.h>
  3. #include <intrins.h>
  4. sbit SDA=P2^1;                          // 将p1.0口模拟数据口
  5. sbit SCL=P2^0;                          // 将p1.1口模拟时钟口
  6. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};                  
  7. bit   bdata SystemError;                // 从机错误标志位
  8. //-----------------------PCF8591专用变量定义--------------------------------------------------------
  9. #define PCF8591_WRITE 0x90
  10. #define PCF8591_READ  0x91
  11. #define  NUM  4                      // 接收和发送缓存区的深度
  12. unsigned char idata receivebuf[NUM];    // 数据接收缓冲区
  13. //--------------------------------------------------------------------------------------------------
  14. // 函数名称: iic_start()
  15. // 函数功能: 启动I2C总线子程序
  16. //--------------------------------------------------------------------------------------------------
  17. void iic_start(void)
  18. {  EA=0;            //时钟保持高,数据线从高到低一次跳变,I2C通信开始
  19. SDA = 1;         
  20. SCL = 1;
  21. delayNOP();      // 延时5us
  22. SDA = 0;
  23. delayNOP();
  24. SCL = 0;
  25. }
  26. //--------------------------------------------------------------------------------------------------
  27. // 函数名称: iic_stop()
  28. // 函数功能: 停止I2C总线数据传送子程序
  29. //--------------------------------------------------------------------------------------------------
  30. void iic_stop(void)
  31. {
  32. SDA = 0;       //时钟保持高,数据线从低到高一次跳变,I2C通信停止
  33. SCL = 1;
  34. delayNOP();
  35. SDA = 1;
  36. delayNOP();
  37. SCL = 0;
  38. }
  39. //--------------------------------------------------------------------------------------------------
  40. // 函数名称: slave_ACK
  41. // 函数功能: 从机发送应答位子程序
  42. //--------------------------------------------------------------------------------------------------
  43. void slave_ACK(void)
  44. {
  45. SDA = 0;   
  46. SCL = 1;
  47. delayNOP();   
  48. SDA = 1;
  49. SCL = 0;
  50. }
  51. //--------------------------------------------------------------------------------------------------
  52. // 函数名称: slave_NOACK
  53. // 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
  54. //--------------------------------------------------------------------------------------------------
  55. void slave_NOACK(void)
  56. {
  57. SDA = 1;   
  58. SCL = 1;
  59. delayNOP();
  60. SDA = 0;
  61. SCL = 0;
  62. }
  63. //--------------------------------------------------------------------------------------------------
  64. // 函数名称: check_ACK
  65. // 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
  66. //--------------------------------------------------------------------------------------------------
  67. void check_ACK(void)
  68. {
  69. SDA = 1;      // 将p1.0设置成输入,必须先向端口写1
  70. SCL = 1;
  71. F0 = 0;
  72. if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志F0
  73.   F0 = 1;
  74. SCL = 0;
  75. }

  76. //--------------------------------------------------------------------------------------------------
  77. // 函数名称: IICSendByte
  78. // 入口参数: ch
  79. // 函数功能: 发送一个字节
  80. //--------------------------------------------------------------------------------------------------
  81. void IICSendByte(unsigned char ch)
  82. {
  83. unsigned char idata n=8;     // 向SDA上发送一位数据字节,共八位
  84. while(n--)
  85. {
  86.   if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
  87.   {
  88.    SDA = 1;    // 传送位1
  89.    SCL = 1;
  90.    delayNOP();
  91.    SDA = 0;
  92.    SCL = 0;   
  93.   }
  94.   else
  95.   {  
  96.    SDA = 0;    // 否则传送位0
  97.    SCL = 1;
  98.    delayNOP();
  99.    SCL = 0;  
  100.   }
  101.   ch = ch<<1;    // 数据左移一位
  102. }
  103. }
  104. //--------------------------------------------------------------------------------------------------
  105. // 函数名称: IICreceiveByte
  106. // 返回接收的数据
  107. // 函数功能: 接收一字节子程序
  108. //--------------------------------------------------------------------------------------------------
  109. unsigned char IICreceiveByte(void)
  110. {
  111. unsigned char idata n=8;    // 从SDA线上读取一上数据字节,共八位
  112. unsigned char tdata;
  113. while(n--)
  114. {
  115.   SDA = 1;
  116.   SCL = 1;
  117.   tdata = tdata<<1;    // 左移一位,或_crol_(temp,1)
  118.   if(SDA == 1)
  119.    tdata = tdata|0x01;    // 若接收到的位为1,则数据的最后一位置1
  120.   else
  121.    tdata = tdata&0xfe;    // 否则数据的最后一位置0
  122.   SCL=0;
  123. }
  124. return(tdata);
  125. }
  126. //--------------------------------------------------------------------------------------------------
  127. // 函数名称: DAC_PCF8591
  128. // 入口参数: slave_add从机地址,n要发送的数据个数
  129. // 函数功能: 发送n位数据子程序
  130. //--------------------------------------------------------------------------------------------------
  131. void DAC_PCF8591(unsigned char controlbyte,unsigned char wdata)
  132. {   
  133. iic_start();                // 启动I2C
  134. IICSendByte(PCF8591_WRITE);     // 发送地址位
  135. check_ACK();                // 检查应答位
  136.     if(F0 == 1)
  137. {
  138.   SystemError = 1;
  139.   return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  140. }
  141.     IICSendByte(controlbyte&0x77); //Control byte
  142. check_ACK();                // 检查应答位
  143.     if(F0 == 1)
  144. {
  145.   SystemError = 1;
  146.   return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  147. }
  148.      IICSendByte(wdata); //data byte
  149. check_ACK();                // 检查应答位
  150.     if(F0 == 1)
  151. {
  152.   SystemError = 1;
  153.   return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  154. }
  155. iic_stop();         // 全部发完则停止
  156. delayNOP();
  157. delayNOP();
  158. delayNOP();
  159. delayNOP();
  160. }
  161. //--------------------------------------------------------------------------------------------------
  162. // 函数名称: ADC_PCF8591
  163. // 入口参数: controlbyte控制字
  164. // 函数功能: 连续读入4路通道的A/D转换结果到receivebuf
  165. //--------------------------------------------------------------------------------------------------
  166. void ADC_PCF8591(unsigned char controlbyte)
  167. {
  168.     unsigned char idata receive_da,i=0;
  169. iic_start();
  170. IICSendByte(PCF8591_WRITE); //控制字
  171. check_ACK();
  172. if(F0 == 1)
  173. {
  174.   SystemError = 1;
  175.   return;
  176. }
  177. IICSendByte(controlbyte); //控制字
  178. check_ACK();
  179. if(F0 == 1)
  180. {
  181.   SystemError = 1;
  182.   return;
  183. }
  184.     iic_start();     //重新发送开始命令
  185.     IICSendByte(PCF8591_READ); //控制字
  186. check_ACK();
  187. if(F0 == 1)
  188. {
  189.   SystemError = 1;
  190.   return;
  191. }
  192. while(i<4)
  193. {
  194.   receive_da=IICreceiveByte();
  195.   receivebuf[i++]=receive_da;
  196.   slave_ACK();    // 收到一个字节后发送一个应答位
  197. }
  198. slave_NOACK();    // 收到最后一个字节后发送一个非应答位
  199. iic_stop();
  200. }
  201. //--------------------------------------------------------------------------------------------------
  202. // 函数名称: main
  203. // 函数功能: 主程序
  204. //--------------------------------------------------------------------------------------------------
  205. void main(void)
  206. {
  207. DAC_PCF8591(0x40,0); //控制字为0100 0000,允许模拟量输出
  208. while(1);                     //零值点输出测试
  209. DAC_PCF8591(0x40,0xff); //控制字为0100 0000,允许模拟量输出
  210.                      //满值点输入测试
  211. ADC_PCF8591(0x40);
  212. }











复制代码从网上下的。能不能用我不知道。一百度就出来了

一周热门 更多>