使用没有SPI引脚的AVR Atmega32 SPI

时间:2014-06-04 04:19:40

标签: avr spi atmega atmelstudio

我是编程微控制器的新手。我对Arduino有一些经验,但在我几乎完成了我的项目之后,我决定将我目前的项目转移到更便宜和更小的东西上。所以我现在正在使用AVR ATmega32与Atmel工作室。

我试图使用ATmega32与MAX7219芯片进行通信,以便与led矩阵进行复用。但是,我确实有多个不同的设备要与之通信。

如何在不实际使用微控制器上提供的SPI引脚的情况下与器件通信?我做了一个测试项目,但似乎有些不对劲,我无法弄清楚问题是什么。我想我已经设法在测试模式下,因为所有LED都点亮了,但在此之后我无法做任何事情。我甚至无法清除显示屏/关闭它。我再次检查了接线。就引脚配置和分配引脚而言,我的编码可能不正确吗?是否有任何建议或更好的方式来编写我的代码?

以下是MA7219 datasheet

的链接
//test

#include <avr/io.h>


int main(void)
{

DDRB = 0b00000111; // pin 1(data), 2(clock) and 3(latch) are outputs

PORTB = 0 << PINB0; // data pin 1 is low
PORTB = 0 << PINB1; // clock pin 2 is low
PORTB = 0 << PINB2; // latch pin 3 is low

uint16_t data;
data = 0b0000110000000000; // data to shift out to the max7219

 //read bit
uint16_t mask;
 for (mask = 0b0000000000000001; mask>0; mask <<= 1) 
{ 
    //iterate through bit mask
    if (data & mask)
    { // if bitwise AND resolves to true
        // send one
        PORTB = 1 << PINB0;
        // tick
        PORTB = 1 << PINB1;
        // tock
        PORTB = 0 << PINB1;
    }
     else{ //if bitwise and resolves to false
        // send 0
        // send one
        PORTB = 0 << PINB0;
        // tick
        PORTB = 1 << PINB1;
        // tock
        PORTB = 0 << PINB1;
    }

}

PORTB = 1 << PINB2; // latch all the data
PORTB = 1 << PINB0; // data pin 1 is high
PORTB = 0 << PINB1; // clock pin 2 is low
PORTB = 0 << PINB2; // latch pin 3 is low
}

1 个答案:

答案 0 :(得分:2)

是的,您的bit-bang代码存在一个问题,即您每次都会分配寄存器的整个值而不保留现有值。因此,您在驱动时钟时会擦除数据信号,从而违反接收器的保持时间并导致不可预测的操作。

您应该使用=设置引脚,或者使用|=

清除它们,而不是使用&= ~(value)分配引脚

例如:

     PORTB = 1 << PINB0;      //drive data
    // tick
    PORTB |= 1 << PINB1;      //clock high PRESERVING data
    // tock
    PORTB &= ~(1 << PINB1);   //clock low

您可能还需要在引脚操作之间插入一点延迟。

从技术上讲,鉴于您已经使用if作为数据状态,您还可以在分配中使用OR重新驱动数据信号,例如

if (data & mask)
{ // if bitwise AND resolves to true
    // send one
    PORTB = 1 << PINB0;
    // tick
    PORTB = (1 << PINB1) | (1 << PINB0);
    // tock
    PORTB = 0 << PINB1 | (1 << PINB0);
}
 else{ //if bitwise and resolves to false
    // send 0
    // send one
    PORTB = 0 << PINB0;
    // tick
    PORTB = 1 << PINB1;
    // tock
    PORTB = 0 << PINB1;
}