打印

失败、失败、太失败了。现在有的还**使用8255

[复制链接]
3740|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
邹凯东|  楼主 | 2007-7-21 12:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


1. 实验任务 
利用单片机AT89S51与ADC0809设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码显示

相关帖子

沙发
古道热肠| | 2007-7-21 12:49 | 只看该作者

你这是在做实验吧

  AD的CLK最好来自P1.0用定时器2的分频脉冲输出功能比你介绍的好。
程序自已调试调试就明白了。

使用特权

评论回复
板凳
NE5532| | 2007-7-21 13:13 | 只看该作者

典型学生作业的说

使用特权

评论回复
地板
邹凯东|  楼主 | 2007-7-21 13:38 | 只看该作者

我智力不高,实在看不懂我打了问好的那几出地方到底是什么意思!请各位帮帮这学生吧!就当为祖国培育下一代了!

使用特权

评论回复
5
救火车| | 2007-7-21 15:16 | 只看该作者

别着急。慢慢调。

先检查几遍硬件连线。确保每条线,每个点都正确可靠。
软件调试分解成AD采集和数码显示两部分。
数码显示部分:
          dispbuf[6]=0; 
          dispbuf[7]=0; 
           /////////////////////////////////
           temp=1234;//在这个地方对temp强行赋值
           /////////////////////////////////
          while(temp/10) 
            { 
调试你的系统直到能正确显示出你赋值的数据。
AD采集部分:
也比较简单。好好看看芯片的技术资料,结合程序看吧。

使用特权

评论回复
6
邹凯东|  楼主 | 2007-7-21 16:00 | 只看该作者

谢谢各位好心人的,可我的情况有点特殊,哪位能详细点告诉我

temp为什么乘235,然后又除128?费解的!我手头没有芯片,老师要我们看懂程序,可我第一次接触单片机编程,只是简单看过几本初级编程书,怎么理解啊!谁来拯救我!

使用特权

评论回复
7
shunpu| | 2007-7-21 16:55 | 只看该作者

理解楼主

使用特权

评论回复
8
邹凯东|  楼主 | 2007-7-21 17:26 | 只看该作者

理解万岁!

使用特权

评论回复
9
NE5532| | 2007-7-21 17:33 | 只看该作者

你得看ADC0809的数据手册,而不是程序。

使用特权

评论回复
10
邹凯东|  楼主 | 2007-7-21 17:44 | 只看该作者

了解!

使用特权

评论回复
11
gyt| | 2007-7-21 20:27 | 只看该作者

0809?

你们老师一定是位老古董:)

使用特权

评论回复
12
hotpower| | 2007-7-22 00:59 | 只看该作者

估计又是哪个倒塌的老师坑害青少年~~~

使用特权

评论回复
13
conwh| | 2007-7-22 02:35 | 只看该作者

失败、失败、太失败了。现在有的还**使用8255

使用特权

评论回复
14
太阳之母| | 2007-7-22 10:39 | 只看该作者

嘿嘿

unsigned char code dispbitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};              //8个数码管的“管选”码
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};  //0~9以及空格的显示字模
unsigned char dispbuf[8]={10,10,10,10,0,0,0,0};                                            //8个字节的显示缓冲区
unsigned char dispcount; 
unsigned char getdata;                                                                    //存放AD转换结果的变量
unsigned int temp;                                                                      //存放具体物理量值的变量
unsigned char i;
  
sbit ST=P3^0;                                                         //启动下一次AD转换的控制信号,8051-->AD芯片
sbit OE=P3^1;                                                            //AD芯片输出使能控制信号, 8051-->AD芯片
sbit EOC=P3^2;                                                     //表示当前AD转换完成的状态信号,AD芯片--->8051
sbit CLK=P3^3;                                                                  //AD芯片的时钟信号,8051-->AD芯片
  
  
void main(void) 

  ST=0; 
  OE=0; 
  ET0=1; 
  ET1=1; 
  EA=1; 
  TMOD=0x12;                     //定时器0工作在16位方式,定时器1工作在8位自动重装载方式
  TH0=216;             //定时器0的定时常数=256-216=40, 如果使用12MHz晶体,就是40us定时
  TL0=216; 
  TH1=(65536-4000)/256; 
  TL1=(65536-4000)%256;   //类似,如果使用12MHz晶体,定时器1的定时值就是4000us(或者说4ms)
  TR1=1; 
  TR0=1; 
  ST=1; 
  ST=0; 
  while(1)                                                        //main()函数的主循环
    { 
      if(EOC==1)                                                  //如果当前AD转换结束
        { 
          OE=1; 
          getdata=P0; 
          OE=0; 
          temp=getdata*235; //????*235是什么意思?
          temp=temp/128;    //????这又是什么意思?  
//上面两行的意思应该是乘以一个系数:235/128以便归一化到某个具体的物理量上,比如测量温度,
//AD转换的电压值和温度值之间有一个转换系数,通过这样的处理,显示的就是真实的温度值了
          i=5; 
//******************************以下8行给显示缓冲区赋初始值****************************
          dispbuf[0]=10; 
          dispbuf[1]=10; 
          dispbuf[2]=10; 
          dispbuf[3]=10; 
          dispbuf[4]=10; 
          dispbuf[5]=0; 
          dispbuf[6]=0; 
          dispbuf[7]=0;
//******************************以上8行给显示缓冲区赋初始值****************************
//*****以下从高位到低位取出各位的值到显示缓冲区(temp是字节量,也就是从百位到个位取)*****
          while(temp/10)                                                 //注意i从5开始
            { 
              dispbuf=temp%10; 
              temp=temp/10; 
              i++; 
            } 
          dispbuf=temp;
//*****以上从高位到低位取出各位的值到显示缓冲区(temp是字节量,也就是从百位到个位取)*****
          ST=1; 
          ST=0;                                              //重新启动下一个AD转换过程
        } 
    } 

  
void t0(void) interrupt 1 using 0 //这个中断每隔40us发生一次,每两次在P3.3上生成一个方波

  CLK=~CLK;//在P3.3引脚上产生方波,结合前面说到的40us定时,频率f=[1000000/(40+40)=25KHz


//下面这个中断每隔4ms发生一次,每次通过P1把一个显示字模送出去,至于送出去的这个字模显示到哪
//个数码管上,这又是通过P2来选中一个数码管把这个字模显示出来的(第dispcount个被选中)
//dispcount是循环变化的(从0变化到7),所以每隔4ms从0号数码管到7号数码管循环显示对应的数码.
void t1(void) interrupt 3 using 0      

  TH1=(65536-4000)/256; 
  TL1=(65536-4000)%256; 
//  P1=dispcode][dispbuf][dispcount]]; //这里你把放括号打错了!!!
  P1=dispcode[ dispbuf][dispcount] ];    //应该是这样的(加空格是为了你看得更清楚)
  P2=dispbitcode[dispcount];                                   //P1和P2的说明在最后
  if(dispcount==7) //估计最后一个数码管的小数点显示了并且P1的最高位控制小数点的亮灭
    { 
      P1=P1 | 0x80; 
    } 
  dispcount++; 
  if(dispcount==8)                      //dispcount在0~7之间递增循环变化,对应0~7号数码管
    { 
      dispcount=0; 
    }  

//进一步说明:假定dispbuf[0]~dispbuf[7]里内容是{10,  10,  10,  10,  10,  3,   1,   4   }
//                           对应的dispcount = 0    1    2    3    4    5    6    7 
//                                  对应的P1 = 0x00,0x00,0x00,0x00,0x00,0x4f,0x06,0x66
//P1的某一位为1,数码管对应的笔画就点亮了       全灭 全灭 全灭 全灭 全灭 数码管上显示3,1,4
//的时候各有几个笔画点亮?0x4f,0x06,0x66里各有几个位为1?

//还是假定dispbuf[0]~dispbuf[7]里内容是{10,      10,      10,      10,      10,      3,       1,       4       }
//                    对应的dispcount = 0        1        2        3        4        5        6        7 
//                           对应的P2 = 0xfe,    0xfd,    0xfb,    0xf7,    0xef,    0xdf,    0xbf,    0x7f
//                                      11111110,11111101,11111011,11110111,11101111,11011111,10111111,01111111
//注意上一行中每个字节只有一位为0,对应位置上的数码关2被选中
//注释说明够详细了吧?再不明白我就只好跳楼了!不过你得先给我买一楼,五层的就够了


使用特权

评论回复
15
太阳之母| | 2007-7-22 10:45 | 只看该作者

嘿嘿

TNND,还是打错了
P1=dispcode[ dispbuf][dispcount] ];    //应该是这样的(加空格是为了你看得更清楚)
... ...
... ...
//注意上一行中每个字节只有一位为0,对应位置上的数码管被选中

使用特权

评论回复
16
太阳之母| | 2007-7-22 10:47 | 只看该作者

嘿嘿

怎么回事?
      P1=dispcode[ dispbuf][dispcount] ];    
                          ^
                          |
这个方括号是BBS自动加上去的?

使用特权

评论回复
17
邹凯东|  楼主 | 2007-7-22 10:54 | 只看该作者

详细之非常!

谢谢啊!我们家住五楼的,要是愿意来我们家跳!11点左右来也许还能赶上一顿午饭!       对了,我改名了,叫纤夫,下次看见一定要来帮忙!有大家与我并肩作战,老师哪还有嚣张的资本!.......这里没有哪个是作老师的吧?...我是单指我那老师!其实心里我是很尊敬老师的!真的

使用特权

评论回复
18
邹凯东|  楼主 | 2007-7-22 11:30 | 只看该作者

全懂了,就是下面中断中的那个3和那个0是什么意思?

void t1(void) interrupt 3 using 0 

  TH1=(65536-4000)/256; 
  TL1=(65536-4000)%256; 
  P1=dispcode[dispbuf][dispcount]]; 
  P2=dispbitcode[dispcount]; 
  if(dispcount==7) 
    { 
      P1=P1 | 0x80; 
    } 
  dispcount++; 
  if(dispcount==8) 
    { 
      dispcount=0; 
    }  


使用特权

评论回复
19
太阳之母| | 2007-7-22 17:18 | 只看该作者

嘿嘿

interrupt 3        using 0
          |              |
    8051第3号中断,使用第0组工作寄存器(R0~R7,有四组)
普通的8051有5个中断,排列顺序为:外部中断0(0号中断),定时器/计数器0(1号中断),外部中断1(2号中断),定时器/计数器1(3号中断),串口中断(4号中断)

使用特权

评论回复
20
邹凯东|  楼主 | 2007-7-22 21:27 | 只看该作者

太阳之母...我不让你死!

今天你帮了我大忙了!程序我看懂了!你没必要跳楼了!让你死还真是要花点本钱的!我不但看懂了,而且还发现了这程序好像有几处错误!想向你求证一下!这是电压检测电路,利用AD转换,我觉得两个中断好想少了点什么!而且定时器1是工作在8位自装载情况下的,为什么有16位!而且既然是自装载,为什么它又在中断中给它设值,它自己不是能自己装载的吗?而且好像定时器0只会计数一次,因为它计数满后就没人给它值,让它重来一次了?是真的有错?还是......你会去我家吃午饭!!!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

21

帖子

0

粉丝