[Top][All Lists]
[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