1

私は 2 つの回路を持っています。どちらもデュアル 7 セグメント ディスプレイと A pic16f684 (以下に示すように) で構成されており、最初の回路は供給されたコードを使用して乱数 1 ~ 26 を生成します。文字部分は同じ回路ですが、片方のトランジスタを外して片方を無効にしています。 回路

/*
 * File:   main.c
 * Original Code Creator: dan1138
 * Target: PIC16F684
 * Compiler: XC8 v2.20
 * IDE: MPLABX v5.25
 * 
 * Description:
 *
 * Created on July 21, 2020, 3:45 PM
 * 
 *                            PIC16F684
 *                  +------------:_:------------+
 *         GND -> 1 : VDD                   VSS : 14 <- 5v0
 * SEG_a_DRIVE <> 2 : RA5/T1CKI     PGD/AN0/RA0 : 13 <> DIGIT_DRIVE_2
 *         SW2 <> 3 : RA4/AN3       PGC/AN1/RA1 : 12 <> DIGIT_DRIVE_1
 *         SW1 -> 4 : RA3/VPP           AN2/RA2 : 11 <> 
 * SEG_b_DRIVE <> 5 : RC5/CPP1          AN4/RC0 : 10 <> SEG_g_DRIVE
 * SEG_c_DRIVE <> 6 : RC4/C2OUT         AN5/RC1 : 9  <> SEG_f_DRIVE
 * SEG_d_DRIVE <> 7 : RC3/AN7           AN6 RC2 : 8  <> SEG_e_DRIVE
 *                  +---------------------------:
 *                             DIP-14
 */

// CONFIG --- Configuration Word --- START
#pragma config FOSC = INTOSCIO
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF
// CONFIG --- Configuration Word --- END

#include <xc.h>
#include <stdlib.h>

/* Oscillator frequency we will select with the OSCCON register */
#define _XTAL_FREQ (4000000ul)
/*
 * Segment locations
 * of an LED display
 *      ---a---
 *     :       :
 *     f       b
 *     :       :
 *      ---g---
 *     :       :
 *     e       c
 *     :       :
 *      ---d---
 */
const unsigned char LEDDigit[] = {
//     abcdefg, Segment on = 0
    0b00000001, // "0"
    0b01001111, // "1"
    0b00010010, // "2"
    0b00000110, // "3"
    0b01001100, // "4"
    0b00100100, // "5"
    0b00100000, // "6"
    0b00001111, // "7"
    0b00000000, // "8"
    0b00001100, // "9"
    0b00001000, // "A"
    0b01100000, // "b"
    0b00110001, // "C"
    0b01000010, // "d"
    0b00110000, // "E"
    0b00111000  // "F"  
}; 



void main(void) 
{
    unsigned char DisplayValue, DisplayLED, DigitSegments;
    unsigned char LoopCount;
    unsigned int  Temp;
    
    PORTA = 0;
    PORTC = 0;
    CMCON0 = 7;                 // Turn off Comparators 
    ANSEL = 0;                  // Turn off ADC 
    
    __delay_ms(500);            // wait for ICD before making PGC and PGD outputs;
    TRISA = 0b011100;           // RA5, RA1, RA0 are outputs
    TRISC = 0b000000; 
    OPTION_REGbits.nRAPU = 0;   // Enable weak pull-up on PORTA
    WPUA = 0;                   // Turn off all pull-ups
    WPUAbits.WPUA4 = 1;         // Turn on RA4 pull-up
    
         
    DisplayValue = 0;           // Start Displaying at 0x00 
    DisplayLED = 0;             // Display the 1s first
    LoopCount = 0;
    srand(0x1234);
    
    for(;;)
    {
        PORTC = 0xFF;   // turn off all segment drivers
        PORTA = 0xFF;   // and digit drivers
        if (1 == (DisplayLED & 1))
        {
            DigitSegments = LEDDigit[(DisplayValue >> 4) & 0x0F];
            if(DigitSegments & 0b1000000)
                          {
                PORTA = 0b111110;   // turn on Digit driver 2
            } 
            else 
            {
                PORTA = 0b011110;   // turn on Digit driver 2 and SEG_a_DRIVER
            }
        }
        else
        {
            DigitSegments = LEDDigit[DisplayValue & 0x0F];
            if(DigitSegments & 0b1000000)
            {
                PORTA = 0b111101;   // turn on Digit driver 1
            } 
            else 
            {
                PORTA = 0b011101;   // turn on Digit driver 1 and SEG_a_DRIVER
            }
        }
        PORTC = DigitSegments;      // turn on segment drivers b to g
        DisplayLED++;               // select next digit

        __delay_ms(10);             // Show digit for 10 milliseconds
        
        if(0 == PORTAbits.RA3)      // is SW1 pressed?
        {
            LoopCount++;
            if(LoopCount == 1)
            {
                 // Display a new random value every 500 milliseconds
                Temp = rand() & 0xFFu;      // put random value in range of 0 to 255 and treat is as a fraction in range (0/256) <= value < (255/256)
                Temp = (Temp * 26u + 0x100u) >> 8; // Use tricky math to make a random number in the range from 1 to 56
                DisplayValue = (Temp / 10u) << 4;  // Extract the ten's digit
                DisplayValue = DisplayValue | (Temp % 10); // Extract the one's digit
            }
            if(LoopCount >= 50)
            {
                LoopCount = 0;
            }
        }
        else
        {
            LoopCount = 0;
        }

        if(0 == PORTAbits.RA4)      // is SW2 pressed?
        {
            DisplayValue = 0;       // Reset display value to zero
            LoopCount = 0;
        }
    }
}

私の目標は、変更されたアルファベットを使用して、2 番目の 7 セグメント ディスプレイに対応する文字を生成することです。ただし、これを行う方法がわかりません。私の当初の考えは、変更された LEDDigits[]; を使用して 2 番目の pic16f684 に温度値を出力することでした。

const unsigned char LEDDigit[] = {
//     abcdefg, Segment on = 0
    0b01111110, //"-"
    0b00001000, // "A"
    0b01100000, // "b"
    0b00110001, // "C"
    0b01000010, // "d"
    0b00110000, // "E"
    0b00111000, // "F"  
    0b00100001, // "G"
    0b01001000, // "H"
    0b01111001, // "I"
    0b01000011, // "J"
    0b00101000, // "Modified K"
    0b01110001, // "L"
    0b00010101, // "Modified M"
    0b01101010, // "n"
    0b01100010, // "o"
    0b00011000, // "P"
    0b00001100, // "q"
    0b01111010, // "r"
    0b00100100, // "S"
    0b01110000, // "t"
    0b01100011, // "u"
    0b01010101, // "Modified V"
    0b01000000, // "Modified W"
    0b00110110, // "Modified X"
    0b01000100, // "y"
    0b00010010 // "Z"
        
}; 

しかし、私はその数を出力できるとは信じていません。1 つのデュアル ディスプレイに数字 (1 ~ 26) を表示し、別のディスプレイに対応する文字を表示するにはどうすればよいですか。

2 番目の 7 セグメント ディスプレイを数値回路に追加し、そのトランジスタを RA2 に設定して、同時に文字を表示させることはできますか? これはどのように機能しますか?

4

1 に答える 1

1

さて、宿題の解決策は次のとおりです。

/*
 * File:   main.c
 * Author: dan1138
 * Target: PIC16F684
 * Compiler: XC8 v2.20
 * IDE: MPLABX v5.25
 * 
 * Description:
 * 
 * This code is the homework solution for Stack Overflow posts:
 *  https://stackoverflow.com/questions/63086495/random-number-generator-with-corresponding-letter
 *  https://stackoverflow.com/questions/63006839/pic16f684-dual-seven-seg-display-program-random-number-generator-in-c
 * 
 *
 * Created on July 21, 2020, 3:45 PM
 * 
 *                            PIC16F684
 *                  +------------:_:------------+
 *         GND -> 1 : VDD                   VSS : 14 <- 5v0
 * SEG_a_DRIVE <> 2 : RA5/T1CKI     PGD/AN0/RA0 : 13 <> DIGIT_DRIVE_2
 *         SW2 <> 3 : RA4/AN3       PGC/AN1/RA1 : 12 <> DIGIT_DRIVE_1
 *         SW1 -> 4 : RA3/VPP           AN2/RA2 : 11 <> DIGIT/ALPHAn mode
 * SEG_b_DRIVE <> 5 : RC5/CPP1          AN4/RC0 : 10 <> SEG_g_DRIVE
 * SEG_c_DRIVE <> 6 : RC4/C2OUT         AN5/RC1 : 9  <> SEG_f_DRIVE
 * SEG_d_DRIVE <> 7 : RC3/AN7           AN6 RC2 : 8  <> SEG_e_DRIVE
 *                  +---------------------------:
 *                             DIP-14
 */

// CONFIG --- Configuration Word --- START
#pragma config FOSC = INTOSCIO
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF
// CONFIG --- Configuration Word --- END

#include <xc.h>
#include <stdlib.h>

/* Oscillator frequency we will select with the OSCCON register */
#define _XTAL_FREQ (4000000ul)
/*
 * Segment locations
 * of an LED display
 *      ---a---
 *     :       :
 *     f       b
 *     :       :
 *      ---g---
 *     :       :
 *     e       c
 *     :       :
 *      ---d---
 */
const unsigned char LEDDigitSegs[] = {
//     abcdefg, Segment on = 0
    0b00000001, // "0"
    0b01001111, // "1"
    0b00010010, // "2"
    0b00000110, // "3"
    0b01001100, // "4"
    0b00100100, // "5"
    0b00100000, // "6"
    0b00001111, // "7"
    0b00000000, // "8"
    0b00001100, // "9"
    0b00001000, // "A"
    0b01100000, // "b"
    0b00110001, // "C"
    0b01000010, // "d"
    0b00110000, // "E"
    0b00111000  // "F"  
}; 

const unsigned char LEDAlphaSegs[] = {
//     abcdefg, Segment on = 0
    0b01111110, // "-"
    0b00001000, // "A"
    0b01100000, // "b"
    0b00110001, // "C"
    0b01000010, // "d"
    0b00110000, // "E"
    0b00111000, // "F"  
    0b00100001, // "G"
    0b01001000, // "H"
    0b01111001, // "I"
    0b01000011, // "J"
    0b00101000, // "Modified K"
    0b01110001, // "L"
    0b00010101, // "Modified M"
    0b01101010, // "n"
    0b01100010, // "o"
    0b00011000, // "P"
    0b00001100, // "q"
    0b01111010, // "r"
    0b00100100, // "S"
    0b01110000, // "t"
    0b01100011, // "u"
    0b01010101, // "Modified V"
    0b01000000, // "Modified W"
    0b00110110, // "Modified X"
    0b01000100, // "y"
    0b00010010  // "Z"
}; 

void main(void) 
{
    unsigned char Digit1_Segments, Digit2_Segments;
    unsigned char LoopCount;
    unsigned int  Temp;

    PORTA = 0xFF;
    PORTC = 0xFF;
    CMCON0 = 7;                 // Turn off Comparators 
    ANSEL = 0;                  // Turn off ADC 

    __delay_ms(500);            // wait for ICD before making PGC and PGD outputs;
    TRISA = 0b011111;           // RA5, RA1, RA0 are outputs
    TRISC = 0b000000; 
    OPTION_REGbits.nRAPU = 0;   // Enable weak pull-up on PORTA
    WPUA = 0;                   // Turn off all pull-ups
    WPUAbits.WPUA4 = 1;         // Turn on RA4 pull-up
    WPUAbits.WPUA2 = 1;         // Turn on RA2 pull-up

    Digit1_Segments = 0xFF;     // Turn off digit segments
    Digit2_Segments = 0xFF;     // Turn off digit segments
    LoopCount = 0;
    srand(0x1234);              // Seed the pseudo random number generator

    for(;;)
    {
        PORTC = 0xFF;   // turn off all segment drivers
        PORTA = 0xFF;   // and digit drivers
        if (TRISAbits.TRISA1 == 0)
        {
            TRISAbits.TRISA1 = 1;
            TRISAbits.TRISA0 = 1;
            if(0 == (Digit2_Segments & 0b1000000))
            {
                PORTA = 0b011110;   // turn on Digit driver 2 and SEG_a_DRIVER
            }
            else
            {
                PORTA = 0b111110;   // turn on Digit driver 2
            }
            PORTC = Digit2_Segments;      // turn on segment drivers b to g
            TRISAbits.TRISA0 = 0;;
        }
        else
        {
            TRISAbits.TRISA1 = 1;
            TRISAbits.TRISA0 = 1;
            if(0 == (Digit1_Segments & 0b1000000))
            {
                PORTA = 0b011101;   // turn on Digit driver 1 and SEG_a_DRIVER
            }
            else
            {
                PORTA = 0b111101;   // turn on Digit driver 1
            }
            PORTC = Digit1_Segments;      // turn on segment drivers b to g
            TRISAbits.TRISA1 = 0;;
        }

        __delay_ms(10);             // Show digit for 10 milliseconds

        if(0 == PORTAbits.RA3)      // is SW1 pressed?
        {
            LoopCount++;
            if(LoopCount == 1)
            {
                // Display a new random value every 500 milliseconds
                Temp = rand() & 0xFFu;      // put random value in range of 0 to 255 and treat is as a fraction in range (0/256) <= value < (255/256)
                if(0 == PORTAbits.RA2)      // Choose between alpha and digits mode
                {
                    // Show random character "A" to "Z" in digit 1, show dash "-" in digit 2
                    Temp = (Temp * 26u + 0x100u) >> 8; // Use tricky math to make a random number in the range from 1 to 26
                    Digit2_Segments = LEDAlphaSegs[0];    // Display a dash "-"
                    Digit1_Segments = LEDAlphaSegs[Temp]; // Display character segments (A-Z)
                }
                else
                {
                    // Show two digit random number from 1 to 56
                    Temp = (Temp * 56u + 0x100u) >> 8; // Use tricky math to make a random number in the range from 1 to 56
                    Digit2_Segments = LEDDigitSegs[(Temp / 10)]; // Display the ten's digit segments
                    Digit1_Segments = LEDDigitSegs[(Temp % 10)]; // Display the one's digit segments
                }
            }
            if(LoopCount >= 50)
            {
                LoopCount = 0;
            }
        }
        else
        {
            LoopCount = 0;
        }

        if(0 == PORTAbits.RA4)      // is SW2 pressed?
        {
            Digit1_Segments = 0xFF;     // Turn off digit segments
            Digit2_Segments = 0xFF;     // Turn off digit segments
            LoopCount = 0;
        }
    }
}

あなたのインストラクターがこれを気に入ってくれたら、あなたが何点取ったか教えてください。

于 2020-07-25T23:46:00.303 に答える