1

我有 2 个电路,均由双七段显示器和 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;
        }
    }
}

我的目标是使用修改后的字母在第二个七段显示器上生成相应的字母。但是,我无法弄清楚如何做到这一点。我最初的想法是使用修改后的 LEDDigits[] 将温度值输出到第二个 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-26),在另一个显示器上显示相应的字母。

我可以将第二个七段显示器添加到数字电路中,将其晶体管设置为 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 回答