I am trying to write a code for displaying numbers on a four digit seven segment display using STM32-F401RE. The problem lies in the while(1) loop.
Here is the code:
void num_display_func(uint16_t numtodisplay);
void displayDigit(uint8_t number);
int main(void){
while (1)
{
/* USER CODE END WHILE */
num_display_func(0209);
/* USER CODE BEGIN 3 */
}
void num_display_func(uint16_t numtodisplay){
uint8_t digit_extract[4];
digit_extract[0] = numtodisplay%10; //extract the last digit of the number
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, SET);
displayDigit(digit_extract[0]);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, RESET);
HAL_Delay(10);
digit_extract[1] = (numtodisplay/10)%10; //extract the second last digit
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, SET);
displayDigit(digit_extract[1]);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, RESET);
HAL_Delay(10);
digit_extract[2] = (numtodisplay/100)%10; //extract the third last digit
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, SET);
displayDigit(digit_extract[2]);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, RESET);
HAL_Delay(10);
digit_extract[3] = (numtodisplay/1000)%10; //extract the fourth last digit
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, SET);
displayDigit(digit_extract[3]);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, RESET);
HAL_Delay(10);
}
void displayDigit(uint8_t number){
GPIOC->ODR |= GPIOx_SEGMENTS_MASK; //Clear the segment bits (Setting the bits to HIGH for common Anode config)
uint8_t digit = segmentCodes[number];
GPIOC->ODR |= (digit & GPIOx_SEGMENTS_MASK );
}
When I am trying to run the code, here is the error:
./Core/Src/main.c:115:21: error: invalid digit "9" in octal constant
115 | num_display_func(0209);
| ^~~~
As far as I know, this can be fixed if the 0 is removed. but in that case how do I display the number, 0209 or any other number starting with zero for that matter?
If I remove the 0 from the number, it may display 209 instead of 0209. How to solve this?
Numeric prefixes in C are 0x for hexadecimal and 0 for octal.
but in that case how do I display the number, 0209 or any other number starting with zero for that matter?
That is a whole different misunderstanding. Your question should really be about that. The value is an integer it will be stored in this case as a 16 bit binary value in two bytes of memory. The decimal (or octal) representation in your code is not preserved or represented, it does not matter how many leading zeros you add or what number base you use, it is just an int literal constant.
If you intend to present that value with four digits with leading zeros, then that is a presentation issue, not a representation issue. That is you determined how to display it when you display it.
In your case, you might simply test n < 1000 for the first digit and output a zero if that is true rather than (numtodisplay/1000)%10. Then compare to 100 and 10 for the second and third digits respectively. However you need not even do that because for 209 the expression (numtodisplay/1000)%10 is zero in any case, so the code you have will "just work" as is. If it does not then that is a different question.
However there is a simpler more compact solution:
void num_display_func( uint16_t numtodisplay )
{
int place_value = 1000 ;
int num = numtodisplay ;
uint16_t pin = GPIO_PIN_12 ;
// For each digit
for( int d = 0; d < 4; d++ )
{
uint8_t digit = num / place_value ;
HAL_GPIO_WritePin(GPIOA, pin, SET) ;
displayDigit( digit ) ;
HAL_GPIO_WritePin(GPIOA, pin, RESET) ;
num %= place_value ;
place_value /= 10 ;
pin >>= 1 ;
HAL_Delay( 10 ) ;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With