移位寄存器使用ATMEGA328p

时间:2017-05-06 20:26:18

标签: c atmega

我想了解更多关于Arduinos使用的shiftout函数,并使用我的ATMEGA328p实现。

设置

#define F_CPU 1000000UL
#define BAUD 9600UL
#define LSBFIRST 0
#define MSBFIRST 1
#define HIGH 0x1
#define LOW  0x0
#define INPUT 0x0
#define OUTPUT 0x1

#include <avr/io.h>
#include <util/delay.h>
#include <USART.h>
#include <pinDefines.h>

#define DATA PD7
#define LATCH PB2
#define CLOCK PB0

uint8_t leds = 0;

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    for (uint8_t i = 0; i < 8; ++i) {
        if (bitOrder == LSBFIRST) { 
            PORTD |= (!!(val & (HIGH << i)) << DATA);
        } else {
            PORTD |= (!!(val & (HIGH << (7 - i))) << DATA);
        }

        PORTB |= (HIGH << clockPin);
        PORTB |= (LOW << clockPin);
    }
}

void updateShiftRegister() {
    PORTB |= (LOW << LATCH);
    shiftOut(DATA, CLOCK, LSBFIRST, leds);
    PORTB |= (HIGH << LATCH);
}

void setupRegisters() {
    DDRD = 0xff;
    DDRB = 0xff;
}


int main(void)
{
    setupRegisters();
    leds = 1;
    updateShiftRegister();
    _delay_ms(2000);
    leds = 0;
    updateShiftRegister();

    return (0);
}

我创建了一个示例来了解有关该函数的更多信息,但结果并没有达到我预期的效果。

根据我的例子,我预计LED1会在2秒后开启并关闭。它打开,但之后不会关闭。我错过了什么吗?我正在搜索我的代码中的错误2小时。

1 个答案:

答案 0 :(得分:0)

DDRD是&#34;数据方向寄存器D&#34;。如果要将整个端口D用作输出,则应将其设置为0xFF,否则将其中的一部分用作输入,这是导致意外结果的原因。

我还没有检查过,但是端口D可能不仅仅是通用数字I / O(例如JTAG)使用了什么来覆盖PORTD设置。请阅读the datasheet。顺便说一下,还有一些示例程序。