AD/DA的转换

本文介绍了一种使用51单片机进行IIC接口编程的方法,包括IIC总线的基本操作如启动、停止、发送和接收数据等,并实现通过IIC接口与AT24C02 EEPROM进行数据读写。此外还展示了如何初始化LCD1602显示器并显示数据,以及如何读取AD转换结果。
[objc]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <reg52.h>  
  2. #include "./delay/delay.h"  
  3.   
  4.   
  5. #define LCD_WRITE_DATA 1  
  6. #define LCD_WRITE_COM 0  
  7. #define LCDPORT P0  
  8. #define SUCC 0  
  9. #define ERR 1  
  10.   
  11.   
  12. sbit RS = P2^4;  
  13. sbit RW = P2^5;  
  14. sbit E = P2^6;  
  15.   
  16.   
  17. sbit SCL = P1^0;  
  18. sbit SDA = P1^1;  
  19. bit ack = 0;  
  20.   
  21.   
  22. void iic_start()  
  23. {  
  24.         SDA = 1;  
  25.         SCL = 1;  
  26.         delay_us(1);  
  27.         SDA = 0;  
  28.         delay_us(1);  
  29.         SCL = 0;  
  30. }  
  31.   
  32.   
  33. void iic_stop()  
  34. {  
  35.         SDA = 0;  
  36.         SCL = 1;  
  37.         delay_us(1);  
  38.         SDA = 1;  
  39.         delay_us(1);  
  40.         SCL = 0;  
  41.   
  42.   
  43. }  
  44.   
  45.   
  46. bit iic_send_byte(unsigned char byte)  
  47. {  
  48.         unsigned char i;  
  49.         SDA = 1;  
  50.         for(i = 0;i < 8;i++)  
  51.         {  
  52.                 SDA = byte & 0x80;  
  53.                 SCL = 1;  
  54.                 delay_us(1);  
  55.                 SCL = 0;  
  56.                 byte <<= 1;  
  57.         }  
  58.         SCL = 1;  
  59.         SDA = 1;  
  60.         delay_us(1);  
  61.         if(0 == SDA)  
  62.         {  
  63.                 ack = 1;  
  64.         }  
  65.         else  
  66.         {  
  67.                 ack = 0;  
  68.         }  
  69.         SCL = 0;  
  70.         return ack;  
  71. }  
  72.   
  73.   
  74. void iic_noack()  
  75. {  
  76.         SDA = 1;  
  77.         SCL = 1;  
  78.         delay_us(1);  
  79.         SCL = 0;  
  80. }  
  81.   
  82.   
  83. void iic_ack()  
  84. {  
  85.         SDA = 0;  
  86.         SCL = 1;  
  87.         delay_us(1);  
  88.         SCL = 0;  
  89. }  
  90.   
  91.   
  92. unsigned char iic_rcv_byte()  
  93. {  
  94.         unsigned char i;  
  95.         unsigned char temp = 0;  
  96.         unsigned char a;  
  97.         SDA = 1;  
  98.         for(i = 0;i < 8;i++)  
  99.         {  
  100.                 SCL = 0;  
  101.                 delay_us(1);  
  102.                 SCL = 1;  
  103.                 if(SDA == 1)  
  104.                 {  
  105.                         a = 0x01;  
  106.                 }  
  107.                 else  
  108.                 {  
  109.                         a = 0x0;  
  110.                 }  
  111.                 temp |= (a<<(7-i));  
  112.                 delay_us(1);  
  113.         }     
  114.         SCL = 0;  
  115.         return temp;  
  116. }  
  117.   
  118.   
  119. unsigned char AT24C02_send_str(unsigned char devaddr,unsigned char romaddr,unsigned charchar *s,unsigned char num)  
  120. {  
  121.         unsigned char i;  
  122.         iic_start();  
  123.         iic_send_byte(devaddr);  
  124.         if(0 == ack) return ERR;  
  125.         iic_send_byte(romaddr);  
  126.         if(0 == ack) return ERR;  
  127.         for(i = 0;i < num;i++)  
  128.         {  
  129.                 iic_send_byte(*s);  
  130.                 if(0 == ack) return ERR;  
  131.                 s++;  
  132.         }  
  133.         iic_stop();  
  134.         return SUCC;  
  135.   
  136.   
  137. }  
  138.   
  139.   
  140. unsigned char AT24C02_rcv_byte(unsigned char devaddr,unsigned char romaddr,unsigned charchar *s,unsigned char num)  
  141. {  
  142.         unsigned char i;  
  143.         iic_start();  
  144.         iic_send_byte(devaddr);  
  145.         if(0 == ack) return ERR;  
  146.         iic_send_byte(romaddr);  
  147.         if(0 == ack) return ERR;  
  148.         iic_start();  
  149.         iic_send_byte(devaddr + 1);  
  150.       
  151.         for(i = 0;i < num - 1;i++)  
  152.         {  
  153.                 *s = iic_rcv_byte();  
  154.                 iic_ack();  
  155.                 s++;  
  156.   
  157.   
  158.         }  
  159.         *s = iic_rcv_byte();  
  160.         iic_noack();  
  161.         iic_stop();  
  162.         return SUCC;  
  163. }  
  164.   
  165.   
  166.   
  167.   
  168. void lcd1602_write_data(unsigned char byte,unsigned char flag)  
  169. {  
  170.         if(flag)  
  171.         {  
  172.                 RS = 1;  
  173.         }  
  174.         else  
  175.         {  
  176.                 RS = 0;  
  177.         }  
  178.         RW = 0;  
  179.         E = 1;  
  180.         LCDPORT = byte;  
  181.         delay_us(5);  
  182.         E = 0;  
  183. }  
  184.   
  185.   
  186. void lcd_init()  
  187. {  
  188.         delay_ms(15);  
  189.         lcd1602_write_data(0x38,LCD_WRITE_COM);  
  190.         delay_ms(5);  
  191.         lcd1602_write_data(0x38,LCD_WRITE_COM);  
  192.         delay_ms(5);  
  193.         lcd1602_write_data(0x38,LCD_WRITE_COM);  
  194.         delay_ms(5);  
  195.         lcd1602_write_data(0x38,LCD_WRITE_COM);  
  196.         delay_ms(5);  
  197.         lcd1602_write_data(0x08,LCD_WRITE_COM);  
  198.         delay_ms(5);  
  199.         lcd1602_write_data(0x01,LCD_WRITE_COM);  
  200.         delay_ms(5);      
  201.         lcd1602_write_data(0x06,LCD_WRITE_COM);  
  202.         delay_ms(5);  
  203.         lcd1602_write_data(0x0c,LCD_WRITE_COM);  
  204.         delay_ms(5);  
  205. }  
  206.   
  207.   
  208. void lcd_write_str(unsigned char x,unsigned char y,unsigned charchar *p)  
  209. {  
  210.         if((x > 15) || (y > 1))  
  211.         {  
  212.                 return;  
  213.         }  
  214.         if(0 == y)  
  215.         {  
  216.                 lcd1602_write_data(0x80+x,LCD_WRITE_COM);  
  217.         }  
  218.         else  
  219.         {  
  220.                 lcd1602_write_data(0x80+0x40+x,LCD_WRITE_COM);  
  221.         }  
  222.   
  223.   
  224.         while(*p != '\0')  
  225.         {  
  226.               lcd1602_write_data(*p,LCD_WRITE_DATA);          
  227.                 p++;  
  228.         }  
  229. }  
  230.   
  231.   
  232. unsigned char AD_read()  
  233. {  
  234.     unsigned char temp;   
  235.     iic_start();  
  236.     iic_send_byte(0x90);  
  237.     if(0 == ack) return ERR;  
  238.     iic_send_byte(0x40);  
  239.     iic_start();  
  240.     iic_send_byte(0x90+1);  
  241.     if(0 == ack) return ERR;  
  242. }  
  243.     temp = iic_rcv_byte();  
  244.     iic_noack();  
  245.     iic_stop();  
  246.     return temp;  
  247.   
  248.   
  249.   
  250.   
  251. void lcd_dis_char(unsigned char x, unsigned char y, unsigned char byte)  
  252. {  
  253.     if((x > 15) || (y > 1))  
  254.         {  
  255.               return ;  
  256.         }  
  257.         if(0 == y)  
  258.         {  
  259.               lcd1602_write_data(0x80 + x,LCD_WRITE_COM);  
  260.         }  
  261.         else  
  262.         {  
  263.               lcd1602_write_data(0x80 + 0x40 + x,LCD_WRITE_COM);  
  264.         }  
  265.         lcd1602_write_data(byte,LCD_WRITE_DATA);  
  266. }  
  267.   
  268.   
  269. unsigned char DA_write(unsigned char num)  
  270. {  
  271.         iic_start();  
  272.         iic_send_byte(0x90);  
  273.         if(0 == ack) return ERR;  
  274.         iic_send_byte(0x40);  
  275.         if(0 == ack) return ERR;  
  276.         iic_send_byte(num);  
  277.         if(0 == ack) return ERR;  
  278.         iic_stop();  
  279.         return SUCC;  
  280. }  
  281.   
  282.   
  283. void main()  
  284. {  
  285.         unsigned char num;  
  286.         unsigned char test;  
  287.         unsigned char v;  
  288.         lcd_init();  
  289.           
  290.     while(1)  
  291.         {  
  292.                 test = AD_read();  
  293.                 v = test*100 / 51;   
  294.                 lcd_dis_char(0,0,(test/100)+0x30);  
  295.                 lcd_dis_char(1,0,(test%100/10)+0x30);  
  296.                 lcd_dis_char(2,0,(test%10)+0x30);  
  297.                 lcd_dis_char(0,1,(v/100)+0x30);  
  298.                 lcd_dis_char(1,1,'.');  
  299.                 lcd_dis_char(2,1,(v%100)/10+0x30);  
  300.                 lcd_dis_char(3,1,(v%10)+0x30);  
  301.                 DA_write(num);  
  302.                 num++;  
  303.                 delay_ms(2);  
  304.         }  
  305.   
  306.   
  307.           
  308.           
  309. }  
<think>嗯,用户问的是AD/DA转换,也就是模数转换和数模转换。首先我得确认自己对这两个概念的理解是否正确。AD转换是模拟信号转数字信号,DA转换则是反过来。可能需要先分别解释两者的定义和基本原理。 然后,用户可能想知道它们的应用场景,比如在哪些设备或系统中使用。比如ADC在传感器、音频处理中的应用,DAC在音频输出、控制系统中的应用。还需要提到常见的技术指标,比如分辨率、采样率、精度这些,因为这些参数会影响转换的质量。 接下来,可能需要举一些例子或者常见的芯片型号,比如ADC中的逐次逼近型、积分型,或者DAC中的R-2R网络结构。这样用户能更具体地理解。 另外,工作原理部分,AD转换可能涉及采样、保持、量化、编码这几个步骤,而DA转换则是将数字信号加权求和,转换成模拟电压或电流。需要简明扼要地解释这些步骤,避免太复杂的术语,但又要准确。 还要注意用户可能的疑问点,比如为什么需要AD/DA转换,数字信号处理的优势在哪里。可能涉及到抗干扰能力强、存储方便、处理灵活等方面。 相关问题方面,用户可能想知道具体的应用实例,或者如何选择ADC/DAC芯片,或者常见的问题比如转换误差、噪声处理等。需要确保提出的问题覆盖不同的方面,既有理论也有实际应用。 </think>AD/DA转换是电子工程中的核心技术,涉及模拟信号与数字信号之间的双向转换: **AD转换(模数转换)** 将连续模拟信号(如电压、温度)转换为离散数字信号。核心步骤包括: 1. **采样**:按奈奎斯特定理以≥2倍最高频率采样 2. **量化**:将采样值映射到有限位数(如8/12/16位) 3. **编码**:生成二进制数字输出 常见ADC类型:逐次逼近型(如ADC0804)、积分型、Σ-Δ型 **DA转换(数模转换)** 将数字信号还原为模拟信号。典型方法: 1. **权重电阻网络**(精度依赖电阻匹配度) 2. **R-2R梯形网络**(更易集成,如DAC0832) 关键指标:分辨率(如12位)、建立时间、线性度 **典型应用** - ADC:传感器数据采集、音频输入 - DAC:音频输出、工业控制信号生成 ```c // 简化版ADC采样示例(假设10位精度) uint16_t read_sensor_voltage() { uint16_t adc_value = 0; // 触发采样保持电路 start_adc_conversion(); // 等待转换完成(需根据时钟频率计算延时) delay_us(10); // 读取10位结果 adc_value = (ADRESH << 8) | ADRESL; return adc_value; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值