2017-05-06 105 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