Trying To Shift Hex Values, Help Please

1.7k views Asked by At

I'm trying to shift my hex output to the left by one, so that I can display digits above 9 on a 7 segment lcd.

Programming on C, the software I'm using is NIOS II, so that I can reprogram straight onto a DE0 Board.

The aim of this project is to increment the value of the of the LCD by one each time 'button1' is pressed. I have done this successfully however of course after 9 it would need to shift to the left and restart from 1, replacing the position it came from with a 0. I've done a fair bit of research but haven't had any luck so any help is appreciated. Thanks.

Code is below:

#include "sys/alt_stdio.h"   //for the alt_putstr function below.  Outputs to Eclipse console
#include "altera_avalon_pio_regs.h"  //for the I/O functions in the while loop below
#include "sys/alt_timestamp.h"  //see Nios II Software Developer’s Handbook, Timestamp Driver
#include "system.h"

#define setHeaderOuts HEADEROUTPUTS_BASE+0x10   //HEADEROUTPUTS_BASE is defined in system.h of the _bsp file.  It refers to the base address in the Qsys design
                                                //the hex offset (in this case 0x10, which is 16 in decimal) gives the number of bytes of offset
                                                //each register is 32 bits, or 4 bytes
                                                //so to shift to register 4, which is the outset register, we need 4 * (4 bytes) = 16 bytes
#define clearHeaderOuts HEADEROUTPUTS_BASE+0x14 //to shift to register 5 (the 'outclear' register) we need to shift by 5 * (4 bytes) = 20 bytes, (=0x14 bytes)
                                                // offset of 5 corresponds to the 'outclear' register of the PIO.


int  main(void)
{
    alt_putstr("This is the ELEE1062 version of the NIOS processor");
    int buttons = 0; //the buttons on the DE0
    //int switches = 0;  //the switches on the DE0
    int count = 0; //general purpose counter
    int hexd = 0;

    while(1)
    {
        buttons=IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTONS1_2_BASE); //read the value of the pushbuttons

        while((buttons & 0x01) == 1) // i.e. while pushbutton 1 is not pressed
        {
            buttons=IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTONS1_2_BASE); //read the value of the pushbuttons
        }

        count=count+1;

        IOWR_ALTERA_AVALON_PIO_DATA(DE0_LEDS_BASE,count); //display the value of count in binary, using the green LEDs

        while((buttons & 0x01) == 0) //i.e. while pushbutton 1 is pressed
        {
            buttons=IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTONS1_2_BASE); //read the value of the pushbuttons

        }

        if (count==0)
        {
            hexd=0x000000c0;
        }

        else if (count==1)
        {
            hexd=0xf9;
        }

        else if ( count==2)
        {
            hexd=0xa4;
        }

        else if ( count==3)
        {
            hexd=0xb0;
        }

        else if ( count==4)
        {
            hexd=0x99;
        }

        else if ( count==5)
        {
            hexd=0x92;
        }

        else if ( count==6)
        {
            hexd=0x82;
        }

        else if ( count==7)
        {
            hexd=0xd8;
        }

        else if ( count==8)
        {
            hexd=0x80;
        }

        else if ( count==9)
        {
            hexd=0x90;
        }

        else if ( count>9)
        {
            hexd= hexd & ~(1<<count);
        }


        //count=alt_timestamp_start(); //start the timer. Timer increments each clock cycle.  Clock for ELEE1062_NIOS is 50MHz
        //buttons=IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTONS1_2_BASE); //read the value of the pushbuttons
        //switches=IORD_ALTERA_AVALON_PIO_DATA(DE0SWITCHES_BASE); //read the value of the switches
        IOWR_ALTERA_AVALON_PIO_DATA(SSEG_BASE,hexd);  //DE0 7 segment displays all off --notice that a logic '1' turns the segment off
        IOWR_ALTERA_AVALON_PIO_DATA(SSEG_BASE,hexd);  //DE0 7 segment displays all on
        IOWR_ALTERA_AVALON_PIO_DATA(DE0_LEDS_BASE,0x000);  //all off --for the green LEDs, a logic '0' turns the LED off
        IOWR_ALTERA_AVALON_PIO_DATA(DE0_LEDS_BASE,0xfff);  //all on
        IOWR_ALTERA_AVALON_PIO_DATA(clearHeaderOuts,0x01); //turn off the first pin of the output port
        IOWR_ALTERA_AVALON_PIO_DATA(setHeaderOuts,0x01);    //turn on the first pin of the output port
        //IOWR_ALTERA_AVALON_PIO_DATA(SSEG_BASE,switches);  //light up the 7 segment display segments corresponding to how the DE0 switches are set
        IOWR_ALTERA_AVALON_PIO_DATA(DE0_LEDS_BASE,buttons); //light up the green LEDs corresponding to which DE0 buttons are pushed
        //count=alt_timestamp(); //record the value of the timer, and store in the 'count' variable


    }
}
2

There are 2 answers

4
Michael Burr On BEST ANSWER

The following function will return a u32 value composed of four bytes with LED values for the digit display. Note that I don't know what order your display wants the digit in, so you might need to byteswap the return value or something. Also, this function will provide leading zeros for the LED display - you might need to modify things so those show as blanks on the display.

typedef unsigned int u32;

static char led_digits[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8, 0x80, 0x90 };

u32 four_digits( int x)
{
    unsigned char c[4];
    int i;

    for (i = 0; i < 4; ++i)
    {
        int digit = x % 10; 
        x = x / 10;
        c[i] = led_digits[digit];
    }

    return (u32)(c[3] << 24) | (u32)(c[2] << 16) | (u32)(c[1] << 8) | (u32)c[0];
}
2
Andrey On

Merely shifting won't work. 9 -> 10 (you can call this shifting) but what about 19 -> 20? Since it is clearly a homework or other form of learning, I will not write code for you. You ultimate goal is to represent numbers on 7 segment led display. Think from that. So as an input you have binary number (count) and output should be led pin signals. Your task is to convert one into another. Led is operating essentially with decimal radix, so you first need to convert binary to series of decimal digits and then convert them to pin signals (this code you have already). To use all four digits you need to convert your number into format 0x11223344 where number denotes led position. 0xF9A4B099 is 1234 (if I am not mistaken).