標(biāo)題: [求助]ADC0804與天祥TX-1C,數(shù)碼管總是現(xiàn)實(shí)255 [打印本頁]
作者: lbc363015930 時(shí)間: 2012-8-20 22:16
標(biāo)題: [求助]ADC0804與天祥TX-1C,數(shù)碼管總是現(xiàn)實(shí)255
我用的是天祥TX-1C的開發(fā)板,用單片機(jī)控制ADC0804進(jìn)行數(shù)模轉(zhuǎn)換,當(dāng)擰動(dòng)實(shí)驗(yàn)板上A/D旁邊的電位時(shí),在數(shù)碼管的前三位以十進(jìn)制方式顯示出A/D轉(zhuǎn)換后的數(shù)字量,但為什么一直顯示255,而不變換,為什么????程序如下,附件是原理圖
#include <reg52.h> //52系列單片機(jī)頭文件
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6; //申明U1鎖存器的鎖存端
sbit wela=P2^7; //申明U2鎖存器的鎖存端
sbit adwr=P3^6; //定義AD的WR端口
sbit adrd=P3^7; //定義AD的RD端口
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--) //i=xms即延時(shí)約xms毫秒
for(j=110;j>0;j--);
}
void display(uchar bai,uchar shi,uchar ge) //顯示子函數(shù)
{
dula=1;
P0=table[bai]; //送段選數(shù)據(jù)
dula=0;
P0=0xff; //送位選數(shù)據(jù)前關(guān)閉所有顯示,防止打開位選鎖存時(shí)
wela=1; //原來段選數(shù)據(jù)通過位選鎖存器造成混亂
P0=0x7e; //送位選數(shù)據(jù)
wela=0;
delayms(5); //延時(shí)
dula=1;
P0=table[shi];
dula=0;
P0=0xff;
wela=1;
P0=0x7d;
wela=0;
delayms(5);
dula=1;
P0=table[ge];
dula=0;
P0=0xff;
wela=1;
P0=0x7b;
wela=0;
delayms(5);
}
void main() // 主程序
{
uchar a,A1,A2,A3,adval;
wela=1;
P0=0x7f; //置CSAD為0,選通ADCS 以后不必再管ADCS
wela=0;
while(1)
{
adwr=1;
_nop_();
adwr=0; //啟動(dòng)AD轉(zhuǎn)換
_nop_();
adwr=1;
for(a=10;a>0;a--) //TX-1C實(shí)驗(yàn)板AD工作頻率較低,所以啟動(dòng)轉(zhuǎn)換后要多留點(diǎn)時(shí)間用來轉(zhuǎn)換
{ //這里把顯示部分放這里的原因也是為了延長轉(zhuǎn)換時(shí)間
display(A1,A2,A3);
}
P1=0xff; //讀取P1口之前先給其寫全1
adrd=1; //選通ADCS
_nop_();
adrd=0; //AD讀使能
_nop_();
adval=P1; //AD數(shù)據(jù)讀取賦給P1口
adrd=1;
A1=adval/100; //分出百,十,和個(gè)位
A2=adval%100/10;
A3=adval%10;
}
}
tx-1c型單片機(jī)開發(fā)板原理圖.pdf
(1015.98 KB, 下載次數(shù): 12)
2012-8-20 22:16 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者: 雪海 時(shí)間: 2013-6-28 21:12
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit wr=P3^6;
sbit rd=P3^7;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar aa,bai,ge,shi,d,a;
void display(uchar bai,uchar shi,uchar ge);
void init()
{
TMOD=0x01;
TH0=0x80;
TL0=0xFE;
EA=1;
ET0=1;
TR0=1;
aa=0;
}
void start()
{
wr=1;
_nop_();
wr=0;
_nop_();
wr=1;
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
void main()
{
init();
while(1)
{
start();
rd=1;
_nop_();
rd=0;
_nop_();
d=P1;
rd=1;
bai=d/100;
shi=d%100/10;
ge=d%10;
for(a=10;a>0;a--)
{
display(bai,ge,shi);
}
}
}
void display(uchar bai,uchar shi,uchar ge)
{
dula=1;
P0=table[bai];
dula=0;
P0=0xff;
wela=1;
P0=0x7e;
wela=0;
delay(1);
dula=1;
P0=table[shi];
dula=0;
P0=0xff;
wela=1;
P0=0x7d;
wela=0;
delay(1);
dula=1;
P0=table[ge];
dula=0;
P0=0xff;
wela=1;
P0=0x7b;
wela=0;
delay(1);
}
void timer0() interrupt 1
{
TH0=0x80;
TL0=0xFE;
aa++;
}我的這個(gè)程序沒問題
作者: w322405 時(shí)間: 2017-9-24 08:51
讀前讀數(shù)據(jù)rd前要把cs置0也就是wela=1;P0=0x7f
作者: 冰凌主銀 時(shí)間: 2019-12-11 20:50
我也遇到了,然后改改改,就正確了,加了注釋,代碼如下:
/*
原理:
ADC0804: ADC0804是8位全MOS中速A/D 轉(zhuǎn)換器,它是逐次逼近式A/D 轉(zhuǎn)換器,片內(nèi)有三態(tài)數(shù)據(jù)輸出鎖存器,
可以和單片機(jī)直接接口。單通道輸入,轉(zhuǎn)換時(shí)間大約為100us。
ADC0804 轉(zhuǎn)換時(shí)序是:當(dāng)CS=0 許可進(jìn)行A/D 轉(zhuǎn)換。
WR由低到高時(shí),A/D開始轉(zhuǎn)換,一次轉(zhuǎn)換一共需要66-73 個(gè)時(shí)鐘周期。
CS與WR同時(shí)有效時(shí)啟動(dòng)A/D轉(zhuǎn)換,轉(zhuǎn)換結(jié)束產(chǎn)生INTR 信號(低電平有效),可供查詢或者中斷信號。
在CS和RD 的控制下可以讀取數(shù)據(jù)結(jié)果。本實(shí)驗(yàn)沒有使用INTR信號。
*/
//擰動(dòng)AD旁邊的電位器,會(huì)在數(shù)碼管的前三位顯示0-255之間的數(shù)值。
//這就是把模擬信號轉(zhuǎn)換成數(shù)字信號,即模數(shù)轉(zhuǎn)換。
#include <reg52.h> //52系列單片機(jī)頭文件
#include <intrins.h> //包含_nop_()函數(shù)所在的頭文件
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6; //聲明U1鎖存器的鎖存端
sbit wela=P2^7; //聲明U2鎖存器的鎖存端
//IO口定義
sbit adwr=P3^6; //定義A/D的WR端口
sbit adrd=P3^7; //定義A/D的RD端口
//數(shù)碼管編碼
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delayms(uint xms) //延時(shí)函數(shù)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void display(uchar bai,uchar shi,uchar ge) //顯示子函數(shù)
{
//顯示百位
dula=1;
P0=table[bai]; //送段選數(shù)據(jù)
dula=0;
P0=0xff; //送位選數(shù)據(jù)前關(guān)閉所有顯示,防止打開位選鎖存時(shí)原來段選數(shù)據(jù)通過鎖存器造成混亂
wela=1;
/*將U2鎖存器的輸出口的最高位置低電平,目的是將與之相連的ADC0804的CS片選端置低選中。
一次選中,以后再不用管它。以后凡是操作U2鎖存器的地方都不要再改變A/D的CS端*/
P0=0x7e; //在數(shù)碼管顯示程序中,送出位選信號時(shí),始終保持U2鎖存器的最高位為低電平。位選第一個(gè)數(shù)碼管0111 1110
wela=0;
delayms(5);
//顯示十位/
dula=1;
P0=table[shi]; //送段選數(shù)據(jù)
dula=0;
P0=0xff;
wela=1;
P0=0x7d; //位選第二個(gè)數(shù)碼管 0111 1101
wela=0;
delayms(5);
//顯示個(gè)位
dula=1;
P0=table[ge]; //送段選數(shù)據(jù)
dula=0;
P0=0xfe;
wela=1;
P0=0x7b; //位選第三個(gè)數(shù)碼管 0111 1011
wela=0;
delayms(5);
}
void main() // 主程序
{
uchar a,A1,A2,A3,adval; //百十個(gè),A/D value
wela=1;
P0=0x7f; //置CSAD為0,選通ADCS,以后不必再管ADCS
wela=0;
while(1)
{
adwr=1; //寫信號輸入
_nop_(); //_nop_()函數(shù),延時(shí)一個(gè)機(jī)器周期
adwr=0; //低電平,啟動(dòng)AD轉(zhuǎn)換
_nop_();
adwr=1;
//立即先送結(jié)果給數(shù)碼管顯示,給A/D轉(zhuǎn)換留有一定時(shí)間
for(a=20;a>0;a--) //TX-1C實(shí)驗(yàn)板A/D工作頻率較低,所以啟動(dòng)轉(zhuǎn)換后要多留點(diǎn)時(shí)間用來轉(zhuǎn)換
{ //把顯示部分放這里的原因也是為了延長轉(zhuǎn)換時(shí)間(增加寫讀之間的時(shí)間間隔)
display(A1,A2,A3);
}
P1=0xff; //讀取P1口之前先給其寫全1
adrd=1; //選通ADCS
_nop_(); //延時(shí)一個(gè)機(jī)器周期
adrd=0; // A/D讀使能
_nop_();
adval=P1; // A/D數(shù)據(jù)讀取賦給P1口
adrd=1;
A1=adval/100; //分出百,十,和個(gè)位
A2=adval%100/10;
A3=adval%10;
}
}
/*
1、首次上電會(huì)看到顯示全是0,但馬上又出現(xiàn)數(shù)字:首次顯示完后,接下來便讀取到了A/D轉(zhuǎn)換后的結(jié)果,
當(dāng)程序再次循環(huán)回來時(shí),便顯示了上次的數(shù)值。
2、擰動(dòng)電位器,數(shù)碼管上數(shù)字始終不動(dòng),只有復(fù)位一次,或者重新上電一次,數(shù)字才會(huì)刷新:因?yàn)檗D(zhuǎn)換時(shí)間不夠。
兩種解決辦法:一是將實(shí)驗(yàn)板上C11電容換成150pF;
二是再適當(dāng)延長A/D轉(zhuǎn)換時(shí)間,即增加數(shù)碼管顯示的次數(shù),可將上例for(a=10;a>0;a--)中的a值增大。
*/
| 歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |