当前位置:   article > 正文

【51单片机入门记录】A/D、D/A转换器PCF859应用

【51单片机入门记录】A/D、D/A转换器PCF859应用

目录

一、IIC初始化代码

二、开发板电路图

三、PCF8591读/写字节操作流程及相关函数

(1)PCF8591(AD)读操作流程及代码

(2)PCF8591(AD)写操作流程及代码

四、应用示例-显示电压值


一、IIC初始化代码

  1. 加载“iic.c文件”,主函数中添加iic.h头文件
  2. 调节软件延迟时长(全部扩大十倍即可)
  3. 编写PCF8591读写函数,并且在头文件中定义
  4. 编写用户用能函数

二、开发板电路图

(图源第十五届蓝桥杯电子赛资源包)

  • 根据图以及前面所学的EEPROM存储器的位置,可知IIC总线上有两个设备,一个是PCF85191另一个是AT24C02 EEPROM存储器。
  • AIN1(光敏电阻线路)、AIN3(活动变阻器、电压采集)

三、PCF8591读/写字节操作流程及相关函数

(1)PCF8591(AD)读操作流程及代码

  1. 主控器发出起始信号
  2. 主控器发出寻址字节(写:0X90)
  3. 被控器做出应答后
  4. 主控器发出控制字节(写:)
  5. 被控器做出应答后
  6. 主控器发出停止信号
  7. 主控器发出起始信号
  8. 主控器发出寻址字节(读:0x91)
  9. 被控器做出应答后
  10. 主控器从被控器读出数据字节,主控器发出应答
  11. 主控器发出停止信号
  1. unsigned char AD_read(unsigned char add)
  2. {
  3. unsigned char dat;
  4. I2CStart();
  5. I2CSendByte(0X90);
  6. I2CWaitAck();
  7. I2CSendByte(add);
  8. I2CWaitAck();
  9. I2CStop();
  10. I2CStart();
  11. I2CSendByte(0X91);
  12. I2CWaitAck();
  13. dat=I2CReceiveByte();
  14. I2CSendAck(1);
  15. I2CStop();
  16. return dat;
  17. }

(2)PCF8591(AD)写操作流程及代码

  1. 主控器发出起始信号
  2. 主控器发出寻址字节(写:0X90)
  3. 被控器做出应答后
  4. 主控器发出控制字节(写)
  5. 被控器做出应答后
  6. 主控器发出DA输出数据字节(写)
  7. 被控器做出应答后
  8. 主控器发出停止信号
  1. void AD_write(unsigned char dat)
  2. {
  3. I2CStart();
  4. I2CSendByte(0X90);
  5. I2CWaitAck();
  6. I2CSendByte(0X40);
  7. I2CWaitAck();
  8. I2CSendByte(dat);
  9. I2CWaitAck();
  10. I2CStop();
  11. }

四、应用示例-显示电压值

  1. //iic.c
  2. #include <STC15F2K60S2.H>
  3. #include<intrins.h>
  4. #define DELAY_TIME 50
  5. //总线引脚定义
  6. sbit sda = P2^1;
  7. sbit scl = P2^0;
  8. //
  9. static void I2C_Delay(unsigned char n)
  10. {
  11. do
  12. {
  13. _nop_();_nop_();_nop_();_nop_();_nop_();
  14. _nop_();_nop_();_nop_();_nop_();_nop_();
  15. _nop_();_nop_();_nop_();_nop_();_nop_();
  16. }
  17. while(n--);
  18. }
  19. //
  20. void I2CStart(void)
  21. {
  22. sda = 1;
  23. scl = 1;
  24. I2C_Delay(DELAY_TIME);
  25. sda = 0;
  26. I2C_Delay(DELAY_TIME);
  27. scl = 0;
  28. }
  29. //
  30. void I2CStop(void)
  31. {
  32. sda = 0;
  33. scl = 1;
  34. I2C_Delay(DELAY_TIME);
  35. sda = 1;
  36. I2C_Delay(DELAY_TIME);
  37. }
  38. //
  39. void I2CSendByte(unsigned char byt)
  40. {
  41. unsigned char i;
  42. for(i=0; i<8; i++){
  43. scl = 0;
  44. I2C_Delay(DELAY_TIME);
  45. if(byt & 0x80){
  46. sda = 1;
  47. }
  48. else{
  49. sda = 0;
  50. }
  51. I2C_Delay(DELAY_TIME);
  52. scl = 1;
  53. byt <<= 1;
  54. I2C_Delay(DELAY_TIME);
  55. }
  56. scl = 0;
  57. }
  58. //
  59. unsigned char I2CReceiveByte(void)
  60. {
  61. unsigned char da;
  62. unsigned char i;
  63. for(i=0;i<8;i++){
  64. scl = 1;
  65. I2C_Delay(DELAY_TIME);
  66. da <<= 1;
  67. if(sda)
  68. da |= 0x01;
  69. scl = 0;
  70. I2C_Delay(DELAY_TIME);
  71. }
  72. return da;
  73. }
  74. //
  75. unsigned char I2CWaitAck(void)
  76. {
  77. unsigned char ackbit;
  78. scl = 1;
  79. I2C_Delay(DELAY_TIME);
  80. ackbit = sda;
  81. scl = 0;
  82. I2C_Delay(DELAY_TIME);
  83. return ackbit;
  84. }
  85. //
  86. void I2CSendAck(unsigned char ackbit)
  87. {
  88. scl = 0;
  89. sda = ackbit;
  90. I2C_Delay(DELAY_TIME);
  91. scl = 1;
  92. I2C_Delay(DELAY_TIME);
  93. scl = 0;
  94. sda = 1;
  95. I2C_Delay(DELAY_TIME);
  96. }
  97. unsigned char AD_read(unsigned char add)
  98. {
  99. unsigned char dat;
  100. I2CStart();
  101. I2CSendByte(0X90);
  102. I2CWaitAck();
  103. I2CSendByte(add);
  104. I2CWaitAck();
  105. I2CStop();
  106. I2CStart();
  107. I2CSendByte(0X91);
  108. I2CWaitAck();
  109. dat=I2CReceiveByte();
  110. I2CSendAck(1);
  111. I2CStop();
  112. return dat;
  113. }
  114. void AD_write(unsigned char dat)
  115. {
  116. I2CStart();
  117. I2CSendByte(0X90);
  118. I2CWaitAck();
  119. I2CSendByte(0X40);
  120. I2CWaitAck();
  121. I2CSendByte(dat);
  122. I2CWaitAck();
  123. I2CStop();
  124. }
  1. //IIC.h
  2. #ifndef _IIC_H
  3. #define _IIC_H
  4. //
  5. static void I2C_Delay(unsigned char n);
  6. //
  7. void I2CStart(void);
  8. //
  9. void I2CStop(void);
  10. //
  11. void I2CSendByte(unsigned char byt);
  12. //
  13. unsigned char I2CReceiveByte(void);
  14. //
  15. unsigned char I2CWaitAck(void);
  16. //
  17. void I2CSendAck(unsigned char ackbit);
  18. //
  19. unsigned char AD_read(unsigned char add);
  20. void AD_write(unsigned char dat);
  21. #endif
  1. //main.c
  2. #include <STC15F2K60S2.H>
  3. #include<intrins.h>
  4. #include<IIC.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. unsigned char LED_Bit=0XFF;
  8. unsigned char Actuator_Bit=0X00;
  9. #define LEDx_ON(n) { LED_Bit&=_crol_(0XFE,n-1); P0=LED_Bit; P2|=0X80; P2&=0X9F; P2&=0X1F;}
  10. #define LEDx_OFF(n) { LED_Bit|=_crol_(0X01,n-1); P0=LED_Bit; P2|=0X80; P2&=0X9F; P2&=0X1F;}
  11. #define Buzzer_ON Actuator_Bit|=0x40; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
  12. #define Buzzer_OFF Actuator_Bit&=0XBF; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
  13. #define Relay_ON Actuator_Bit|=0x10; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
  14. #define Relay_OFF Actuator_Bit&=0XEF; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
  15. unsigned char code tab[]= {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,\
  16. 0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,\
  17. 0XBF,0XFF};
  18. unsigned char KEY_Value = 0 ;
  19. unsigned char DigCom=0;
  20. unsigned char DigBuf[8] = {10,10,10,10,10,10,10,10};
  21. unsigned char LED = 1 ;
  22. unsigned int LED_tt =0;
  23. bit LED_Ref = 0 ;
  24. unsigned int SEG_tt =0; //定义一个数码管计数时间标识位
  25. bit SEG_Ref = 0 ; //定义一个数码管刷新标识位
  26. bit SEG_Run = 0 ; //定义一个控制数码管运行标识位
  27. unsigned int Num = 999 ;
  28. unsigned char Open;
  29. unsigned char EEPROM_Write[8] = {2,3,4,5,6,7,8,9};
  30. unsigned char EEPROM_Read[8] = {0,0,0,0,0,0,0,0};
  31. unsigned int AD_VALUE=0;
  32. unsigned int AD_tt =0;
  33. bit AD_Ref =0;
  34. void ALL_Init(void);
  35. void Delay_MS(unsigned int MS);
  36. void KeyScan(void);
  37. void ArrKeyScan(void);
  38. void Timer0Init(void); //1毫秒@11.0592MHz
  39. void main(void)
  40. {
  41. ALL_Init();
  42. Timer0Init();
  43. EA=1;ET0=1;
  44. while(1)
  45. {
  46. if(AD_Ref == 1)
  47. {
  48. AD_Ref = 0 ;
  49. AD_VALUE = AD_read(0X03);
  50. AD_write(AD_VALUE);
  51. AD_VALUE = AD_VALUE * 1.96;
  52. DigBuf[2]=21;DigBuf[3]=21;DigBuf[4]=21;
  53. DigBuf[5]=AD_VALUE/100 + 10; DigBuf[6]=AD_VALUE%100/10;
  54. DigBuf[7]=AD_VALUE%10;
  55. }
  56. KeyScan();
  57. if(KEY_Value==7){KEY_Value=0;SEG_Run = 1 ;}
  58. if(KEY_Value==6){KEY_Value=0;SEG_Run = 0 ;}
  59. if(KEY_Value==5){KEY_Value=0;LEDx_ON(1);Buzzer_ON;}
  60. if(KEY_Value==4){KEY_Value=0;LEDx_OFF(1);Buzzer_OFF;}
  61. }
  62. }
  63. void KeyScan(void)
  64. {
  65. if(P30==0)
  66. {
  67. Delay_MS(10);
  68. if(P30==0)KEY_Value = 7 ;
  69. while(!P30);
  70. }
  71. else if(P31==0)
  72. {
  73. Delay_MS(10);
  74. if(P31==0)KEY_Value = 6 ;
  75. while(!P31);
  76. }
  77. else if(P32==0)
  78. {
  79. Delay_MS(10);
  80. if(P32==0)KEY_Value = 5 ;
  81. while(!P32);
  82. }
  83. else if(P33==0)
  84. {
  85. Delay_MS(10);
  86. if(P33==0)KEY_Value = 4 ;
  87. while(!P33);
  88. }
  89. }
  90. void Timer0(void) interrupt 1
  91. {
  92. P0=0X00;
  93. P2|=0XC0; // P2=P2|0XC0; XXXX XXXX | 1100 0000 = 11XX XXXX
  94. P2&=0XDF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX
  95. P2&=0X1F; //关闭所有的74HC573锁存器
  96. P0=tab[DigBuf[DigCom]];
  97. P2|=0XE0; // P2=P2|0XE0; XXXX XXXX | 1110 0000 = 111X XXXX
  98. P2&=0XFF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX
  99. P2&=0X1F; //关闭所有的74HC573锁存器
  100. P0=(0X01<<DigCom); //然后选中第一个数码管
  101. P2|=0XC0; // P2=P2|0XC0; XXXX XXXX | 1100 0000 = 11XX XXXX
  102. P2&=0XDF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX
  103. P2&=0X1F; //关闭所有的74HC573锁存器
  104. if(++DigCom == 8)DigCom = 0 ;
  105. LED_tt++;
  106. if(LED_tt == 999) {LED_tt = 0 ; LED_Ref = 1 ;}
  107. if(++SEG_tt==1000){SEG_tt=0;SEG_Ref=1;}
  108. if(++AD_tt==500){AD_tt=0;AD_Ref=1;}
  109. // XXX_tt++;
  110. // if(++XXX_tt==NNN){XXX_tt=0;XXX_Ref=1;}
  111. }
  112. void Timer0Init(void) //1毫秒@11.0592MHz
  113. {
  114. AUXR |= 0x80; //定时器时钟1T模式
  115. TMOD &= 0xF0; //设置定时器模式
  116. TL0 = 0xCD; //设置定时初始值
  117. TH0 = 0xD4; //设置定时初始值
  118. TF0 = 0; //清除TF0标志
  119. TR0 = 1; //定时器0开始计时
  120. }
  121. void Delay_MS(unsigned int MS)
  122. {
  123. unsigned i,j;
  124. for(i=0;i<MS;i++)
  125. for(j=853;j>0;j--); //STC15单片机设置为853; STC8H单片机修改为1109;STC32G单片机修改为427;
  126. }
  127. void ALL_Init(void)
  128. {
  129. P0 =0X00; //先设置关闭蜂鸣器继电器的P0输出值(全关)
  130. P2|=0XA0; // 将P27 P25 设置为1 其他位保持不变
  131. P2&=0XBF; // 将P26设置为0 其他位保持不变
  132. P2&=0X1F; //关闭所有的74HC573锁存器
  133. P0 =0XFF; //先设置关闭所有的LED的P0输出值(全关)
  134. P2|=0X80; // 将P27设置为1 其他位保持不变
  135. P2&=0X9F; // 将P26 P25设置为0 其他位保持不变
  136. P2&=0X1F; //关闭所有的74HC573锁存器
  137. P0 =0X00; //先设置选择数码管位选的P0输出值(全不选)
  138. P2|=0XC0; // 将P27 P26 设置为1 其他位保持不变
  139. P2&=0XDF; // 将P26设置为0 其他位保持不变
  140. P2&=0X1F; //关闭所有的74HC573锁存器
  141. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/415180
推荐阅读
相关标签
  

闽ICP备14008679号