使用没有SPI引脚的AVR ATMEGA32 SPI
-
21-12-2019 - |
题
我对编程微控制器很开心。我有一些arduino的经历,但在我几乎完成了我的项目之后,我判断我目前的项目将我的目前的项目搬到更便宜和更小。所以我现在使用Avr Atmega32与Atmel Studio。
我正在尝试使用Atmega32与MAX7219芯片进行通信,以通过LED矩阵复用。但是,我确实有多个不同的设备,我想与之沟通。
如何在没有实际使用微控制器上提供的SPI引脚的情况下与设备通信?我已经做出了一个测试项目,但似乎有问题,我无法弄清楚这个问题是什么。我想我设法在测试模式下获得它,因为所有LED都被点亮,但我无法在此之后做任何事情。我甚至无法清除显示/关闭它。我已经检查了接线。我的编码可能是不正确的,也可能是引脚配置和分配引脚吗?有任何建议还是更好地编写我的代码?
以下是 ma7219数据表
//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
}
. 解决方案
是的,您的位爆炸代码呈现出每次分配寄存器的整个值,而无需保留现有值。因此,您可以在您驾驶时钟的即时删除数据信号,违反接收器的保持时间并导致不可预测的操作。
而不是使用=
分配引脚,您应该将它们设置为|=
或用&= ~(value)
清除它们
例如:
PORTB = 1 << PINB0; //drive data
// tick
PORTB |= 1 << PINB1; //clock high PRESERVING data
// tock
PORTB &= ~(1 << PINB1); //clock low
.
您可能还需要在引脚操作之间插入轻微的延迟。
技术上,鉴于您已经使用了数据状态的生成古代码,您还可以使用赋值或在分配中重新驱动数据信号,例如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;
}
. 不隶属于 StackOverflow