久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3854|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

從寫ADC0804程序中發(fā)現(xiàn)的一個關(guān)于數(shù)碼管動態(tài)掃描的問題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:70976 發(fā)表于 2014-12-27 14:51 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
以前我寫過一個電子時鐘程序,動態(tài)掃描里面使用了這樣的代碼序列:
P2 = 0xff;     // 先關(guān)閉所有數(shù)碼管
P2 = dis_digit;     // | LEDMASK;   
P0 = dis_buf[dis_index];   // 從第0個數(shù)碼管開始,即最左邊開始

由于每個數(shù)碼管都有數(shù)字要顯示,沒發(fā)現(xiàn)有什么問題.
但是今天寫ADC0804程序時應(yīng)用這個動態(tài)掃描函數(shù)卻發(fā)現(xiàn)了一點問題,
那就是我不想顯示的數(shù)碼管一直都顯示著一個模糊的數(shù)字,并且跟它往前相鄰的數(shù)字一樣.
猜測和調(diào)試了很久,最后才發(fā)現(xiàn)問題出在代碼的執(zhí)行順序上.
正確的代碼執(zhí)行序列應(yīng)該是關(guān)燈后立刻把內(nèi)容準備好,再開燈,這樣才能沒有副作用.
所以對P0的賦值要夾在對P2的兩次賦值之間.

PS:
電子時鐘.c
/*邏輯已經(jīng)修改清晰,使用時分秒三個變量獨立處理,并配有相應(yīng)函數(shù)*/

#include <reg51.h>
#include <intrins.h>
#define PUSH(Key)  !Key   //XL600都是按下為低電平的,高電平時作為輸入
#define LEDMASK   0x24   //00100100  ---  1的地方不亮
#define MIDDLINE  10
#define BALCK   11
#define ISKEY(pos)  (key & (1 << pos))      //檢測是第幾個按鍵,從0開始起
sbit KeyPP  = P3 ^ 2;       //Key Play and Pause
sbit KeyHourAdd = P3 ^ 3;       //Key Hour Add
sbit KeyMinAdd = P3 ^ 4;       //Key Min Add
//sbit KEYSET  = P3 ^ 5;
enum { KEYPP = 0, KEYHOURADD = 1, KEYMINADD = 2, KEYSET = 3};
unsigned char code Led7Tab[12] = { 0x28, 0x7E, 0xA2, 0x62, 0x74, //0 1 2 3 4
        0x61, 0x21, 0x7A, 0x20, 0x60,       //5 6 7 8 9
        0xF7,    //中間短橫線    MIDDLINE
        0xFF};    //不顯示,全黑   BALCK
unsigned char dis_buf[8], hour, min, sec, start;
void clr_time();
void timetick();  
void    UpdateTime();      
void delayms(unsigned char ms);
void proc_key(unsigned char key);   
void PART2LED(unsigned char part, unsigned char pos);   
void ToThenCarry(unsigned char *src, unsigned char top, unsigned char *dest);
unsigned char scan_key();

void main(void)
{
P0 = 0xff;
P2 = 0xff;
TMOD = 0x01;        
TH0 = 0xFC;
TL0 = 0x17;
IE = 0x82;  
TR0 = 1;
clr_time();                                
while(1)
{
  unsigned char key;
  if(scan_key() != 0)
  {
   delayms(10);
   if((key = scan_key()) != 0)
   {                           
    while(scan_key() != 0)
        ;
    proc_key(key);
   }
  }
  else if(start)
  {
      timetick();
  }
}                                                      
}
unsigned char scan_key()
{
unsigned char key = 0, keyPos;         //由于按鍵類型是sbit,不可以成為<<運算符的左值,
                                               //故將其裝換為新的unsigned char變量,然后移位
key |= (keyPos= ~KeyPP) << 0;         
key |= (keyPos= ~KeyHourAdd) << 1;   
key |= (keyPos= ~KeyMinAdd) << 2;      
//這里就可以擴展以后的按鍵了
return (key);
}                                       

void proc_key(unsigned char key)
{
if(ISKEY(KEYPP))
{
     start = !start;
}
else if(ISKEY(KEYHOURADD))
{
     ++hour;
     if(hour == 24)
  hour = 0;
     UpdateTime();
}
        else if(ISKEY(KEYMINADD))
{
     ++min;
     if(min == 60)
  min = 0;
     UpdateTime();
}                                                   
}                                                
void clr_time()         //全部清零
{
    hour = min = sec = 0;
    dis_buf[2] = dis_buf[5] = Led7Tab[MIDDLINE];
    UpdateTime();
}
void UpdateTime()
{
    PART2LED(hour, 1);
    PART2LED(min,  4);
    PART2LED(sec,  7);
}
void PART2LED(unsigned char part, unsigned char pos)
{
    dis_buf[pos] = Led7Tab[part % 10];
    dis_buf[pos - 1] = Led7Tab[(part / 10)];
}
void ToThenCarry(unsigned char *src, unsigned char top, unsigned char *dest)
{
    if(*src >= top)
    {
*src = 0;
++(*dest);
    }
}
void timetick()      
{

    delayms(255);
    ++sec;
    ToThenCarry(&sec, 60, &min);
    ToThenCarry(&min, 60, &hour);
    if(hour == 24)
    {
clr_time();
    }
    UpdateTime();
    dis_buf[2] = dis_buf[5] ^= 0x08;      //技巧:F7 -- FF 互變,用 00001000 異或即可
}

void Display() interrupt 1       //動態(tài)掃描顯示數(shù)碼管,放在中斷里就是最好的方案,搞得我想了半天其它方法
{
        static unsigned char data dis_digit = 0xFE;     // P2的二進制掩碼選通第幾個數(shù)碼管,從0位即最左邊掃描起
static unsigned char dis_index     = 0;  //   邏輯第幾個數(shù)碼管
TH0 = 0xFC;
TL0 = 0x17;

P2 = 0xff;     // 先關(guān)閉所有數(shù)碼管
P0 = dis_buf[dis_index];   // 從第0個數(shù)碼管開始,即最左邊開始
       //  P0的賦值要夾在這中間,也就是緊跟在燈全滅之后,
       //  否則,它會模糊地顯示上一個數(shù)字,即它之前的那個數(shù)字,
       //  這個bug直到今天寫ADC0804程序才發(fā)現(xiàn).
       //   Apr. 4, 2009

P2 = dis_digit;   
dis_digit = _crol_(dis_digit, 1);  // 循環(huán)左移
dis_index++;   
dis_index &= 0x07;    // 技巧:    掩碼:0111,當1000時變成0  
}                                                         
void delayms(unsigned char ms)
{      
    unsigned int i;
    while(--ms)
    {
for ( i = 0; i < 320; i++)
     ;
    }
}

ADC0804.c
#include "..\mcu.h"
#define ADCDATA P1
sbit ADC0804_WR = P3 ^ 6;
sbit ADC0804_RD = P3 ^ 7;
unsigned char dis_buf[8];
void Number2Led(unsigned char number);
void ClearDisplay(void);

void main(void)
{
    unsigned char value;

    TMOD = 0x02;
    TH0 = 0xF0;
    TL0 = 0xF0;
    IE = 0x82;  
    TR0 = 1;         
    ADCDATA = 0xFF;
    ClearDisplay();
    while(1)
    {
ADC0804_WR = 0;
ADC0804_WR = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ADC0804_RD = 1;
ADC0804_RD = 0;
value = ADCDATA;
value = ~value;
Number2Led(value);
    }
}
void Number2Led(unsigned char number)
{
    unsigned char i, j;
    i = 7;
    while(1)
    {
dis_buf = LED7TAB[number % 10];
if(number > 10)
{
     number /= 10;
}
else
{
     break;
}
    }
    for(j = 1; j <= i; j++)
    {
dis_buf[j] = 0xFF;
    }
}

void Display() interrupt 1       //動態(tài)掃描顯示數(shù)碼管,放在中斷里就是最好的方案,搞得我想了半天其它方法
{
        static unsigned char dis_digit     = 0xFE;     // P2的二進制掩碼選通第幾個數(shù)碼管,從0位即最左邊掃描起
static unsigned char dis_index     = 0;  //   邏輯第幾個數(shù)碼管
P2 = 0xff;     // 先關(guān)閉所有數(shù)碼管
P0 = dis_buf[dis_index];   // 從第0個數(shù)碼管開始,即最左邊開始
P2 = dis_digit;     // | LEDMASK;   

dis_digit = _crol_(dis_digit, 1);  // 循環(huán)左移
dis_index++;   
dis_index &= 0x07;    // 技巧:    掩碼:0111,當1000時變成0  
}                                                                                                        
void ClearDisplay(void)
{
    unsigned char index;
    for(index = 0; index < 8; index++)
    {
dis_buf[index] = 0xFF;
    }
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 51ⅴ精品国产91久久久久久 | 成人在线电影在线观看 | 天天干天天爱天天 | 天天拍天天插 | 天天色天天色 | 久久精品中文 | 九九亚洲精品 | 成人免费毛片在线观看 | 中文一区二区视频 | 国产91成人 | 日本人做爰大片免费观看一老师 | 亚洲三区在线观看 | 一区视频在线 | 天天操天天怕 | 精品国产18久久久久久二百 | 久久一区二区av | 你懂的av| 国产一级一级国产 | 欧美日韩中文在线 | 久久精品91久久久久久再现 | 国产精品黄 | 国产ts人妖系列高潮 | 久久精品久久久 | 日韩一区二 | 亚洲 中文 欧美 | 久久久久一区 | 欧美一级淫片免费视频黄 | 欧美精品99 | 日韩av一区二区在线观看 | eeuss国产一区二区三区四区 | 天天躁天天操 | 久久成人一区 | 色婷婷国产精品 | 免费网站在线 | 日韩成人免费av | 香蕉大人久久国产成人av | 中文字幕在线观看精品 | 亚洲黄色一级毛片 | 国产在线播放av | 亚洲成人一区二区 | 国产精品日韩 |