2017-05-06 181 views
1

我想了解更多关于与Arduinos配合使用的移位功能,以及使用ATMEGA328p实现的移位功能。使用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小时现在的代码中的错误。

回答

0

DDRD是“数据方向寄存器D”。如果你想使用整个端口D作为输出,你应该把它设置为0xFF,否则其中的一部分被用作输入,是什么原因导致你未预料到的结果。

我还没有检查过,但有可能Port D的用途不仅仅是通用数字I/O(例如通过JTAG),它会覆盖PORTD的设置。刚刚阅读the datasheet。顺便说一下,还有一些示例程序。

+0

嗨!我试过了,但没有改变。这是我修改过的代码,以便清理一下。为什么不关闭LED? – sesc360

+0

尝试调试代码。所以首先检查一下,是否可以正确设置输出引脚(例如'DDRD = 0xFF; PORTD = 0xAA')。如果是这样,那么开始检查命令的其余命令。顺便说一下,'PORTB | =(LOW << clockPin)'是错误的。你想要的是'PORTB&=〜(1 << clockPin)' – yar

+0

顺便说一句,你在错误的论坛。 Thry在https://embdev.net/forum/microcontrollers发帖 – yar