I have 2 circuits, both made up of a dual seven segment display and A pic16f684 (As shown below) the first circuit uses the code supplied to generate a random number 1-26. The letter portion is the same circuit, but with one of the transistor removed, to disable one side.
/*
* 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;
}
}
}
My goal to is generate the corresponding letter on the second seven segment display using a modified alphabet. however, I cant figure out how to do this. My original thought was to output the temp value to the second pic16f684 with modified LEDDigits[];
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"
};
But I dont believe I can just output that number. How can I display the number (1-26) on one dual display, and the corresponding letter on another display.
Could I potentially add the second seven segment display into the number circuit, set its transistor on RA2, and have it display the letter at the same time? how would this work?
Ok, so here is a solution for your homework:
/*
* 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;
}
}
}
If you instructor likes this please let me know what marks you received.