去掉鬼影和數字變換抖動的定時器c++
數碼管會有兩個現象,ide
一、不顯示的段有熒光,俗稱鬼影函數
緣由,38譯碼器切換的時候,因爲運行速度太快,上一條指令的瞬時值未消除產生的。
spa
解決方法:在數碼管顯示值前,清0
it
二、數碼管變化的時候,其它抖動class
緣由:程序在計算的時候浪費了時間,數碼管刷新不是以1毫秒進行的,時間長數碼管顯示拉動。
定時器
解決方法:使用中斷優先級程序
EA:啓動中斷方法
ET0:打開定時器中斷im
中斷函數的說明:
void InterruptTimer0() interrupt 1
interrupt:中斷函數,
1:中斷函數的編號。
中斷函數的編號x, 計算方法,x*8+3 = 中斷向量地址、
#include <reg52.h> /*38譯碼器選位輸入*/ sbit ADDR0 = P2^5; sbit ADDR1 = P2^6; sbit ADDR2 = P2^7; unsigned int conter; unsigned char l; /*數碼管真值表*/ unsigned char led_display[16] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71}; /*存儲LED變化時的值*/ unsigned char led_buffer[10] = {0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00}; unsigned char vector_38[8] = {0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0}; void main() { unsigned int sec; /*打開定時器*/ TR0 = 1; TMOD = 0x01; /*打開中斷*/ EA = 1; ET0 = 1; TH0 = 0xFC; //1us TL0 = 0x67; conter = 0; /*賦初值*/ while(1) { if (conter >= 1000) { /*更改數碼管*/ sec++; conter = 0; led_buffer[7] = led_display[sec%10]; led_buffer[6] = led_display[sec/10%10]; led_buffer[5] = led_display[sec/100%10]; led_buffer[4] = led_display[sec/1000%10]; led_buffer[3] = led_display[sec/10000%10]; led_buffer[2] = led_display[sec/100000%10]; led_buffer[1] = led_display[sec/1000000%10]; led_buffer[0] = led_display[sec/10000000%10]; } } } void InterruptTimer0() interrupt 1 { TH0 = 0xFC; //1us TL0 = 0x67; conter++; P0 = 0x00; if (l == 0) {ADDR0 = 0;ADDR1 = 0;ADDR2 = 0;l++;P1=led_buffer[0];} else if (l == 1) {ADDR0 = 1;ADDR1 = 0;ADDR2 = 0;l++;P1=led_buffer[1];} else if (l == 2) {ADDR0 = 0;ADDR1 = 1;ADDR2 = 0;l++;P1=led_buffer[2];} else if (l == 3) {ADDR0 = 1;ADDR1 = 1;ADDR2 = 0;l++;P1=led_buffer[3];} else if (l == 4) {ADDR0 = 0;ADDR1 = 0;ADDR2 = 1;l++;P1=led_buffer[4];} else if (l == 5) {ADDR0 = 1;ADDR1 = 0;ADDR2 = 1;l++;P1=led_buffer[5];} else if (l == 6) {ADDR0 = 0;ADDR1 = 1;ADDR2 = 1;l++;P1=led_buffer[6];} else if (l == 7) {ADDR0 = 1;ADDR1 = 1;ADDR2 = 1;l++;P1=led_buffer[7];} if (l>7){l=0;} }