Switch & Case in Atmel Studio C

Go To Last Post
33 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How to make this?

My project

8 mini-tables of 5 dw,  selected via PB3 PB4 PB5 jumper pin, 3 pins for input, read data from port, shift to 0-7 format(?)
 

I have a sample code

---------------

void read_config_bits (config_bits)    // Read config bits PB3 PB4 PB5 type of power table (0-7)
    {
    DDRB = 0x00;                // make port a as input all bits
    PORTB = 0x38;               // enable all pull-ups  bit 5-4-3
    config_bits = PINB;               // read data from port a pins

    ??shift??

    }

 

switch(???)            // Find data table from config bits (data 0-7)
    {
    case 0: ?? code select data0 number 1-5 via read ADC   // Switch to Sheme 0
    break;

 

........

case 7: ?? code select data7 number 1-5 via read ADC   // Switch to Sheme 7
    break;

 

default: ?? nothing

};

 

data0 int16 0225, 0446, 0333, 0555, 0111   // numder 1-5

....

data7 int16  0225, 0446, 0333, 0555, 0111 // numder 1-5

----------------------------

This topic has a solution.

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
config_bits = ( config_bits >>3 ) & 0x07; 

Now you can use the variable in the switch statement.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, ok!

next step?

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Do you use portB for something else than reading it's value?

 

You could just initialize the port and that's it.

 

while(1){
    ...
    DDRB ~= 0x38;                   // make in 3,4,5 as input
    PORTB = 0x38;                   // enable all pull-ups  bit 5-4-3
    ...
    config_bits = (PINB>>3)&0x7;    // read data from port a pins
    switch(config_bits)             // Find data table from config bits (data 0-7)
    {
        case 0: ?? code select data0 number 1-5 via read ADC   // Switch to Sheme 0
        break;
        ........
        case 7: ?? code select data7 number 1-5 via read ADC   // Switch to Sheme 7
            break;
     
        default: ?? nothing
    };
 
data0 int16 0225, 0446, 0333, 0555, 0111   // numder 1-5
....
data7 int16  0225, 0446, 0333, 0555, 0111 // numder 1-5

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, next step yes

How make ADC port PB2 init&read routine before switch(config_bits)?

I want to work this big cycle (while?) worked on watchdog timer

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You probably want an ADC_init() routine you call just once at program start that sets up the ADC so it can make a reading. Then you want an ADC_read() you call from within the loop that sets the ADSC bit to start a conversion then waits for it to switch back from 1 to 0 - which signals that the conversion is complete - then it reads the ADC result register(s) and then passes those back.

 

The internet (and indeed the Tutorial forum here) have examples of how to implement such ADC_init() and ADC_read() routines.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

    while (1)

{
        adc_in = adc_read();

}

 

void adc_set (void)
    {
    ADMUX |= (1 << MUX0);                     // PB2/ADC1
    ADMUX |= (0 << ADLAR);                    // Set the prescaler to clock/128 & enable ADC at 9.6 MHz this is 75 kHz
    ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
    }

int adc_read (int16 voltage)
    {

    int16 VRef=2.56

    ADCSRA |= (1 << ADSC);
    while (ADCSRA & (1 << ADSC));
    return ADCH, ADCL; ???

    voltage = (ADCH*256+ADCL) * VRef/ 1024    ??? // for 10 bit precision(1024 as 2^10 = 1024).
    }

 

read from http://www.robotplatform.com/kno...

 

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're doing too much steppin' ! Those question marks in your posted code will throw errors and the line after "return" won't get executed. Open the datasheet and read about the ADC, and also get the tutorials from the forum and study them until you have a better understanding of that system. You're asking for very basic things, which show you haven't put in your study time.

 

1) Learn...

2)...THEN do.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
ADMUX |= (0 << ADLAR);

This does nothing. Shifting 0 by any number results in 0. ORing anything with 0 leaves the original value.

voltage = (ADCH*256+ADCL) * VRef/ 1024    ??? // for 10 bit precision(1024 as 2^10 = 1024).

ADCL must be read before ADCH and this line does not guarantee that. Even ADCL + ADCH * 256 does not guarantee this as the compiler is free to access the values of those registers in whatever order it likes within one statement. You could split this up into two lines, but that is unnecessary since avr-libc provides ADCW which reads the entire value.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi, guys, next step smiley

 

#include <avr/io.h>
#define F_CPU 1000000UL  // 1 MHz
#define CPU_TYPE __AVR_ATtiny25__ ???
#include <util/delay.h>
1. UL  - ?? what this?

2. how to define CPU type?

 

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

Last Edited: Sun. Feb 1, 2015 - 05:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

mixer188 wrote:
1. UL - ?? what this?

 

'C' textbook time: http://publications.gbdirect.co....

 

Some more 'C' learning resources (including that textbook): http://blog.antronics.co.uk/2011...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I agree, it seems like you have problems programing in general and not just issues with the AVR. You should probably do some online tutorials (there are plenty out there, google is your friend) and you would probably already have an answer to a lot of your questions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
------ Rebuild All started: Project: Power, Configuration: Release AVR ------

                Program Memory Usage     :    1824 bytes   89,1 % Full
                Data Memory Usage         :    84 bytes   65,6 % Full
Done building project "Power.cproj".

Build succeeded.
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

This my little first C ARV project, 516 line of code, written in Atmel Sdudio 6.2 for 5 night-session ))
it a base to modify and update code and function
 

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

Last Edited: Sat. Feb 7, 2015 - 08:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This my little first C ARV project, 516 line of code, written in Atmel Sdudio 6.2 for 5 night-session ))

Well, from your post we have learned that the name of your project is "Power.cproj" and it takes 1824 bytes.

We will have to do with this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!
I modify & add new code
see it for errors of float variable, contains 1.1 to 9.999999 and etc errors for EEPROM read-write.
Compiler has no errors.

 

unsigned long volt_factor    = {5859375};        // Outer Resistive divider Umax = 15V, Uref=2.56V, Umax/Uref ??????????

 

int main(void)

{
        int mode;
        if(mode == 0)						        // Calibrate Mode = 0 (ON)?
                {
                calibrate_set();                                        // Yes
                }
        else                  						// Calibrate Mode OFF
                {
                if(EEPROM_read(0) != 0xFF)				 // Empty calibrate voltage (0xFF)??????
                        {
                        volt_factor = EEPROM_read(0);			// Yes, Read from EEPROM calibrated voltage factor to variable (float) ???????
                        }
                else							 // No, use standard volt_factor = 5.859375 (float)
                        {
                        while(1)					// Main work cycle
                                {
                                adc_setup();				// ADC setting for read voltage
                                voltage = adc_read();			// Get the ADC value voltage
                                }
                        }
                }
        sleep_enable();
        sleep_cpu();							// Sleep cpu after calibrate mode
return 0;
}
unsigned int adc_tmp = {0};                    // tmp data for ADCW
    unsigned int a;
    for (a=8; a>0; a--)                        // read 8 times
        {
        _delay_us(10);                        // Delay needed for the stabilization of the ADC input voltage
        ADCSRA |= (1 << ADSC);                      // Start the conversion (bit 6)
            while (ADCSRA & (1 << ADSC));              // Wait for it to finish
        adc_tmp += ADCW;
        }                                       // End 8 reading
    adc_tmp = adc_tmp/8;                        // average value of ADC from 8 times, ADCW 16bit data, ADCH + ADCL
    return adc_tmp;

 

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

Last Edited: Sun. Feb 8, 2015 - 09:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Most compilers have the eeprom functions already - no need to make your own.a float is usually 4 bytes long, so storing to 1byte in eeprom isn't going to work. You need to read/write a block of 4 bytes for a float. The question has been asked many times before. Search 'eeprom floating point'

You might want to read up on C casting. You do integer math when you probably would want to use float. Also note that float constants should have a decimal point eg 10.0
You also put {0} around constants. Highly irregular as it suggests an array.
So, think carefully about your numbers and understand integer rounding.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I think you need to do a bit more research. I gather you want to see if the eprom location is empty (i.e. 0xffffffff) and then write a value if it is. The function is called eprom_read_float because it reads 4 bytes from eprom and returns the floating point representation of that value. Unfortunately you can't compare it with a long int -you're comparing apples with oranges. You want to test it with a long int, then read it as a long int in order to see if it is empty, then you can write your float value. What the value 0xffffffff represents as a float value, I don't know off the top of my head. You could read the fp standard ieee754 or try reading it as a float and seeing what the value is represented as.

 

Oh yes, there is a tutorial in the tutorial section that might help.

 

 

After a bit of searching : there's eprom_read_dword() which would be the choice for testing with 0xffffffffU

 

Last Edited: Sun. Feb 8, 2015 - 11:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

int read_bits(void)  
{
    unsigned int bits;
    DDRB  &= (~((1<<DDB5) | (1<<DDB4) | (1<<DDB3)));  
    PORTB |=    (1<<PB5)  | (1<<PB4)  | (1<<PB3);  
    bits = (PINB>>3) & 0x7;   
    return bits;
}

 

In simulator mode tiny45 , "bits" return always 3, instead 7

why?

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I gather your last problem was resolved? If so, tell us.
In answer to your new question:
Probably because pb5 is low?
Why use an unsigned int for something that is a byte? Unsigned char or uint8_t
Also, another anomaly that can get you into trouble - bits is unsigned int but you return it as an int.

Last Edited: Sun. Feb 8, 2015 - 09:19 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, older troubles resolved yes

 

use char ??

 

unsigned char read_bits(void)                     
{
    unsigned char bits;
    DDRB  &= (~((1<<DDB5) | (1<<DDB4) | (1<<DDB3)));      
    PORTB |=    (1<<PB5)  | (1<<PB4)  | (1<<PB3);         
    bits = (PINB>>3) & 0x7;             IN R24,0x16        In from I/O location = 1F; >> 0F >> 07>> 03 ; ANDI R24,0x07        Logical AND with immediate             
    return bits;      03
}

 

bits return 3 sad
PB5 0
 

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

Last Edited: Sun. Feb 8, 2015 - 09:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why ?? What is pinb defined as? It's not an int. delve down into the header files to see.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

#define F_CPU 8000000UL                // For <delay.h> only

#include <avr/sleep.h>                // Power Management and Sleep Modes; void sleep_enable (void); void sleep_disable (void); void sleep_cpu (void);
#include <avr/io.h>                // all include
#include <avr/eeprom.h>                // Internal EEPROM
#include <util/delay.h>                // delay routine
#include <math.h>                // Mathematics

 

/* declare function

 

/* declare global variables

 

/* declare array

 

int main(void)

{}

 

that all

-----------------

file iotnx5.h

#define PORTB   _SFR_IO8(0x18)
#define PB5     5
#define PB4     4
#define PB3     3
#define PB2     2
#define PB1     1
#define PB0     0

 

 

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

Last Edited: Sun. Feb 8, 2015 - 10:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wasn't suggesting that unsigned char would cure the problem. As to ehy PB5 is low is probably due to some other influence.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bits = PINB ; IN R24,0x16        In from I/O location

1F!!! instead 3F

possible to somehow configure other settings or fusebits or interrupts or timers? i do not use this

 

 

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

Last Edited: Sun. Feb 8, 2015 - 10:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
1F!!! instead 3F
So PB5 is low.

 

And on which physical pin of the ATtiny25/45/85 is PB5 located?

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Feb 8, 2015 - 11:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How to fix RESET and this fuse bits in Atmel Studio 6 Simulator?

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Be careful.  If you disable the reset pin, you will no longer be able to program the part with ISP or with debugWire.  You will need a programmer capable of HVSP.  Your AVR ISP MkII Clone is not capable of that.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is a lot of redirection going on here: Case/Switch, ADC, EEPROM,  etc.  and yet, there is no resolution to any of these deviations from the original topic.

 

The OP needs to get the basics down.  There is a main() with a return.  And at that, the return is executed before the return value is calculated. There are many other glaring errors, as well!   It seems that with each redirection of topic (more like a Ping-Pong ball being slammed around at high velocity within a Rubik's-Cube sized box) the OP displays increasing deficiency in knowledge of the most rudimentary basics.

 

So to put my two cents into the fray, I offer the following:

 

/****************************************************************************/
/********************** ATMEGA1280v ADC Test Program ************************/
/****************************************************************************/
/*
  System platform:        Defacto Original Arduino Mega class development board
  Controller:             ATMega1280v
  Fosc:                   Upgraded from 16.000MHz to 18.432MHz
  Compiler:               ImageCraft ICCAVR, version 7.23
  Programming method:     ATISP MKII under control of AVRStudio 6.xx
  Adruino Mega output:    USART0: 230.4K Baud, 8 Data, 1 Stop, No parity
  Display console:        Terra-Term: 230.4K Baud, 8 Data, 1 Stop, No parity 
  ADC operating mode:     Free running, using channel 0

  Note: This program compiled correctly for the ATMega328P, as well,
  but was not tested.
  
  This program was taken first, from a previous project and modified to work
  within a current and on-going ATMega1280v project.
  
  The applicable functional ADC program parts were then extracted from the
  ATMega1280v based project and assembled into what is seen here.  As such,
  there may be some program functionality of what worked in the ATMega1280v
  project that have been missed.
  
  While the code presented here works within the original ATMega1280v project,
  the code presented here has not been tested for functionality.
  
  This ADC test program is, however, a good starting point.
*/
/****************************************************************************/

/****************************************************************************/
/************************* Controller Header files **************************/
/****************************************************************************/
#include <iom1280v.h>
#include <AVRdef.h>
/****************************************************************************/

/****************************************************************************/
/************************** Compiler Header Files ***************************/
/****************************************************************************/
#include <stdio.h> // The float option is set in the compiler IDE Options tab
/****************************************************************************/

void adc_init(void);

void main (void) {
   float ADC_Ch0_Temp;

  adc_init();
  
  while(1) {

     ADC_Ch0_Temp = (5.00 * (float)ADC) / 1023; // Direct reading and scaled to 5.00 VDC
     printf("ADC: = ");
     printf("%1.3f Volts ox0A0x0D", ADC_Ch0_Temp);

  }
}

// ADC initialize
// Conversion time: 6.944uS
void adc_init(void) {
  ADCSRA = 0x00; // Disable ADC
/*
************************************** ADMUX ****************************************
 | REFS1 | REFS1 |                   | MUX5 | MUX4 | MUX3 | MUX2 | MUX1 | MUX0 |
-+-------+-------+-                 -+------+------+------+------+------+------+-
 |   0   |   0   | AREF OFF          |   0  |   0  |   0  |   0  |   0  |   0  | ADC0
-+-------+-------+-                 -+------+------+------+------+------+------+-
 |   0   |   1   | Avcc              |   0  |   0  |   0  |   0  |   0  |   1  | ADC1
-+-------+-------+---               -+------+------+------+------+------+------+-
 |   1   |   0   | Reserved          |   0  |   0  |   0  |   0  |   1  |   0  | ADC2
-+-------+-------+---               -+------+------+------+------+------+------+-
 |   1   |   1   | Internal 1.1V     |   0  |   0  |   0  |   0  |   1  |   1  | ADC3
-+-------+-------+--                -+------+------+------+------+------+------+-
 |   X   |   X   | NA                |   0  |   0  |   0  |   1  |   0  |   0  | ADC4
-+-------+-------+-                 -+------+------+------+------+------+------+-
 |   X   |   X   | NA                |   0  |   0  |   0  |   1  |   0  |   1  | ADC5
-+-------+-------+-                 -+------+------+------+------+------+------+-
 |   X   |   X   | NA                |   0  |   0  |   0  |   1  |   1  |   0  | ADC6
-+-------+-------+-                 -+------+------+------+------+------+------+-
 |   X   |   X   | NA                |   0  |   0  |   0  |   1  |   1  |   1  | ADC7
-+-------+-------+-                 -+------+------+------+------+------+------+-
 |   X   |   X   | NA                |   0  |   1  |   1  |   1  |   1  |   0  | 1.1V (Vbg)
-+-------+-------+-                 -+------+------+------+------+------+------+-
 |   X   |   X   | NA                |   0  |   1  |   1  |   1  |    1 |   1  | 0V (GND)
-+-------+-------+-                 -+------+------+------+------+------+------+-
*/           
  // Channel 0 selected: MUX3 = 0, MUX2 = 0, MUX1 = 0, MUX0 = 0
  // ADC input 0 selected, right Justified (ADLAR = 0)
  ADMUX = (1<<REFS0); // Avcc, external capacitor connected at AREF pin: 0x40 
  ACSR  = (1<<ACD); // Disable the Analog comparator: 0x40

  // Turn off digital input buffers on ADC channels: DIDr0 = 0xFF, DIDR2 = 0xFF 
  //  DIDR0 = (1<<ADC7D) | (1<<ADC6D) | (1<<ADC5D) | (1<<ADC4D) |/
  //          (1<<ADC3D) | (1<<ADC2D) | (1<<ADC1D) | (1<<ADC0D); 
  //  DIDR2 = (1<<ADC15D) | (1<<ADC14D) | (1<<ADC13D) | (1<<ADC12D) |/
  //          (1<<ADC11D) | (1<<ADC10D) | (1<<ADC9D) | (1<<ADC8D);

  ADCSRB &= ~((1<<ADTS2) | (1<<ADTS1) | (1<<ADTS0)); // Free running: 0x00

/*  
         |   ADEN    |   ADSC    |   ADATE    |        ADPS2, ADPS1, ADPS0         |
         |    ADC    |   Start   |   Auto     |              ADC CLK               |
         |  Enable   | Conversion|  Trigger   |           Divide by 128            |
*/
  ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (1<<ADPS2) | (1<ADPS1) | (1<<ADPS0); // 0xE7
}

 

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

Last Edited: Mon. Feb 9, 2015 - 03:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

Be careful.  If you disable the reset pin, you will no longer be able to program the part with ISP or with debugWire.  You will need a programmer capable of HVSP.  Your AVR ISP MkII Clone is not capable of that.

I need 1 pin for input, or ADC, or OUT, or redefine new pin map.  What to do where to get 1 pin for Tiny25-45?

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I need 1 pin for input, or ADC, or OUT, or redefine new pin map.  What to do where to get 1 pin for Tiny25-45?

I'm getting very confused.

 

An old saying:  "You cannot put 10 pounds of stuff into a box that only holds 5 pounds."

 

Without extraordinary methods, there are five useful I/O pins on the 8-pin Tiny25.

 

How many I/O pins, total, do you need?

 

The original code indicated three pins for the selection table.  Is that correct?

 

The use of the ADC indicates that only a single channel is needed?  Now you are up to four needed pins.

 

What is this OUT?  I see no output in the code.

 

I don't think your initial ADC routines are correct, are they?  |= (0<<ADLAR) is zero and has no effect, for example.

 

I've never seen the need for float in AVR8, especially in a program of this type.  Do all your calculations in millivolts, and store as a 16 bit unsigned integer.  After all, you only have a 10-bit ADC.  A reading of a 5V signal only has a resolution of 5mV per count anyway.  Your program then becomes a few hundred bytes.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

A couple suggestions:

 

-- I assume your selection table is like toggle switches, or maybe a DIP switch block?  In any case, switches bounce so for a simple implementation you would want them set before your program starts.  You also want time for the pullups to "take".  In all my apps, after initial setup of port direction and pullups and such, I delay for as long as the application will tolerate.  I've found 100ms to be a good time.  That should let everything settle down to a good reading.

 

-- For something this simple, it shouldn't matter which pins are being used for the switches.  Just do them individually...

unsigned char config_bits;
...
    config_bits = 0;
    // Active-low inputs, right?
    if ((PINB & (1<<PB0)) == 0)
        {
            // low switch made
            config_bits |= 1;
        }
    if ((PINB & (1<<PB2)) == 0)
        {
            // middle switch made
            config_bits |= 2;
        }
    if ((PINB & (1<<PB4)) == 0)
        {
            // high switch made
            config_bits |= 4;
        }        
// .. or whichever pins you want        

If the compiler sees fit to keep config_bits in a register then each if() might well take only two words of code.

 

                 ; 0000 0006 unsigned char config_bits;
                 ; 0000 0007 //...
                 ; 0000 0008     config_bits = 0;
                 ;	config_bits -> R17
00005a e010      	LDI  R17,LOW(0)
                 ; 0000 0009     // Active-low inputs, right?
                 ; 0000 000A     if ((PINB & (1<<PINB0)) == 0)
00005b 9b18      	SBIS 0x3,0
                 ; 0000 000B         {
                 ; 0000 000C             // low switch made
                 ; 0000 000D             config_bits |= 1;
00005c 6011      	ORI  R17,LOW(1)
                 ; 0000 000E         }
                 ; 0000 000F     if ((PINB & (1<<PINB2)) == 0)
00005d 9b1a      	SBIS 0x3,2
                 ; 0000 0010         {
                 ; 0000 0011             // middle switch made
                 ; 0000 0012             config_bits |= 2;
00005e 6012      	ORI  R17,LOW(2)
                 ; 0000 0013         }
                 ; 0000 0014     if ((PINB & (1<<PINB4)) == 0)
00005f 9b1c      	SBIS 0x3,4
                 ; 0000 0015         {
                 ; 0000 0016             // high switch made
                 ; 0000 0017             config_bits |= 4;
000060 6014      	ORI  R17,LOW(4)
                 ; 0000 0018         }

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

    DDRB  &= (~((1<<DDB5) | (1<<DDB4) | (1<<DDB3)));
    PORTB |=    (1<<PB5)  | (1<<PB4)  | (1<<PB3);       

PB3 & PB4 work ok, but PB5 "1" not read, allways "0"

 

fusebit need set from this link http://www.robotroom.com/Atmel-A...

HVSP is missing sad

 

Is it possible to use it PB5 as a way out?

AvrStudio 7
AVR ISP MkII Clone
Core I3-4330
Kingston HyperX Savage SSD

Last Edited: Thu. Feb 12, 2015 - 10:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But PB5 is the _RESET pin on a tiny25/45/85. So yes you can enable it as an IO (by enabling the RSTDISBL fuse) but you will never be able to ISP program the chip again because that requires the _RESET signal.

 

If you have a device that can do High Voltage Serial Programming (HVSP) and your design can cope with +12V being applied to the _RESET pin then you can consider enabling RSTDISBL. Otherwsie DO NOT DO IT!

 

Suitable programmers are STK500, Dragon, STK600 - all can do HVSP. If you don't own one of these do not change RSTDISBL.

 

It is often easier to write your code for an AVR with more pins (14, 28 or whatever) and then finally port it to the 8 pin device when it is finished (and as a final act enable RSTDISBL).