avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fw: Fw: [avr-gcc-list] AVR UART as ANSI Terminal Interface


From: Ned Konz
Subject: Re: Fw: Fw: [avr-gcc-list] AVR UART as ANSI Terminal Interface
Date: Mon, 1 Nov 2004 11:54:15 -0800
User-agent: KMail/1.7

On Monday 01 November 2004 10:59 am, Royce & Sharal Pereira wrote:
> >    struct flag_bits
> >    {
> >       unsigned key: 1;
> >       unsigned ZCD: 1;
> >    } flg;
> >
> >    #define flg_key flg.key
> >    #define flg_ZCD flg.ZCD
> >
> > This way, the syntax of the code using the bits doesn't have to change.
> >
> >    flg_key = 1;
> >
> >    if (flg_ZCD) /* etc. */
>
> -------------------------------
> Can this method be used for ports & other SFRs which have predetermined
> addresses?

Yes.

I use this kind of code all the time. Here's the definition of an 8-bit wide 
port, ADMUX on an ATTiny26L:

typedef union
{
    unsigned char asByte;

    struct
    {
        unsigned char bMUX0:1;
        unsigned char bMUX1:1;
        unsigned char bMUX2:1;
        unsigned char bMUX3:1;
        unsigned char bMUX4:1;
        unsigned char :1;
        unsigned char bREFS0:1;
        unsigned char bREFS1:1;
    };
    struct
    {
        unsigned char bMUX:5;   // MUX0..4
        unsigned char bADLAR:1;
        unsigned char bREFS:2;  // REFS0, REFS1
    };
} ADCMUX_t;


#define ADCMUX ADCMUX_sfr.asByte
#define MUX0 ADCMUX_sfr.bMUX0
#define MUX1 ADCMUX_sfr.bMUX1
#define MUX2 ADCMUX_sfr.bMUX2
#define MUX3 ADCMUX_sfr.bMUX3
#define MUX4 ADCMUX_sfr.bMUX4
#define ADLAR  ADCMUX_sfr.bADLAR
#define REFS0 ADCMUX_sfr.bREFS0
#define REFS1 ADCMUX_sfr.bREFS1

// deal with 5-bit wide value at once:
#define ADCMUX_MUX ADCMUX_sfr.bMUX

// deal with 2-bit wide value at once:
#define ADCMUX_REFS ADCMUX_sfr.bREFS


Then you define ADCMUX_sfr using one of:

/* target specific address */
#define ADCMUX_sfr (*(volatile ADCMUX_t *) (0x27))

or

/* defined in separate assembly language file */
extern volatile ADCMUX_t ADCMUX_sfr;

or

/* somewhat better chance of handling common registers (PORTA, etc.) */
#define ADCMUX_sfr (*(volatile ADCMUX_t *)(_SFR_IO8(0x07)))


And use it like:

 ADCMUX |= 0x80;  /* as a byte variable */
 ADCMUX_MUX = 0x1f; /* a 5-bit wide bitfield */
 MUX1 = 0;    /* a single bit */


Which produces assembly language like this with no optimization:

  49:xxx.c         ****         ADCMUX |= 0x80;
  50                    .LM2:
  51 0008 8091 2700             lds r24,39
  52 000c 8068                  ori r24,lo8(-128)
  53 000e 8093 2700             sts 39,r24
  50:xxx.c         ****
  51:xxx.c         ****         ADCMUX_MUX = 0x1f;
  55                    .LM3:
  56 0012 8091 2700             lds r24,39
  57 0016 8F61                  ori r24,lo8(31)
  58 0018 8093 2700             sts 39,r24
  52:xxx.c         ****
  53:xxx.c         ****         MUX1 = 0;
  60                    .LM4:
  61 001c 8091 2700             lds r24,39
  62 0020 8D7F                  andi r24,lo8(-3)
  63 0022 8093 2700             sts 39,r24

and like this with optimization:

  49:xxx.c         ****         ADCMUX |= 0x80;
  50                    .LM2:
  51 0008 3F9A                  sbi 39-0x20,7
  50:xxx.c         ****
  51:xxx.c         ****         ADCMUX_MUX = 0x1f;
  53                    .LM3:
  54 000a 87B1                  in r24,39-0x20
  55 000c 8F61                  ori r24,lo8(31)
  56 000e 87B9                  out 39-0x20,r24
  52:xxx.c         ****
  53:xxx.c         ****         MUX1 = 0;
  58                    .LM4:
  59 0010 3998                  cbi 39-0x20,1

-- 
Ned Konz
http://bike-nomad.com



reply via email to

[Prev in Thread] Current Thread [Next in Thread]