/******************************************************************************/
/***************************SPI通訊,MASTER程序********************************/
/***************************目標MCU:MEGA8L************************************/
/**************************外部晶振3.6864MHz***********************************/
/******************************************************************************/
/**********************************引腳連接************************************/
/********************** MASTER MISO ---- SLAVE MISO ***************************/
/********************** MASTER MOSI ---- SLAVE MOSI ***************************/
/********************** MASTER SCK ---- SLAVE SCK ***************************/
/********************** MASTER /SS ---- SLAVE /SS ***************************/
/******************************************************************************/
#include <iom8v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define DDR_SPI DDRB
#define MOSI 3
#define MISO 4
#define SCK 5
#define SS 2
#define PORT_SPI PORTB
#define LED_RED_ON PORTB|=BIT(0)
#define LED_RED_OFF PORTB&=~BIT(0)
#define LED_RED_OUTPUT DDRB|=BIT(0)
#define LED_BLUE_ON PORTD|=BIT(7)
#define LED_BLUE_OFF PORTD&=~BIT(7)
#define LED_BLUE_OUTPUT DDRD|=BIT(7)
/********************************SPI初始化*************************************/
void SPI_Init(void)
{
DDR_SPI|=(1<<MOSI)|(1<<SCK);
SPCR=(1<<SPE)|(1<<DORD)|(1<<MSTR)|(1<<SPR0);//主,LSB在先
SPSR=0;
//SPCR|=(1<<SPIE);
}
#pragma interrupt_handler spi_stc_isr:11
void spi_stc_isr(void)
{
LED_BLUE_OUTPUT;
LED_BLUE_ON;
SPDR=0xaa;
//SPCR&=~(1<<SPIE);
}
/********************************SPI SEND**************************************/
void SPI_Send(uchar command)
{
DDR_SPI|=(1<<SS);
PORT_SPI|=(1<<SS);
//SPCR|=(1<<MSTR);
SPCR|=(1<<SPIE);//開SPI中斷
}
/***********************************MAIN***************************************/
void main(void)
{
Delay_ms(100);
LED_RED_OUTPUT;
LED_RED_OFF;
LED_BLUE_OUTPUT;
LED_BLUE_OFF;
SPI_Init();
SEI();
while(1)
{
Delay_ms(2000);
LED_RED_ON;
SPI_Send(0xaa);
Delay_ms(2000);
LED_BLUE_OUTPUT;
LED_BLUE_OFF;
LED_RED_OFF;
SEI();
}
}
偶的本意是想實現每次SPI中斷后蘭色LED點亮,延時2秒在啟動一次SPI中斷。
偶現在的問題是發現:
1,按照這個程序,第一次中斷能進去,但以后不行了。現象是2秒后蘭色的LED與紅色的LED一起亮,再過2秒一起暗掉,然后就是紅色的開始每隔2秒閃了,而蘭色的不動作,說明SPI中斷進不了了;
2,如果SPI初始化程序里就進行允許SPI中斷,則一上電蘭色的LED就亮,過了會就滅了,然后蘭色的一直不亮,說明SPI中斷也是進不了;
3,后來又調試了幾次,發現必須要把MSTR再設置一下,也就是在發送的子程序里重新設置一下,但這樣的結果是蘭色的LED一直亮,紅色的LED到是交替閃爍,偶搞不明白,偶就在SPI中斷里設置了點亮蘭色的LED,主程序里隔2秒就關掉蘭色LED的,為什么會沒關掉???
4,如果中斷里最后加上關掉SPI,發送子程序里加上重新設置MSTR,就得到了偶想要的那個紅色與蘭色LED同時亮滅的效果,這又是為什么啊,為什么MSTR要重新設置一下?
偶實驗的時候,SPI的那幾個口什么都沒接,SS腳也已經設置成輸出高電平,不會有被拉低的可能啊。
DATASHEET上寫:
When the SPI is configured as a master (MSTR in SPCR is set), the user can determine
the direction of the SS pin.
If SS is configured as an output, the pin is a general output pin which does not affect the
SPI system. Typically, the pin will be driving the SS pin of the SPI slave.
If SS is configured as an input, it must be held high to ensure Master SPI operation. If
the SS pin is driven low by peripheral circuitry when the SPI is configured as a master
with the SS pin defined as an input, the SPI system interprets this as another master
selecting the SPI as a slave and starting to send data to it. To avoid bus contention, the
SPI system takes the following actions:
1. The MSTR bit in SPCR is cleared and the SPI system becomes a slave. As a
result of the SPI becoming a slave, the MOSI and SCK pins become inputs.
2. The SPIF flag in SPSR is set, and if the SPI interrupt is enabled, and the I-bit in
SREG is set, the interrupt routine will be executed.
按照DATASHEET,主的時候MSTR設置,如果SS被設置為輸入,且在MSTR為“1“時被外部拉低,則MSTR會被清除,但是偶SS一直設置成輸出高電平,不存在被拉低的可能啊,兩個困惑的小疑問,或許某一天的將來豁然開朗。
|