单片机 【AD/DA模块】

 

 

  1 #include <reg52.h>
  2 #include <intrins.h>
  3 #define MAIN_Fosc        11059200UL    //宏定义主时钟HZ
  4 #define PCF8591_ADDR    0x90        //PCF8591地址
  5 #define DACOUT_EN        0x40        //DAC输出使能
  6 
  7 /*====================================
  8  自定义类型名
  9 ====================================*/
 10 typedef unsigned char INT8U;
 11 typedef unsigned char uchar;
 12 
 13 typedef unsigned int INT16U;
 14 typedef unsigned int uint;
 15 
 16 /*====================================
 17  硬件接口位声明
 18 ====================================*/
 19 sbit SDA = P2^0;   //I2C串行数据
 20 sbit SCL = P2^1;   //I2C串行时钟
 21 sbit DU  = P2^6;   //数码管段选
 22 sbit WE  = P2^7;   //数码管位选
 23 sbit LED1= P1^0;   //读取AD的值是否成功(亮成功,灭失败)
 24 sbit LED2= P1^1;   //DAC成功输出(亮成功,灭失败)
 25 sbit BEEP= P2^3;   //蜂鸣器引脚定义
 26 
 27 uchar AD_Value;    //存储AD转换回的数字量
 28 /*====================================
 29 共阴极数码管段选码
 30 ====================================*/
 31 uchar code table[]={ 
 32 //0        1     2     3     4     5     6     7     8
 33 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
 34 //9     A     B       C     D       E     F        -     .      关显示
 35 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
 36                    };
 37 
 38 /*====================================
 39 数码管位选码
 40 ====================================*/
 41                   //第1位    2位      3位     4位   5位    6位      7位    8位
 42 uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码
 43 
 44 /*====================================
 45 函数:void Delay_Ms(INT16U ms)
 46 参数:ms,毫秒延时形参
 47 描述:12T 51单片机自适应主时钟毫秒级延时函数
 48 ====================================*/
 49 void Delay_Ms(INT16U ms)
 50 {
 51      INT16U i;
 52      do{
 53           i = MAIN_Fosc / 96000; 
 54           while(--i);   //96T per loop
 55      }while(--ms);
 56 }
 57 
 58 /*====================================
 59 函数:void Delay5us()
 60 描述:12T 51单片机5微秒延时函数自适应时钟(11.0592M,12M,22.1184M)
 61 ====================================*/
 62 void Delay5us()
 63 {
 64     #if MAIN_Fosc == 11059200
 65         _nop_();
 66     #elif MAIN_Fosc == 12000000
 67         _nop_();
 68     #elif MAIN_Fosc == 22118400
 69         _nop_(); _nop_(); _nop_();
 70     #endif
 71 }
 72 
 73 /*====================================
 74 函数:void Display(INT8U Value)
 75 参数:Value,显示值 取值0-255
 76 描述:共阴极数码管显示函数可显示一个字节的数
 77 ====================================*/
 78 void Display(INT8U Value)
 79 {
 80 //------------------------------
 81     DU = 1;
 82     P0 = table[Value/100];    //管显示百位
 83     DU = 0;
 84 
 85     P0 = 0xff;                  //清除断码
 86 
 87     WE = 1;
 88     P0 = T_COM[0];              //第一位数码管
 89     WE = 0;
 90     Delay_Ms(5);
 91 //-------------------------------
 92     DU = 1;
 93     P0 = table[Value%100/10]; //显示十位
 94     DU = 0;
 95 
 96     P0 = 0xff;                  //清除断码
 97 
 98     WE = 1;
 99     P0 = T_COM[1];              //第二位数码管
100     WE = 0;
101     Delay_Ms(5);
102 //-------------------------------
103     DU = 1;
104     P0 = table[Value%10];        //显示个位
105     DU = 0;
106                                 
107     P0 = 0xff;                    //清除断码
108 
109     WE = 1;
110     P0 = T_COM[2];                //第三位数码管
111     WE = 0;
112     Delay_Ms(5);
113 }
114 
115 /*====================================
116 函数:I2C_init()
117 描述:I2C总线初始化
118 ====================================*/
119 void I2C_init()
120 {
121     SDA = 1;   //数据总线高
122     _nop_();
123     SCL = 1;   //时钟总线高
124     _nop_();
125 }
126 
127 /*====================================
128 函数:I2C_Start()
129 描述:I2C起始信号
130 ====================================*/
131 void I2C_Start()  
132 {
133     SCL = 1;
134     _nop_();
135     SDA = 1;
136     Delay5us();
137     SDA = 0;
138     Delay5us();
139 }
140 
141 /*====================================
142 函数:I2C_Stop()
143 描述:I2C停止信号
144 ====================================*/
145 void I2C_Stop()
146 {
147     SDA = 0;
148     _nop_();
149     SCL = 1;
150     Delay5us();
151     SDA = 1;
152     Delay5us();
153 }
154 
155 /*====================================
156 函数:Master_ACK(bit i)
157 参数:i 为0时发送非应答 为1时发送应答
158 描述:I2C主机发送应答
159 ====================================*/
160 void Master_ACK(bit i)    
161 {
162     SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化
163     _nop_(); // 让总线稳定
164     if (i)     //如果i = 1 那么拉低数据总线 表示主机应答
165     {
166         SDA = 0;
167     }
168     else     
169     {
170         SDA = 1;     //发送非应答
171     }
172     _nop_();//让总线稳定
173     SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号
174     _nop_();
175     SCL = 0;//拉低时钟总线, 占用总线继续通信
176     _nop_();
177     SDA = 1;//释放SDA数据总线。
178     _nop_();
179 }
180 
181 /*====================================
182 函数:Test_ACK()
183 返回:0为非应答 1为应答
184 描述:I2C检测从机应答
185 ====================================*/
186 bit Test_ACK()     // 检测从机应答
187 {
188     SCL = 1;//时钟总线为高电平期间可以读取从机应答信号
189     Delay5us();
190     if (SDA)
191     {
192         SCL = 0;
193         I2C_Stop();
194         return(0);
195     }
196     else
197     {
198         SCL = 0;
199         return(1);
200     }
201 }
202 
203 /*====================================
204 函数:I2C_send_byte(uchar byte)
205 参数:byte 要发送的字节
206 描述:I2C发送一个字节
207 ====================================*/
208 void I2C_send_byte(uchar byte)
209 {
210     uchar i;
211     for(i = 0 ; i < 8 ; i++)
212     {
213         SCL = 0;
214         _nop_();
215         if (byte & 0x80)    //
216         {
217             SDA = 1;
218             _nop_();
219         }
220         else
221         {
222             SDA = 0;
223             _nop_();
224         }
225         SCL = 1;
226         _nop_();
227         byte <<= 1;
228     }
229     SCL = 0;
230     _nop_();
231     SDA = 1;
232     _nop_();    
233 }
234 
235 /*====================================
236 函数:I2C_read_byte()
237 返回:读取的字节
238 描述:I2C读一个字节
239 ====================================*/
240 uchar I2C_read_byte()
241 {
242     uchar i, dat;
243     SCL = 0 ;
244     _nop_();
245     SDA = 1;
246     _nop_();
247     for(i = 0 ; i < 8 ; i++)
248     {
249         SCL = 1;
250         _nop_();
251         dat <<= 1;      
252         if (SDA)
253         {
254             dat |= 0x01;  
255         }
256         _nop_();
257         SCL = 0;
258         _nop_();
259     }
260     return(dat);
261 }
262 
263 /*DAC输出*/
264 bit DAC_OUT(uchar DAT)
265 {
266     I2C_Start();
267     I2C_send_byte(PCF8591_ADDR+0);//
268     if (!Test_ACK())
269     {
270         return(0);
271     }
272     I2C_send_byte(DACOUT_EN);//    //DA输出使能 
273     if (!Test_ACK())
274     {
275         return(0);
276     }
277     I2C_send_byte(DAT);
278     if (!Test_ACK())
279     {
280         return(0);
281     }
282     I2C_Stop();
283     return(1);    
284 }
285 
286 /*读AD数据*/
287 bit ADC_Read(uchar CON)
288 {
289     I2C_Start();
290     I2C_send_byte(PCF8591_ADDR+0);
291     if (!Test_ACK())
292     {
293         return(0);
294     }
295     I2C_send_byte(CON);  //
296     Master_ACK(0);
297     I2C_Start();
298     I2C_send_byte(PCF8591_ADDR+1);
299     if (!Test_ACK())
300     {
301         return(0);
302     }
303     AD_Value = I2C_read_byte();
304     Master_ACK(0);
305     I2C_Stop();
306     return(1);    
307 }
308 
309 void main()
310 {
311     I2C_init();
312     while(1)
313     {        
314         //单端输入,读出通道2的值
315         if (ADC_Read(0x02))    LED1 = 0;    else    LED1 = 1;    
316         if (DAC_OUT(AD_Value))    LED2 = 0;    else    LED2 = 1;
317         Display(AD_Value);
318         if (AD_Value > 150)    BEEP = 0;    else    BEEP = 1;
319         Delay_Ms(5);
320     }    
321 }
AD代码

 

posted @ 2018-04-04 16:42  Justice-V  阅读(366)  评论(0)    收藏  举报