我用的两块Mini板子,从机读取DS18B20的温度数据后传给主机,两块板子都用LCD显示数据。刚开始通信正常,但运行一会后主机会卡死,显示的温度数值是正常值的两倍(有时候还会抽风显示别的数),停止发送数据。希望大家能帮我看看
主机SPI.C
SPI_InitTypeDef SPI_InitStructure;
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //片选
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //
SPI_InitStructure.SPI_CRCPolynomial = 7; //
SPI_Init(SPI1, &SPI_InitStructure); //
SPI_Cmd(SPI1, ENABLE); //
}
//写一个字节
u8 SPI1_Write_Byte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
{
retry++;
if(retry>200)return 0;
} //
SPI_I2S_SendData(SPI1, TxData); //
return 0 ;
}
//读一个字节
u8 SPI_Read_Byte(u8 txdata)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
{
retry++;
if(retry>200)return 0;
} //
return SPI_I2S_ReceiveData(SPI1); //
}
主机主函数
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "key.h"
#include "spi.h"
u8 DataRx=0;
int main()
{
delay_init();
uart_init(9600);
LED_Init();
SPI1_Init();
LCD_Init();
KEY_Init();
POINT_COLOR=RED;
LCD_ShowString(60,50,200,16,16,"START");
while(1)
{
LCD_ShowString(60,70,200,16,16,"reading");
SPI1_Write_Byte(0x55); //主机写,从机读
DataRx=SPI_Read_Byte(0x00); //主机读,从机写
LCD_ShowNum(60,90,DataRx,2,16); //显示
LCD_ShowString(60,110,200,16,16,"read finish");
}
}
从机SPI.C
SPI_InitTypeDef SPI_InitStructure;
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_6);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //片选
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; //
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //
//SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7; //
SPI_Init(SPI1, &SPI_InitStructure); //
SPI_Cmd(SPI1, ENABLE);
}
//写一个字节
u8 SPI1_Write_Byte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
{
retry++;
if(retry>200)return 0;
} //
SPI_I2S_SendData(SPI1, TxData); //
return 0 ;
}
//读一个字节
u8 SPI_Read_Byte(u8 txdata)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
{
retry++;
if(retry>200)return 0;
} //
return SPI_I2S_ReceiveData(SPI1); //
}
从机主函数
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "ds18b20.h"
#include "spi.h"
short temperature;
u8 slave_temp=0;
int main(void)
{
delay_init();
uart_init(9600);
LED_Init();
SPI1_Init();
LCD_Init();
POINT_COLOR=RED;
while(DS18B20_Init()) // DS18B20初始化判断
{
LCD_ShowString(60,130,200,16,16,"DS18B20 Error");
delay_ms(200);
LCD_Fill(60,130,239,130+16,WHITE);
delay_ms(200);
}
LCD_ShowString(60,130,200,16,16,"DS18B20 OK");
POINT_COLOR=BLUE;//
LCD_ShowString(60,150,200,16,16,"Temp: . C");
while(1)
{
temperature=DS18B20_Get_Temp();
LCD_ShowNum(60+40+8,150,temperature/10,2,16); //
LCD_ShowNum(60+40+32,150,temperature%10,1,16); //
slave_temp=SPI_Read_Byte(0x00); //主机写,从机读
SPI1_Write_Byte(temperature/10); //主机读,从机写
LCD_ShowNum(60,170,slave_temp,1,16);
}
} |