-1

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


    }
}
  • Can you make clear what part of your program you're having trouble with (I think it's the expression `hexd= hexd & ~(1< – Michael Burr Dec 16 '13 at 17:02
  • Thanks for replying, what I need the program to do is increment the value by 1 each time the 'button1' is pressed, and once its passes the value 9 on the LCD it needs to display 10, all the way up to 9999. The problem I am having is the I cant get past 9. Ideally I'd like to create a loop to do this, but its quite tricky. – NoobProgrammer Dec 16 '13 at 17:07
  • The hexd= hexd & ~(1< – NoobProgrammer Dec 16 '13 at 17:09
  • I am wondering what were *researching*. How to shift? You are trying to solve a goal that has nothing to do with your original goal. – Andrey Dec 16 '13 at 17:20

2 Answers2

1

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).

Andrey
  • 59,039
  • 12
  • 119
  • 163
  • I've been researching what decimal digits is, I've had no luck. In terms of 0xF9A4B099, it does represent 1234 however the issue I am trying to solve is, how can I get the program to increase by 1 with the use of a loop, Without having to type out each number in hex format? – NoobProgrammer Dec 16 '13 at 18:04
  • @user2192435 you are trying to solve wrong issue, you just increment your number as is, then you need to convert binary number to it's decimal digits (well you should know what is decimal digits, it is what humans use to write numbers). – Andrey Dec 16 '13 at 18:13
0

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];
}
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • What is the point of providing complete code for obvious homework question? – Andrey Dec 16 '13 at 18:15
  • Also you don't need array at all, just shift left the digits in the loop. – Andrey Dec 16 '13 at 18:15
  • @Andrey and Jongware: it didn't cross my mind about it being a homework question. I don't always bother to think of the unspoken motivations behind a question - sometimes I just post an answer. Also, keep in mind that even if I had realized the homework angle, there are a lot of opinions on SO about how homework questions should be handled: http://meta.stackexchange.com/questions/10811/how-do-i-ask-and-answer-homework-questions Finally, I'm not sure I'd call this answer a complete solution to the homework, just one aspect of the problem. – Michael Burr Dec 18 '13 at 00:58
  • @MichaelBurr I know very well that metaquestion, and of course it is up to you what approach to pick for this questions. I just expressed my opinion that it is completely pointless for educational purpose to give straight answers. Give man a fishing rod and all that stuff. Maybe it is just me, but I can spot homework questions with 90% hit rate. – Andrey Dec 18 '13 at 01:21