我的單片機程序功能是在數(shù)碼管顯示計數(shù)的同時,在外部中斷0的端口加了一個按鍵,當按鍵按下時,實行外部中斷函數(shù),數(shù)碼管顯示光敏電阻電壓值。
遇到問題:當按鍵按下時,數(shù)碼管不變化,沒有顯示電壓值。
仿真圖+程序見下圖:
QQ截圖20180614184037.jpg (369.82 KB, 下載次數(shù): 47)
下載附件
仿真圖
2018-6-14 18:41 上傳
- #include<reg51.h>
- #include<absacc.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- /*********************************端口定義**********************************/
- sbit CS = P3^5;
- sbit Clk = P3^4;
- sbit DATI = P3^3;
- sbit DATO = P3^3;
- sbit KEY1 = P3^2;
- /*******************************定義全局變量********************************/
- unsigned char dat = 0x00; //AD值 .
- //若dat=adc0832(CH)*500.0/255; 不可用unsigned char dat
- //500不可以。用500.0
- //如 下面unsigned int disdat; 不可unsigned char disdat
- unsigned char CH; //通道變量
- unsigned int dis[] = {0x00, 0x00, 0x00}; //顯示數(shù)值
- uchar code dispcode[ ]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; /*七段共陰管顯示定義*/
- char code tablewe[]={ 0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; /*七段共陰管位選顯示定義*/
- uchar seconde=0; /*定義并初始化變量*/
- uchar minite=0;
- uchar hour=0;
- uchar a=0;
- uint mstcnt=0;
- /*函數(shù)聲明*/
- void delay(uchar k ); //延時子程序
- void time_pro( ); //時間處理子程序
- void display( ); //顯示子程序
- void led_display( ); //led閃爍程序
- void convdata( ) ; //電壓計算數(shù)據(jù)程序
- void display_key1(void); //數(shù)碼管顯示數(shù)據(jù)程序,中斷進行
- /*****************************************/
- /*************AD轉(zhuǎn)換子程序****************/
- /*****************************************/
- unsigned char adc0832(unsigned char CH)
- {
- unsigned char i,test,adval;
- adval = 0x00;
- test = 0x00;
- Clk = 0; //初始化
- CS=1;
- DATI = 1;
- CS = 0;
- _nop_();
- Clk = 1;
- _nop_();
- if ( CH == 0x00 ) //通道選擇
- {
- Clk = 0; //寫入10,選單極性0通道
- DATI = 1; //通道0的第一位
- _nop_(); //clk上升沿寫進去
- Clk = 1;
- _nop_();
- Clk = 0;
- DATI = 0; //通道0的第二位
- _nop_();
- Clk = 1;
- _nop_();
- }
- else
- { //寫入11,選單極性1通道
- Clk = 0;
- DATI = 1; //通道1的第一位
- _nop_(); //clk上升沿寫進去
- Clk = 1;
- _nop_();
- Clk = 0;
- DATI = 1; //通道1的第二位
- _nop_();
- Clk = 1;
- _nop_();
- }
- Clk = 0; //寫進空閑位 //clk上升沿寫進去
- DATI = 1;
- _nop_();
- Clk = 1;
- _nop_();
- //讀取前8位的值
- for( i = 0;i < 8;i++ ) //讀取前8位的值
- { //clk下升沿讀出來
- _nop_(); //高位先行
- adval <<= 1;
- Clk = 1;
- _nop_();
- Clk = 0;
- if (DATO)
- adval |= 0x01;
- //else
- // adval |= 0x00;
- }
- for (i = 0; i < 8; i++) //讀取后8位的值
- { //clk下升沿讀出來
- test >>= 1; //低位先行,時序圖上
- if (DATO)
- test |= 0x80;
- //else
- //test |= 0x00;
- _nop_();
- Clk = 1;
- _nop_();
- Clk = 0;
- }
- if (adval == test) //比較前8位與后8位的值,如果不相同舍去。
- dat = adval; //若一直出現(xiàn)顯示為零,請將該行去掉
- _nop_();
- CS = 1; //釋放ADC0832,關(guān)閉
- DATO = 1;
- Clk = 1;
- return dat;
- }
- /**************************************************/
- /*****將0-255級換算成0.00-5.00的電壓數(shù)值***********/
- /**************************************************/
- void convdata(unsigned char i) //i=dat*5/255=51,是255份; 256份誤差大
- {
- unsigned int disdat; //不可unsigned char disdat
- disdat=i*500.0/255; //500不可以。用500.0
- /* 驗證讀數(shù)
- dis[0] = i/100; //個位
- dis[1] = i/10%10; //小數(shù)點后第一位
- dis[2] = i%10; //小數(shù)點后第二位 */
-
- dis[0] = disdat/100; //個位
- dis[1] = disdat/10%10; //小數(shù)點后第一位
- dis[2] = disdat%10; //小數(shù)點后第二位
- }
- /*****************************************/
- /*****數(shù)碼管顯示光敏電阻電壓程序**********/
- /*****************************************/
- void display_key1(void)
- {
- P1=0xfe;
- P0= dispcode[dis[0]] + 0x80; //顯示個位和小數(shù)點
- delay(5);
- P1=0xfd;
- P0=dispcode[dis[1]]; //顯示小數(shù)點后第一位
- delay(5);
- P1=0xfb;
- P0=dispcode[dis[2]]; //顯示小數(shù)點后第二位
- delay(5);
- }
- /*****************************/
- /*led燈閃爍程序*/
- /****************************/
- void led_display(void)
- {
- delay(50); //led燈閃爍三次后熄滅
- P2=0x07; //賦初始值
- delay(50);
- P2=0x00;
- delay(50);
- P2=0x07;
- delay(50);
- P2=0x00;
- delay(50);
- P2=0x07;
- delay(50);
- P2=0x00;
- }
- /*****************************/
- /*延時子程序*/
- /****************************/
- void delay (uchar k)
- {
- uchar j;
- while((k--)!=0)
- {
- for(j=0;j<125;j++)
- {;}
- }
- }
- /**************************/
- /*時間處理子程序*/
- /**************************/
- void time_pro( void)
- {
- if(seconde==60) //秒鐘設(shè)為60進制
- {
- seconde=0;
- minite++;
- if(minite==60) //分鐘設(shè)為60進制
- {
- minite=0;
- hour++;
- if(hour==24) //時鐘設(shè)為24進制
- {
- hour=0;
- }
- }
- }
- }
- /*****************************/
- /* 顯示子程序*/
- /*****************************/
- void display()
- {
- static uchar i=0;
- P0=0x00; //消隱
- switch(i)
- {
- case 0: P1=0xfe;
- P0=dispcode[hour/10];//顯示小時的十位
- i++;
- break;
- case 1: P1=0xfd;
- P0=(dispcode[(hour%10)])|0X80;//顯示小時的個位
- i++;
- break;
- case 2: P1=0xfb;
- P0=dispcode[minite/10];//顯示分的十位
- i++;
- break;
- case 3: P1=0xf7;
- P0=(dispcode[minite%10])|0X80;//顯示分的個位
- i++;
- break;
- case 4: P1=0xef;
- P0=dispcode[seconde/10];//顯示秒的十位
- i++;
- break;
- case 5: P1=0xdf;
- P0=dispcode[seconde%10];//顯示秒的個位
- i=0;
- break;
- }
- }
- /**************************/
- /*主函數(shù)*/
- /**************************/
- void main(void)
- {
- P1=0xff; //初始化p1口,全設(shè)為1
- TMOD=0x01; //time0為定時器,方式1
- TH0=0xfc; //預(yù)置計數(shù)初值1ms
- TL0=0x18;
- EA=1;
- ET0=1;
- TR0=1;
- while (1)
- {
- if(a==0)
- {
- led_display( ); //led燈閃爍
- time_pro( ); //時間處理
- }
- else
- display_key1();
- }
- }
- /*****兩個中斷程序,一個計數(shù)器T0中斷,一個外部INT0中斷*****/
- /**********************************************************/
- /* 中斷服務(wù)程序?qū)崿F(xiàn)數(shù)碼管的定時顯示 計數(shù)器中斷 */
- /**********************************************************/
- void timer0(void) interrupt 1 using 0 //定時器0方式1,16位計數(shù)器,50ms中斷一次
- {
- PT0=0; //設(shè)置為低級中斷
- TH0=0xfc; //重置計數(shù)初值1ms
- TL0=0x18;
- mstcnt++;
- if(mstcnt>=1000)
- {
- seconde++;
- mstcnt=0;
- }
- display( ); //顯示時間T1高級中斷
- a=0;
- }
- /**********************************************************/
- /* 外部中斷————實現(xiàn)按鍵按下時電壓顯示 */
- /**********************************************************/
- void int0(void) interrupt 0
- {
- PX0=1; //設(shè)置為高級中斷
- CH = 0x00; //在這里選擇通道 0x00(單極性0通道)或0x01(單極性1通道)
- if (KEY1 == 0)
- {
- a++;
- P1=0x00; //端口初始化
- P0=0xff;
- dat = adc0832(CH);
- convdata(dat); //數(shù)據(jù)轉(zhuǎn)換
- // display_key1(); //顯示數(shù)值INT0高級中斷,符合設(shè)計要求
- }
- }
復(fù)制代碼
|