Pic16f684&双七段显示程序:C语言随机数生成器
Pic16f684 & dual seven seg display program: random number generator in C
我正在尝试转换此代码以生成随机数 1-56。
我会理解,但是因为程序必须来回切换才能显示两个数字,所以我很困惑。
我知道在某些方面,我可以使用rand()来选择。
我最终会将此代码与液晶屏结合使用来显示数字以及双七段显示,但现在,只是想办法对 PIC16F684 进行编程以在dua84l 七段显示器
下面是电路和代码。
未包含在图中,但在代码中是 RA3 和 RA4 具有清除显示或生成下一个数字的按钮。
提供的程序在按下按钮时显示 00-0xFF。重写程序可能更容易,但我就是看不懂
#include <xc.h>
/*
*
*
* 6/30/2020
/******************************************/
/* ------------------------------------------- */
/* Software/Hardware Interface: */
/* ------------------------------------------- */
/* */
/* Select Right Digit using >> RA0 */
/* Select Left Digit using >> RA1 */
/* */
/* Segment a >> RA5 */
/* Segment b >> RC5 */
/* Segment c >> RC4 */
/* Segment d >> RC3 */
/* Segment e >> RC2 */
/* Segment f >> RC1 */
/* Segment g >> RC0 */
/* ------------------------------------------- */
void PORTA_init(void)
{
PORTA = 0; // All PORTA Pins are low
CMCON0 = 7; // Turn off Comparators
ANSEL = 0; // Turn off ADC
//TRISA = 0b001111; // RA4 and 5 are outputs; RA0,1,2, and 3 are input
return;
}
/******** END OF PORTA_init ****************************/
void delay_routine(void)
{
int i, j;
for (i = 0; i<2000; i++);
for (j = 0; j <2000;j++);
return;
}
/******** END OF delay_20ms *************************/
// 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
int i, j;
int DisplayValue, DisplayLED;
const char LEDDigit[] = {
0b0000001, // "0"
0b1001111, // "1"
0b0010010, // "2"
0b0000110, // "3"
0b1001100, // "4"
0b0100100, // "5"
0b0100000, // "6"
0b0001111, // "7"
0b0000000, // "8"
0b0001100, // "9"
0b0001000, // "A"
0b0000000, // "b"
0b0110001, // "C"
0b0000001, // "d"
0b0110000, // "E"
0b0111000
}; // "F"
main()
{
PORTA = 0;
PORTC = 0;
CMCON0 = 7; // Turn off Comparators
ANSEL = 0; // Turn off ADC
TRISA = 0b011101; // RA5 and RA1 are outputs
TRISC = 0b000000;
DisplayValue = 0; // Start Displaying at 0x00
DisplayLED = 0; // Display the 1s first
while(1 == 1) // Loop Forever
{
if (0 == DisplayLED) // True, then display right digit
{
RA5 = LEDDigit[DisplayValue & 0x0F] >> 6;
// Clears display bits 4 - 7 of DisplayValue,
// then selects bit 7 of LEDDigit
PORTC = LEDDigit[DisplayValue & 0x0F] & 0x03F;
// clears display bits 4 - 7 of DisplayValue,
// then selects bits 0 - 6 of LEDDigit
}
else
{
RA5 = LEDDigit[(DisplayValue >> 4) & 0x0F] >> 6;
PORTC = LEDDigit[(DisplayValue >> 4) & 0x0F] & 0x03F;
} //
TRISA = TRISA ^ 0b000011; // Swap Left/Right (RA0 and RA1)
PORTA = PORTA & 0b111100; // Make Sure Bits are Low
DisplayLED = DisplayLED ^ 1; // Other Digit Next
NOP(); // Used for 10 ms Timing
for (i = 0; i < 30; i++);//10ms Delay Loop
NOP(); // Used for 10 ms Timing
if (RA3 == 0)
{
delay_routine();
DisplayValue++; // Increment the Counter
delay_routine();
} //
if (RA4 == 0)
{
delay_routine();
DisplayValue=0;
delay_routine();
}
}
}
您的数字是 BCD 编码的(BinaryCodedDecimal),每个数字 0-9 编码为四位 0000-1001。
DisplayLED
在 0 和 1 之间切换,到 select 要显示的数字,你必须确保在显示之前不要更新随机值,实际上你应该更新它甚至更少,因为显示器依靠 LED 的余辉和我们缓慢的眼睛来显示图像。
if (DisplayLED == 0) {
uint8_t r = myrand(); // place your favorite random generator here.
DisplayValue = (r/10)<<4|(r%10);
}
通过将 PortA 上的引脚 0 和 1 分别变为输入和输出来翻转它们
TRISA = TRISA ^ 0b000011; // Swap Left/Right (RA0 and RA1)
PORTA = PORTA & 0b111100; // Make Sure Bits are Low
DisplayLED = DisplayLED ^ 1; // Other Digit Next
由于 TRISA
中的最低有效位被初始化为 01
它们将在取反时交替出现,只有其中一个始终是输出。
@tjpplay,
您发布的代码有一些细微的问题,并且无法交替启用数字驱动程序。
您检测按钮按下的方法会扰乱数字多路复用器的时序并导致闪烁。
将数字驱动器连接到用于在线串行编程器 (ICSP) 的 PGC 和 PGD 引脚会使电路编程变得困难。在线调试 (ICD) 不适用于此实现。
该代码仅对 PORTA 和 PORTC 寄存器使用 8 位写入,从而避免了新玩家的读取-修改-写入 (RMW) 陷阱。
使用允许 C 编译器执行单个位设置和清除的语法可能会对 PIC16F684 等控制器产生 RMW 问题,尤其是在直接驱动 LED 时。
我认为这段代码可能适用于您的硬件:
/*
* File: main.c
* Author: 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;
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;
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)
{
DisplayValue++; // Increment display value every 500 milliseconds
}
if(LoopCount >= 50)
{
LoopCount = 0;
}
}
else
{
LoopCount = 0;
}
if(0 == PORTAbits.RA4) // is SW2 pressed?
{
DisplayValue = 0; // Reset display value to zero
LoopCount = 0;
}
}
}
这就是我如何修改上面的代码来生成您要求的随机数:
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 * 56u + 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;
}
}
}
我正在尝试转换此代码以生成随机数 1-56。 我会理解,但是因为程序必须来回切换才能显示两个数字,所以我很困惑。
我知道在某些方面,我可以使用rand()来选择。
我最终会将此代码与液晶屏结合使用来显示数字以及双七段显示,但现在,只是想办法对 PIC16F684 进行编程以在dua84l 七段显示器
下面是电路和代码。 未包含在图中,但在代码中是 RA3 和 RA4 具有清除显示或生成下一个数字的按钮。
提供的程序在按下按钮时显示 00-0xFF。重写程序可能更容易,但我就是看不懂
#include <xc.h>
/*
*
*
* 6/30/2020
/******************************************/
/* ------------------------------------------- */
/* Software/Hardware Interface: */
/* ------------------------------------------- */
/* */
/* Select Right Digit using >> RA0 */
/* Select Left Digit using >> RA1 */
/* */
/* Segment a >> RA5 */
/* Segment b >> RC5 */
/* Segment c >> RC4 */
/* Segment d >> RC3 */
/* Segment e >> RC2 */
/* Segment f >> RC1 */
/* Segment g >> RC0 */
/* ------------------------------------------- */
void PORTA_init(void)
{
PORTA = 0; // All PORTA Pins are low
CMCON0 = 7; // Turn off Comparators
ANSEL = 0; // Turn off ADC
//TRISA = 0b001111; // RA4 and 5 are outputs; RA0,1,2, and 3 are input
return;
}
/******** END OF PORTA_init ****************************/
void delay_routine(void)
{
int i, j;
for (i = 0; i<2000; i++);
for (j = 0; j <2000;j++);
return;
}
/******** END OF delay_20ms *************************/
// 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
int i, j;
int DisplayValue, DisplayLED;
const char LEDDigit[] = {
0b0000001, // "0"
0b1001111, // "1"
0b0010010, // "2"
0b0000110, // "3"
0b1001100, // "4"
0b0100100, // "5"
0b0100000, // "6"
0b0001111, // "7"
0b0000000, // "8"
0b0001100, // "9"
0b0001000, // "A"
0b0000000, // "b"
0b0110001, // "C"
0b0000001, // "d"
0b0110000, // "E"
0b0111000
}; // "F"
main()
{
PORTA = 0;
PORTC = 0;
CMCON0 = 7; // Turn off Comparators
ANSEL = 0; // Turn off ADC
TRISA = 0b011101; // RA5 and RA1 are outputs
TRISC = 0b000000;
DisplayValue = 0; // Start Displaying at 0x00
DisplayLED = 0; // Display the 1s first
while(1 == 1) // Loop Forever
{
if (0 == DisplayLED) // True, then display right digit
{
RA5 = LEDDigit[DisplayValue & 0x0F] >> 6;
// Clears display bits 4 - 7 of DisplayValue,
// then selects bit 7 of LEDDigit
PORTC = LEDDigit[DisplayValue & 0x0F] & 0x03F;
// clears display bits 4 - 7 of DisplayValue,
// then selects bits 0 - 6 of LEDDigit
}
else
{
RA5 = LEDDigit[(DisplayValue >> 4) & 0x0F] >> 6;
PORTC = LEDDigit[(DisplayValue >> 4) & 0x0F] & 0x03F;
} //
TRISA = TRISA ^ 0b000011; // Swap Left/Right (RA0 and RA1)
PORTA = PORTA & 0b111100; // Make Sure Bits are Low
DisplayLED = DisplayLED ^ 1; // Other Digit Next
NOP(); // Used for 10 ms Timing
for (i = 0; i < 30; i++);//10ms Delay Loop
NOP(); // Used for 10 ms Timing
if (RA3 == 0)
{
delay_routine();
DisplayValue++; // Increment the Counter
delay_routine();
} //
if (RA4 == 0)
{
delay_routine();
DisplayValue=0;
delay_routine();
}
}
}
您的数字是 BCD 编码的(BinaryCodedDecimal),每个数字 0-9 编码为四位 0000-1001。
DisplayLED
在 0 和 1 之间切换,到 select 要显示的数字,你必须确保在显示之前不要更新随机值,实际上你应该更新它甚至更少,因为显示器依靠 LED 的余辉和我们缓慢的眼睛来显示图像。
if (DisplayLED == 0) {
uint8_t r = myrand(); // place your favorite random generator here.
DisplayValue = (r/10)<<4|(r%10);
}
通过将 PortA 上的引脚 0 和 1 分别变为输入和输出来翻转它们
TRISA = TRISA ^ 0b000011; // Swap Left/Right (RA0 and RA1)
PORTA = PORTA & 0b111100; // Make Sure Bits are Low
DisplayLED = DisplayLED ^ 1; // Other Digit Next
由于 TRISA
中的最低有效位被初始化为 01
它们将在取反时交替出现,只有其中一个始终是输出。
@tjpplay,
您发布的代码有一些细微的问题,并且无法交替启用数字驱动程序。
您检测按钮按下的方法会扰乱数字多路复用器的时序并导致闪烁。
将数字驱动器连接到用于在线串行编程器 (ICSP) 的 PGC 和 PGD 引脚会使电路编程变得困难。在线调试 (ICD) 不适用于此实现。
该代码仅对 PORTA 和 PORTC 寄存器使用 8 位写入,从而避免了新玩家的读取-修改-写入 (RMW) 陷阱。
使用允许 C 编译器执行单个位设置和清除的语法可能会对 PIC16F684 等控制器产生 RMW 问题,尤其是在直接驱动 LED 时。
我认为这段代码可能适用于您的硬件:
/*
* File: main.c
* Author: 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;
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;
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)
{
DisplayValue++; // Increment display value every 500 milliseconds
}
if(LoopCount >= 50)
{
LoopCount = 0;
}
}
else
{
LoopCount = 0;
}
if(0 == PORTAbits.RA4) // is SW2 pressed?
{
DisplayValue = 0; // Reset display value to zero
LoopCount = 0;
}
}
}
这就是我如何修改上面的代码来生成您要求的随机数:
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 * 56u + 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;
}
}
}