Exibição dinâmica de tubo digital de 4 dígitos no modo de interrupção do relógio arduino

    Geralmente, exibimos números na placa de desenvolvimento arduino e geralmente usamos tubos digitais de vários dígitos para exibir, mas os tubos digitais de vários dígitos realmente usam o método de "exibição de varredura dinâmica" para exibir, ou seja, o primeiro tubo digital e o segundo tubo digital é exibido em sequência. tubo, o terceiro tubo digital, o quarto tubo digital... Este método é usar o resíduo visual do olho humano. Quando a frequência de exibição da varredura for superior a 25 quadros por segundo, o que vemos é que cada tubo digital é exibido ao mesmo tempo. Atualmente, a maioria dos programas de exemplo do arduino são exibidos continuamente no loop principal, mas há um grande problema com essa abordagem. Se um loop no loop principal precisar ser executado por um longo período de tempo (mais de 40 ms), a frequência de exibição será inferior a 25 quadros por segundo, portanto, a exibição exibida ficará instável e até mesmo o conteúdo estará pulando.

    Para garantir que a frequência de exibição seja maior que 25 quadros por segundo, podemos usar a interrupção do relógio do arduino para executar a "exibição de varredura dinâmica". Em primeiro lugar, é necessário definir um intervalo de interrupção de relógio apropriado, cada interrupção exibe um tubo digital e o requisito mínimo de exibição de 25 quadros por segundo, o intervalo de tempo de interrupção deve ser inferior a 10ms (1000ms/4/25), para melhorar a qualidade da exibição, este programa usa O intervalo de interrupção é de 5ms.

    Este experimento usa arduino UNO, e o tubo digital de 4 dígitos usado é um cátodo comum 3641AS. A seguir está o diagrama de pinos do tubo:

    (Carreguei a foto por meia hora e ainda não está terminada, por favor, vá online para encontrar o diagrama de pinos do tubo)

   Para a conveniência da fiação, conecte os pinos 1 a 12 de 3641AS a D2 a D13 do arduino. O diagrama de fiação real é o seguinte:

    (Fiz upload da foto por meia hora e ainda não terminei. Você só precisa conectar os pinos 1 a 12 do 3641AS às 12 portas IO D2 a D13 do arduino UNO)

    O programa completo (que foi testado) é o seguinte:

#include<MsTimer2.h> //chama o arquivo de biblioteca do timer T2

/*

  Usando o método de interrupção do relógio, o tubo digital de 4 dígitos exibe dinamicamente o programa 0-9999

  Vantagem: a função de atraso pode ser usada arbitrariamente no loop principal

  

  A porta aciona diretamente o tubo digital de cátodo comum de 4 bits e geralmente não é necessário nenhum resistor limitador de corrente externo.

  Como a corrente de saída da porta é limitada, geralmente não superior a 20 mA, é recomendável adicionar um resistor limitador de corrente para uso prolongado.

*/

int ledCount=8;//tubo digital de 8 segmentos

int segCount=4;//4 tubo digital

//long anteriorMillis = 0;

//Defina o código do segmento, aqui está o código do segmento negativo comum, você pode usar o software de código do segmento de tubo digital para alterar o valor da matriz ou exibir qualquer forma

const unsigned char dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

// código de bits

//carac não assinado const dofly_WeiMa[]={0,1,2,3};

int ledPins[] = {

  12,8,5, 3, 2, 11, 6, 4, }; // 11,7,4,2,1,10,5,3 O número real de pinos do tubo digital, o mesmo que o chip , contando no sentido anti-horário

int segPins[] = {

  13,10,9,7}; //12,9,8,6 O número real de pinos do tubo digital, o mesmo que o chip, no sentido anti-horário

unsigned char displayTemp[4];//display buffer, store segment code

void setup() {

// Configurações de loop, defina as portas correspondentes como saída

  for (int thisLed = 0; thisLed < ledCount; thisLed++) {

    pinMode(ledPins[thisLed], OUTPUT); }

  for (int thisSeg = 0; thisSeg < segCount; thisSeg++) {

    pinMode(segPins[thisSeg], OUTPUT);

  }

  MsTimer2::set(5, Timedisp); //Define Timedisp como uma sub-rotina chamada pela interrupção do relógio e aciona a interrupção do relógio a cada 5ms para entrar na função Timedisp

  MsTimer2::start(); //Inicia a interrupção do clock

}

// Processamento de dados, escreva os dados do byte a serem processados ​​na porta do pino correspondente.

void deal(valor char não assinado){

  for(int i=0;i<8;i++)

    digitalWrite(ledPins[i],bitRead(value,i));//use a função bitWrite, bem simples

    // !bitRead(value,i), adiciona aqui na frente! (símbolo não operacional), dependendo se o tubo digital de cátodo comum ou ânodo comum é usado.

}

// O programa de exibição chamado pela interrupção do relógio

//A cada interrupção, exibe um valor de código de segmento em displayTemp[0]—displayTemp[3] uma vez

void Timedisp() {

  int estático i;

  deal(0);// Limpa o "fantasma"

  for(int a=0;a<segCount;a++) //Ciclo de código de bit de gravação, apenas um tubo digital é ativado a qualquer momento, todos eles são fechados antes e, em seguida, o tubo digital necessário é bloqueado

    digitalWrite(segPins[a],1);//Fecha todos os tubos digitais

  digitalWrite(segPins[i],0);//Selecione o tubo digital correspondente

  deal(displayTemp[i]);//Lê o valor do código do segmento correspondente e grava no tubo digital correspondente

  i++;

  if(i==segCount) //reciclar após 4 dígitos

    i=0;

}

//Exibe programa, exibe num em 4 dígitos, num é menor que 10000

void disp(num longo sem sinal) {

  num=num%10000;//operação de módulo para evitar que num exceda 9999

  displayTemp[0]=dofly_DuanMa[num/1000]; //Envia o valor do código de segmento de um dígito de num para exibir o buffer displayTemp[0]

  displayTemp[1]=dofly_DuanMa[(num%1000)/100]; //Envia o valor do código de segmento de dez dígitos de num para exibir o buffer displayTemp[1]

  displayTemp[2]=dofly_DuanMa[((num%1000)%100)/10]; //Envia o valor do código de segmento de centenas de dígitos de num para o buffer de exibição displayTemp[2]

  displayTemp[3]=dofly_DuanMa[((num%1000)%100)%10]; //Envia o valor do código de segmento de milhares de dígitos de num para o buffer de exibição displayTemp[3]

}

//laço principal

loop void() {

    static unsigned int num;//Define um dado

    disp(número);

    num++;

    delay(100); //Atraso 100ms

}

Acho que você gosta

Origin blog.csdn.net/m0_61543203/article/details/126129038
Recomendado
Clasificación