通常SPI通过4个引脚与外部器件相连:
前三个硬件控制,最后一个软件模拟(功能简单,外设多的时候需要多根)
● MISO:主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据。
● MOSI:主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据。
● SCK:串口时钟,作为主设备的输出,从设备的输入
● NSS:从设备选择。这是一个可选的引脚,用来选择主/从设备。它的功能是用来作为“片
选引脚”,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。从设备的NSS
引脚可以由主设备的一个标准I/O引脚来驱动。一旦被使能(SSOE位),NSS引脚也可以作为
输出引脚,并在SPI处于主模式时拉低;此时,所有的SPI设备,如果它们的NSS引脚连接
到主设备的NSS引脚,则会检测到低电平,如果它们被设置为NSS硬件模式,就会自动进
入从设备状态。当配置为主设备、NSS配置为输入引脚(MSTR=1,SSOE=0)时,如果NSS
被拉低,则这个SPI设备进入主模式失败状态:即MSTR位被自动清除,此设备进入从模式
时钟信号的相位和极性&数据帧格式为了应对与不同的外设
#define MAX6675_CS_LOW GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET)
#define MAX6675_CS_HIGH GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET)
void SPI1_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
//PA4:CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PA5:SCK
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PA6:MISO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PA7:MOSI
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
//根据外设来选择
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
u16 SPI_read(void)
{
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, 0x00);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI1);
}
u16 temp;
u8 flag;//热电偶是否正常工作
float temperature;
while (1)
{
MAX6675_CS_LOW;
temp = SPI_read();
MAX6675_CS_HIGH;
flag = (temp & 0x4);
if (!flag)
{
// 去除第三位到14位 温度
temp <<= 1;
temp >>= 4;
temperature = temp * 0.25;
printf("Temperature = %4.2f\n",temperature);
}
else
{
printf("Sensor is borken!\n");
}
Delay_us(100000);
}