[Top][All Lists]

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

[avr-gcc-list] Simple Problem

From: Kris
Subject: [avr-gcc-list] Simple Problem
Date: Wed, 24 Sep 2003 01:37:54 -0400

I've been experimenting with the at90s2313. I've gotten the hardware and
software setup and have successfully programmed the device using gcc.
However, for the life of me, I've not figured out how to perform one of the
simplest operations, reading a port bit. Strangely, the avr-gcc docs never
actually explain how to do this, so I'm assuming it's so rediculously simple
that I must be missing something. I've searched Google and the docs for
hours, and while I learned how to setup an I2C bus, poll data from the UART,
and vary PWM, simply reading in a single bit elludes me.

So here's my setup. I've basically modified one of the examples included
with WinAVR, demo.c, to mirror the change to PB0 on an LED on PB1 while
using PWM to pulse an LED on PB3. When PB0 is wired to +5V, PB1 should be
set high. When PB0 is wired to ground, PB1 should be set low. PB3 should be
pulsing the entire time.

What follows is my code:

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define OC1 PB3
#define OCR OCR1
#define DDROC DDRB
#if defined(COM11)
#  define XCOM11 COM11
#elif defined(COM1A1)
#  define XCOM11 COM1A1
#  error "need either COM1A1 or COM11"

enum { UP, DOWN };

volatile uint16_t pwm;
volatile uint8_t direction;

typedef unsigned char  u08;

{//do stuff during interrupt

    switch (direction)
        case UP:
            if (++pwm == 1023)
                direction = DOWN;

        case DOWN:
            if (--pwm == 0)
                direction = UP;
 OCR = pwm;

ioinit (void)
    /* tmr1 is 10-bit PWM */
    TCCR1A = _BV (PWM10) | _BV (PWM11) | _BV (XCOM11);

    /* tmr1 running on full MCU clock */
    TCCR1B = _BV (CS10);

    /* set PWM value to 0 */
    OCR = 0;

    /* enable OC1 and PB2 as output and B0 and B1 as inputs*/
 DDROC = 0x00;//set all bits as inputs
    DDROC |= _BV (OC1) | _BV(PB1);//set b3 and b1 as output
 PORTB = 0xff;//turn all bits on

    timer_enable_int (_BV (TOIE1));

    /* enable interrupts */
    sei ();

main (void)
    ioinit ();

    /* loop forever, the interrupts are doing the rest */

    for (;;){
  if(bit_is_set(PORTB,0)){//if pb0 is on
  PORTB |= PB1;//turn pb1 on
  PORTB &= ~PB1;//turn pb1 off


    return (0);

It compiles fine, and pulses PB3 perfectly, but seems to completely ignore
the changing input values on port B. I've tried several different settings
for DDRB, reading from different macros, and even reading from PINB. Nothing
seems to work. What am I doing wrong? Any help would be greatly appreciated.

reply via email to

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