首页 > 技术文章 > (七)单片机控制两路数据采集系统 这里要学习中断

shengruxiahua 2015-12-26 12:07 原文

自己修改电路图和代码,结果调试不成功?不知道为什么????

电路图如下:  127   247  移动滑动变阻器没有软用???

错误代码:

  1 #include<reg52.h>
  2 #define uchar8 unsigned char 
  3 #define uint16 unsigned int 
  4 sbit CLOCK = P2^0;
  5 sbit START = P2^1;
  6 sbit EOC   = P2^3;   // A/D转换结束信号,输出,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)
  7 sbit OE    = P2^2;   // 数据输出允许信号,输入,高电平有效。 当A/D转换结束时,此端输入一个高电平,输出数字量
  8 
  9 sbit wei1  = P3^1; 
 10 sbit wei2  = P3^2;
 11 sbit wei3  = P3^3;
 12 
 13 sbit wei4  = P3^5;
 14 sbit wei5  = P3^6;
 15 sbit wei6  = P3^7;
 16 
 17 
 18 uchar8 code dulatab[]={  0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F }   ; // 0----9
 19 uchar8 code welatab[]={  0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf,0x7f };  // 数码管位控码
 20 
 21 
 22 /*****************************/
 23 // 函数名称: DelayMS( )
 24 // 函数功能: 延时
 25 // 入口函数: 延时毫秒
 26 // 出口函数: 无
 27 /*************************                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              *******************/
 28 void delay(uint16 val)
 29 {
 30        uint16  i,j;
 31        for( i=0;i<val;i++)
 32            for(j=0;j<113;j++);
 33 
 34 }                                           
 35 
 36 
 37 void init( )   // 初始化
 38 {
 39      P2=0xff;
 40      EA = 1;
 41      TMOD = 0x02 ;
 42      TH0=216;
 43      TL0=216;
 44      TR0=1;
 45      ET0=1;
 46 
 47      START=0;
 48      OE=0;
 49      P2=0x30;        // 这里仿真 EOC 出现短路
 50 }             
 51 
 52 
 53 void write1(uchar8 num)            
 54 {
 55 
 56    uchar8  i,j,k;
 57    k=num/100;
 58    j=num%100/10;
 59    i=num%10;
 60 
 61    P3=0xff;
 62    P0=dulatab[k];
 63    wei4=0;
 64    delay(4);
 65 
 66    P3=0xff;
 67    P0=dulatab[j];
 68    wei5=0;
 69    delay(4);
 70 
 71    P3=0xff;
 72    P0=dulatab[i];
 73    wei6=0;
 74    delay(4);
 75 
 76 }
 77 
 78 void write0(uchar8 num)
 79 {
 80 
 81    uchar8  i,j,k;
 82    k=num/100;
 83    j=num%100/10;
 84    i=num%10;
 85 
 86    P3=0xff;
 87    P0=dulatab[k];
 88    wei1=0;
 89    delay(4);
 90 
 91    P3=0xff;
 92    P0=dulatab[j];
 93    wei2=0;
 94    delay(4);
 95 
 96    P3=0xff;
 97    P0=dulatab[i];
 98    wei3=0;
 99    delay(4);
100 
101 }
102 
103 
104 uchar8 adin0()
105 {
106     uchar8 value;
107     OE = 0;        // 数据先不允许输出
108     EOC = 1;    // 
109     START = 0;
110     P2&=0x8f;    // 1000 1111 位与 保持 低四位不变(即 OE EOC START CLOCK )
111 
112     P2|=0x30;   //   使得 C B A     为 1 1 0 ,那么 也就是 选择 IN3通道 
113     delay(10);
114 
115     START=1;   // 上升沿 使得 0809 复位
116     delay(10);
117     START=0;   //  下降沿 ,启动 AD 转换
118   
119     while(!EOC); // EOC = =0 ,为什么省去了 CLOCK; WHY ?????
120     //   while(1)
121     //  {
122     //            CLOCK = ! CLOCK ; if( EOC == 1)  break ;   // 等待转换结束,跳出循环                                                  
123     //  }
124 
125     delay(10);
126     OE = 1;           //   当A/D转换结束时,此端输入一个高电平,输出数字量。OE=0,关闭输出,不准输出到单片机
127     delay(1);
128 
129     value=P3;
130     OE=0;           // OE=0,关闭输出,不准输出到单片机
131     return value;
132 
133 }
134 
135 uchar8 adin1()
136 {
137     uchar8 value;
138     OE = 0;        // 数据先不允许输出
139     EOC = 1;    // 
140     START = 0;
141     P2&=0x8f;    // 1000 1111 位与 保持 低四位不变(即 OE EOC START CLOCK )
142 
143     P2|=0x00;   //   使得 C B A     为 1 1 0 ,那么 也就是 选择 IN3通道 
144     delay(10);
145 
146     START=1;   // 上升沿 使得 0809 复位
147     delay(10);
148     START=0;   //  下降沿 ,启动 AD 转换
149   
150     while(!EOC); // EOC = =0 ,为什么省去了 CLOCK; WHY ?????
151     //   while(1)
152     //  {
153     //            CLOCK = ! CLOCK ; if( EOC == 1)  break ;   // 等待转换结束,跳出循环                                                  
154     //  }
155 
156     delay(10);
157     OE = 1;           //   当A/D转换结束时,此端输入一个高电平,输出数字量。OE=0,关闭输出,不准输出到单片机
158     delay(1);
159 
160     value=P3;
161     OE=0;           // OE=0,关闭输出,不准输出到单片机
162     return value;
163 
164 }
165 
166 
167 void main()
168 {
169    uchar8 in0,in1;
170    init();
171    while(1)
172    {
173      in0 = adin0();
174      write0(in0);
175      
176      in1 = adin1();
177      write1(in1);    
178     
179    }
180 }
181 
182 void timer0 ( void )  interrupt 1
183 {
184      CLOCK = ~ CLOCK ;
185 
186 }

 

不知道为什么,也不清楚究竟哪里出错了????

还是按照书上的过一遍看看???

 

实验图:

 

 

相关代码:

  1 #include<reg52.h>
  2 #define uchar8 unsigned char 
  3 #define uint16 unsigned int 
  4 sbit CLOCK = P1^3;
  5 sbit START = P1^2;
  6 sbit EOC   = P1^1;   // A/D转换结束信号,输出,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)
  7 sbit OE    = P1^0;   // 数据输出允许信号,输入,高电平有效。 当A/D转换结束时,此端输入一个高电平,输出数字量
  8 
  9 sbit wei1  = P2^1; 
 10 sbit wei2  = P2^2;
 11 sbit wei3  = P2^3;
 12 
 13 sbit wei4  = P2^5;
 14 sbit wei5  = P2^6;
 15 sbit wei6  = P2^7;
 16 
 17 
 18 uchar8 code dulatab[]={  0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F }   ; // 0----9
 19 uchar8 code welatab[]={  0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf,0x7f };  // 数码管位控码
 20 
 21 
 22 /*****************************/
 23 // 函数名称: DelayMS( )
 24 // 函数功能: 延时
 25 // 入口函数: 延时毫秒
 26 // 出口函数: 无
 27 /*************************                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              *******************/
 28 void delay(uint16 val)
 29 {
 30        uint16  i,j;
 31        for( i=0;i<val;i++)
 32            for(j=0;j<113;j++);
 33 
 34 }                                           
 35 
 36 
 37 void init( )   // 初始化
 38 {
 39      P2=0xff;
 40      EA = 1;
 41      TMOD = 0x02 ;
 42      TH0=216;
 43      TL0=216;
 44      TR0=1;
 45      ET0=1;
 46 
 47      START=0;
 48      OE=0;
 49      P1=0x30;        // 
 50 }             
 51 
 52 
 53 void write1(uchar8 num)            
 54 {
 55 
 56    uchar8  i,j,k;
 57    k=num/100;
 58    j=num%100/10;
 59    i=num%10;
 60 
 61    P2=0xff;
 62    P0=dulatab[k];
 63    wei4=0;
 64    delay(4);
 65 
 66    P2=0xff;
 67    P0=dulatab[j];
 68    wei5=0;
 69    delay(4);
 70 
 71    P2=0xff;
 72    P0=dulatab[i];
 73    wei6=0;
 74    delay(4);
 75 
 76 }
 77 
 78 void write0(uchar8 num)
 79 {
 80 
 81    uchar8  i,j,k;
 82    k=num/100;
 83    j=num%100/10;
 84    i=num%10;
 85 
 86    P2=0xff;
 87    P0=dulatab[k];
 88    wei1=0;
 89    delay(4);
 90 
 91    P2=0xff;
 92    P0=dulatab[j];
 93    wei2=0;
 94    delay(4);
 95 
 96    P2=0xff;
 97    P0=dulatab[i];
 98    wei3=0;
 99    delay(4);
100 
101 }
102 
103 
104 uchar8 adin0()
105 {
106     uchar8 value;
107     OE = 0;        // 数据先不允许输出
108     EOC = 1;    // 
109     START = 0;
110     P1&=0x8f;    // 1000 1111 位与 保持 低四位不变(即 OE EOC START CLOCK )
111 
112     P1|=0x30;   //   使得 C B A     为 1 1 0 ,那么 也就是 选择 IN3通道 
113     delay(10);
114 
115     START=1;   // 上升沿 使得 0809 复位
116     delay(10);
117     START=0;   //  下降沿 ,启动 AD 转换
118   
119     while(!EOC); // EOC = =0 ,为什么省去了 CLOCK; WHY ?????
120     //   while(1)
121     //  {
122     //            CLOCK = ! CLOCK ; if( EOC == 1)  break ;   // 等待转换结束,跳出循环                                                  
123     //  }
124 
125     delay(10);
126     OE = 1;           //   当A/D转换结束时,此端输入一个高电平,输出数字量。OE=0,关闭输出,不准输出到单片机
127     delay(1);
128 
129     value=P3;
130     OE=0;           // OE=0,关闭输出,不准输出到单片机
131     return value;
132 
133 }
134 
135 uchar8 adin1()
136 {
137     uchar8 value;
138     OE = 0;        // 数据先不允许输出
139     EOC = 1;    // 
140     START = 0;
141     P1&=0x8f;    // 1000 1111 位与 保持 低四位不变(即 OE EOC START CLOCK )
142 
143     P1|=0x00;   //   使得 C B A     为 1 1 0 ,那么 也就是 选择 IN3通道 
144     delay(10);
145 
146     START=1;   // 上升沿 使得 0809 复位
147     delay(10);
148     START=0;   //  下降沿 ,启动 AD 转换
149   
150     while(!EOC); // EOC = =0 ,为什么省去了 CLOCK; WHY ?????
151     //   while(1)
152     //  {
153     //            CLOCK = ! CLOCK ; if( EOC == 1)  break ;   // 等待转换结束,跳出循环                                                  
154     //  }
155 
156     delay(10);
157     OE = 1;           //   当A/D转换结束时,此端输入一个高电平,输出数字量。OE=0,关闭输出,不准输出到单片机
158     delay(1);
159 
160     value=P3;
161     OE=0;           // OE=0,关闭输出,不准输出到单片机
162     return value;
163 
164 }
165 
166 
167 void main()
168 {
169    uchar8 in0,in1;
170    init();
171    while(1)
172    {
173      in0 = adin0();
174      write0(in0);
175      
176      in1 = adin1();
177      write1(in1);    
178     
179    }
180 }
181 
182 void timer0 ( void )  interrupt 1
183 {
184      CLOCK = ~ CLOCK ;
185 
186 }

 

 

 实验证明可以的,

总结: 数字不对的原因是   P0 八位端口 对应的  ADC0808 的 OUT1——OUT8接线不要搞反了就可以了??

至于程序还是要仔细,来回看看

 

推荐阅读