NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » Program

January 12, 2011
by Jalex
Jalex's Avatar

I just want to see if I am understanding this correctly as I go. DDRC |= (1<<PC4); This is to make PC4 an output pin. Is DDRC a static register that only controls the IO of portc? and PORTC |= (1<<PC4); This is to set it high. Does the (1) in (1<<PC4) mean we only want to OR' 1 bit? I understand all the rest pretty good.

January 12, 2011
by Rick_S
Rick_S's Avatar

The (1<<PC4) means we are ORing the current value of DDRC with 1 shifted 4 times or 0001000 in binary. This will allow us to change just the single bit in the register for PORTC to turn the pin at PC4 into an output.

Rick

January 13, 2011
by Jalex
Jalex's Avatar

Thanks Rick Got it. I am pretty rusty I guess though. What does (Void) mean, I forgot, and (Double), I don't remember that one either. I have gotten lazy and have been using Visual Basic lately. I find it easier to trouble shoot large code files and I like not having to compile it to test it. This is kind of making me think I might want to get back into Assembly. Of course I would be really rusty at that too now. I haven't used it since I went to 32 bit and got lazy using VB 6. Is there a list of these registers with there proper names? I saw so many things in the data sheet I am not sure about a lot of them. I am having more trouble understanding how the controller works than the C code itself.

January 13, 2011
by Jalex
Jalex's Avatar

Hi Again Rick Sorry I bothered you with a lot of this. I studied the guide and found the answers to a lot of this. Still not sure about (Double) though but my C is finally coming back to me a little now. I have been trying to study with a lot going on around here and I find it hard. LOL

January 13, 2011
by Rick_S
Rick_S's Avatar

double is a data type like int, char, etc... There are also some defined types like uint8_t, uint16_t, etc...

January 13, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Jalex,

Like Rick mentioned, Double is another data type that you have at your disposal. It represents a floating point decimal number, which means you can hold numbers like 3.02 in it. One thing to note is that the microcontroller emulates these floating operations in software so a single multiplication of floating point numbers could take hundreds of CPU cycles, whereas operations with integers are much quicker.

Humberto

January 13, 2011
by Jalex
Jalex's Avatar

Thanks Humberto I got most of them. I thought that was what Float did. I really enjoy this kit and all the help I get for my dumb questions. LOL It is really quite different than computer programming. I didn't realize how many functions the computer takes care of automatically. I think I am almost ready to try writing one from scratch.

January 13, 2011
by bretm
bretm's Avatar

float and double and long double are all the same in avr-libc on 8-bit atmega's.

January 14, 2011
by Ralphxyz
Ralphxyz's Avatar

More specifically (Double) in C is to CAST a variable as a Double this is needed in certain math operations.

Google Type casting to get detailed explanations.

Ralph

January 14, 2011
by Jalex
Jalex's Avatar

Thanks Ok I see. Then are you saying that Float is for 8 bit and Double is 16 bit? If double and float are the same and I carry over in the the second bite what would stop me from writing over that bite? I think what I want is kind of a chart showing all the static control registers and there names. I see them referred to in all the code and I have to look them up all the time. I remember on the old Commodore the screen memory was static and you had to control each pixel and color you wanted by setting and clearing the bits. I also don't understand how the Ram is used. Does the chip handle that and just use it for math computations and things like that or what?

January 14, 2011
by bretm
bretm's Avatar

None of the machine registers use float or double format. Float is 32 bits (4 bytes) and so is double. They're the same thing on 8-bit AVR chips.

The Atmega datasheet has a master list of all the registers and register bits in a chapter called Register Summary near the end. But all the good info about the registers is summarized at the end of each chapter for each hardware subsystem.

RAM is allocated and used by the compiler whenever you declare any global variables. Is also used for the stack when you call functions and declare local variables in a function. You can also allocate RAM using malloc() but that's not very commonly done when you only have 1024 bytes to work with in the first place.

January 14, 2011
by Jalex
Jalex's Avatar

Thanks bretm Yes I finally got to study the data sheet more in depth and I see what you mean. I think I have it figured out now and I am ready to try a couple of programs I wrote. I will see how that goes and then know a little more.

January 17, 2013
by scootergarrett
scootergarrett's Avatar

So I guess I will post this question because it’s all about data types. But this is data pointer and addresses stuff. So I’m trying to embed (mux) different data types into a uint8_t data array, so it can be quickly loaded onto an SD card. So I have my test program where I’m trying to load different types into different locations in ‘buffer’ then I want to get them back out. This works method works in C on my computer. The MCU is placing the data correctly I can verify that by looking at the buffer data byte by byte, but not retrieving it. So what’s the deal with casting address pointer on the MCU?

int main()
{
    uint8_t buffer[512];

    // Different types //
    uint32_t one = 0;
    short two = 0;
    double three = 0.0;
    uint8_t four = 0;

    // Start up the LCD //
    lcd_init();
    FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
    lcd_home();

    // Example Numbers muxed into buffer //
    *(uint32_t*)&buffer[0x0] = 725000;
    *(short*)&buffer[0x10] = 400;
    *(double*)&buffer[0x20] = 3.14;
    *(uint8_t*)&buffer[0x30] = 25;

    // Demux number out of buffer and print //
    one = *((uint32_t*)&buffer[0x0]);
    two = *((short*)&buffer[0x10]);
    three = *((double*)&buffer[0x20]);
    four = *((int8_t*)&buffer[0x30]);

    fprintf_P(&lcd_stream, PSTR("%i  %i  %05.2f  %i"), one, two, three, four);

    while(1);
    return 0;
}

This program prints 4104 11 -49…00.00 16456

I need someone who know there pointer within this chip. Thanks

January 17, 2013
by Noter
Noter's Avatar

Here's some info on dereferencing type-punned pointer

January 17, 2013
by Noter
Noter's Avatar

Turns out the problem is not in your pointers but in your print statement. The format specifier for a long is %ld -

fprintf_P(&lcd_stream, PSTR("%ld %i %05.2f %i"), one, two, three, four);
January 17, 2013
by scootergarrett
scootergarrett's Avatar

The letter d is killing me. Just yesterday I had to open the drive in binary form by just adding a b. today just add a b then all your stress will go away. Thank you so much. I need to make a sheet for printing and scanning.

Only thing when I put a double on my memory card with my computer it’s a 64bit and the MCU doesn’t support that I think. And my C compiler doesn’t support single. I can probably work around this if I have to. Thanks again

January 17, 2013
by scootergarrett
scootergarrett's Avatar

Yes my computer dose 32bit its called float dur. I’m too quick to jump on the forum, Now I can move all sorts of number on my SD card quickly with both C and the MUC. Computer code to load numbers:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <Windows.h>
#include <conio.h>

#define BUFFER_SIZE 512

int main()
{
    // SDHC read and write varables //
    char buf[BUFFER_SIZE] = {0};
    int sector = 0;
    FILE *volume;

    int k, i;
    int one;
    short two;
    double three;
    char four;

    printf("size of a char is %d\n", sizeof(char));
    printf("size of a short is %d\n", sizeof(short));
    printf("size of a int is %d\n", sizeof(int));
    printf("size of a long is %d\n", sizeof(long));
    printf("size of a double is %d\n", sizeof(double));
    printf("size of a float is %d\n", sizeof(float));
    printf("size of a long double is %d\n", sizeof(long double));

    /// Load numbers on SD card ///
    printf("Loading .");

    *(int*)&buf[0x0] = 725123;
    *(short*)&buf[0x10] = 499;
    *(float*)&buf[0x20] = 2.70;
    *(char*)&buf[0x30] = 60;

    volume = fopen("\\\\.\\E:", "ab");
    setbuf(volume, NULL);       // Disable buffering
    sector = 1;
    fseek(volume, sector*BUFFER_SIZE, SEEK_SET);
    fwrite(buf, sizeof(*buf), BUFFER_SIZE, volume);
    fclose(volume);

    one = *((int*)&buf[0x0]);
    two = *((short*)&buf[0x10]);
    three = *((float*)&buf[0x20]);
    four = *(char*)&buf[0x30];

    printf("\n%i  %i  %05.2f  %i", one, two, three, four);

    printf("\nComplete\n");
    return 0;
}

and MCU code:

// SDHC Card test program

#define F_CPU 14745600

#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/io_328p.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"
#include "SDHC.h"

int main()
{
    int k;

    // Different typs //
    uint32_t one = 0;
    short two = 0;
    double three = 0.0;
    uint8_t four = 0;

    // Start up the LCD //
    lcd_init();
    FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
    lcd_home();

    // Start the SDHC //
    spi_init();
    sdhc_init();
    delay_ms(100);
    lcd_write_string(PSTR("Start "));

    sdhc_read_block(1);

    // Demux number out of buffer and print //
    one = *((uint32_t*)&buffer[0x0]);
    two = *((short*)&buffer[0x10]);
    three = *((double*)&buffer[0x20]);
    four = *((uint8_t*)&buffer[0x30]);

    fprintf_P(&lcd_stream, PSTR("%ld  %i  %05.2f  %i"), one, two, three, four);

    while(1);
    return 0;
}

I feel so empowered to move 1's and 0's where ever I see fit. Noter thank you so much

January 17, 2013
by Noter
Noter's Avatar

Glad to help. You have created a good demonstration of why C has been my favorite language for many years. Pointers may take some work to master but they are quite powerful for all types of data manipulation. I like pointers to functions too but don't have use for them very often. One place you can see a pointer to a function in use is in the bootloader. It uses a pointer to a function located at 0x0000 as a soft reset when it's time to start the user code.

Post a Reply

Please log in to post a reply.

Did you know that two resistors can be used to make a voltage divider? Learn more...