为什么我的 SPI 通讯不工作? (Atmega644)
Why is not my SPI communication working? (Atmega644)
我正在构建一个鼓机,我已经存储了一个示例头文件,其中包含一个底鼓声音,其值介于 0 和 170 之间。我想通过 SPI 将它发送到一个 10 位 MCP4811 DAC,然后输出它连接到 3.5 毫米音频插孔。
我的 MISO、MOSI、SCK 和 RESET 引脚连接到我的 USB 编程器和 DAC。
这是 "samples.h"
中存储的音频文件的片段
unsigned const char sample_1[2221] PROGMEM = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, ...}
unsigned int sample_len[1] = {2221}
所以它是一个2221位的样本。我想使用频率 = 22 kHz 的 SPI 发送到 DAC。
我使用的是 16 MHz Crystal,因此我相应地设置了保险丝以使用它。
我正在使用溢出 22 kHz 的定时器。
volatile unsigned int sample_count[1] = {0};
volatile unsigned int audio_out = 0;
volatile unsigned char spi_junk;
int main (void)
sei();
DDRB = 0b10110000; //Set MOSI, SCK and SS as output.
PORTB = (1 << PINB4) //active low on SS.
TIMSK1 = (1<<OCIE1A); //Enable interrupt
TCCR1B = (1<<WGM12) | (1<<CS11); // set CTC mode and divide clk by 8
OCR1A = 91; //16 MHz/(8*91) ~ 22068 Hz
//SPI Init
SPCR = (1<<SPE) | (1<<MSTR); //master, 8 MHz
SPSR = (1<<SPI2X);
ISR (TIMER1_COMPA_vect) {
audio_out = 0;
//If play_track == 1, then the sound should be played back.
if (play_track && sample_count[0] < sample_len[0]){
audio_out += (pgm_read_byte(&(sample_1[sample_count[0]++)));
// send audio_out to 10-bit DAC on SPI
PORTB &= ~(1<<PINB4); // B.4 (DAC /CS)
SPDR = (char) ((audio_out >> 6) & 0x000f); //byte 1 0 0 0 0 b9 b8 b7 b6
while (!(SPSR & (1<<SPIF)));
spi_junk = SPDR;
SPDR = (char) ((audio_out & 0x003f) << 2); //byte 2 b5 b4 b3 b2 b1 b0 0 0
while (!(SPSR & (1<<SPIF)));
spi_junk = SPDR;
PORTB |= (1<<PINB4);
}
我的 PIN 设置是。
Atmega644 -> DAC
MOSI -> SDI
SCK -> SCK
SS -> /CS
在 MCP4811 上
Vdd -> 5V
Vss -> GND
V_out -> Audio jack.
MCP4811 上的其余引脚未连接任何东西。
我已经看到 audio_out 按预期工作,通过在 LCD 屏幕上显示 audio_out 值。但没有任何内容输出到 DAC。任何人都知道可能有什么问题吗?
编辑:添加了我错过添加的 SPI init。
您的代码中没有 SPI 初始化。
加入main()
SPSR = (1 << SPI2X); // double speed (to get maximum of 8MHz output)
SPCR = (1 << SPE) | (1 << MSTR); // 1:1 prescaler, master mode, SPI mode 0, SPI enable
另外对您的代码进行几点说明:
仅在所有初始化完成后使用sei()
,以避免在未初始化的外设上发生中断。
最好先将 PB4 设置为高电平,然后将其设置为输出,以避免在两个命令之间 PB 输出为低电平:
PORTB = (1 << PINB4) //active low on SS.
DDRB = 0b10110000; //Set MOSI, SCK and SS as output.
你的线路在这里
SPDR = (char) ((audio_out >> 6) & 0x000f); //byte 1 0 0 0 0 b9 b8 b7 b6
将 ¬SHDN 设置为 0,这将关闭 DAC
0 = Shutdown the device. Analog output is not available. VOUT pin is connected to 500 kohm typical)
改为将位 12 设置为 1
SPDR = (char) ((audio_out >> 6) & 0x0f)|0x10; //byte 1 0 0 0 1 b9 b8 b7 b6
来自数据表
1 = Active mode operation. VOUT is available.
我正在构建一个鼓机,我已经存储了一个示例头文件,其中包含一个底鼓声音,其值介于 0 和 170 之间。我想通过 SPI 将它发送到一个 10 位 MCP4811 DAC,然后输出它连接到 3.5 毫米音频插孔。
我的 MISO、MOSI、SCK 和 RESET 引脚连接到我的 USB 编程器和 DAC。
这是 "samples.h"
中存储的音频文件的片段unsigned const char sample_1[2221] PROGMEM = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, ...}
unsigned int sample_len[1] = {2221}
所以它是一个2221位的样本。我想使用频率 = 22 kHz 的 SPI 发送到 DAC。
我使用的是 16 MHz Crystal,因此我相应地设置了保险丝以使用它。
我正在使用溢出 22 kHz 的定时器。
volatile unsigned int sample_count[1] = {0};
volatile unsigned int audio_out = 0;
volatile unsigned char spi_junk;
int main (void)
sei();
DDRB = 0b10110000; //Set MOSI, SCK and SS as output.
PORTB = (1 << PINB4) //active low on SS.
TIMSK1 = (1<<OCIE1A); //Enable interrupt
TCCR1B = (1<<WGM12) | (1<<CS11); // set CTC mode and divide clk by 8
OCR1A = 91; //16 MHz/(8*91) ~ 22068 Hz
//SPI Init
SPCR = (1<<SPE) | (1<<MSTR); //master, 8 MHz
SPSR = (1<<SPI2X);
ISR (TIMER1_COMPA_vect) {
audio_out = 0;
//If play_track == 1, then the sound should be played back.
if (play_track && sample_count[0] < sample_len[0]){
audio_out += (pgm_read_byte(&(sample_1[sample_count[0]++)));
// send audio_out to 10-bit DAC on SPI
PORTB &= ~(1<<PINB4); // B.4 (DAC /CS)
SPDR = (char) ((audio_out >> 6) & 0x000f); //byte 1 0 0 0 0 b9 b8 b7 b6
while (!(SPSR & (1<<SPIF)));
spi_junk = SPDR;
SPDR = (char) ((audio_out & 0x003f) << 2); //byte 2 b5 b4 b3 b2 b1 b0 0 0
while (!(SPSR & (1<<SPIF)));
spi_junk = SPDR;
PORTB |= (1<<PINB4);
}
我的 PIN 设置是。
Atmega644 -> DAC
MOSI -> SDI
SCK -> SCK
SS -> /CS
在 MCP4811 上
Vdd -> 5V
Vss -> GND
V_out -> Audio jack.
MCP4811 上的其余引脚未连接任何东西。
我已经看到 audio_out 按预期工作,通过在 LCD 屏幕上显示 audio_out 值。但没有任何内容输出到 DAC。任何人都知道可能有什么问题吗?
编辑:添加了我错过添加的 SPI init。
您的代码中没有 SPI 初始化。
加入main()
SPSR = (1 << SPI2X); // double speed (to get maximum of 8MHz output)
SPCR = (1 << SPE) | (1 << MSTR); // 1:1 prescaler, master mode, SPI mode 0, SPI enable
另外对您的代码进行几点说明:
仅在所有初始化完成后使用sei()
,以避免在未初始化的外设上发生中断。
最好先将 PB4 设置为高电平,然后将其设置为输出,以避免在两个命令之间 PB 输出为低电平:
PORTB = (1 << PINB4) //active low on SS.
DDRB = 0b10110000; //Set MOSI, SCK and SS as output.
你的线路在这里
SPDR = (char) ((audio_out >> 6) & 0x000f); //byte 1 0 0 0 0 b9 b8 b7 b6
将 ¬SHDN 设置为 0,这将关闭 DAC
0 = Shutdown the device. Analog output is not available. VOUT pin is connected to 500 kohm typical)
改为将位 12 设置为 1
SPDR = (char) ((audio_out >> 6) & 0x0f)|0x10; //byte 1 0 0 0 1 b9 b8 b7 b6
来自数据表
1 = Active mode operation. VOUT is available.