STM32+max6675+hc06实现上位机与下位机分离的水温测量
本项目设计了一种基于STM32F1单片机的水温测量系统。
该系统由上位机和下位机两部分组成。上位机包括STM32单片机、蓝牙通信模块、LCD显示器和按键等;下位机包括STM32单片机、K型热电偶、MAX6675放大模块、继电器和LCD显示器等。
系统利用搭载MAX6675放大模块的K型热电偶传感器进行水温测量,并通过SPI传输协议将数据传送给下位机中的STM32单片机,并在LCD屏幕上显示。同时,下位机中的STM32单片机通过蓝牙通信模块将水温数据和继电器工作状态传送给上位机中的STM32单片机,并在LCD屏幕上显示。此外,上位机可以通过按键设定上下限温度和恒定温度,并通过蓝牙通信模块传送给下位机中的STM32单片机,以控制下位机中的继电器来控制水温。
实测可以测量水温在0-100范围内,精度在1℃以内。
文章目录
下位机
下位机主函数
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "w25qxx.h"
#define N 10
float value_buff[N]; //定义算术平均计算缓冲区
float nvalue_buff[N-2]; //定义去极值之后的缓冲区
int main(void)
{
extern u8 flag1;
extern u8 flag2,flag3;
double t;
double tp=0;
double adcData[10]={0.0};
float sum;
int i,major_col,minor_col,j,k;
double neo;
double temp;
// u8 key;
delay_init();
max6675_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为115200
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init(); //初始化LCD
KEY_Init(); //按键初始化
while(1)
{
HC06_receive();
sum=0;
tp=0;
t = max6675_readTemperature();
/*这里采用去极值平均滤波*/
for(i=0;i<10;i++)
{
adcData[i]=t;
}
for(i=0;i<N-1;i++)
{
for(j=0;j<N-i-1;j++)
{
if(adcData[j]>adcData[j+1])
{
temp=adcData[j];
adcData[j]=adcData[j+1];
adcData[j+1]=temp;
}
}
}
for(i=2;i<8;i++)
{
tp+=adcData[i];
}
/*****************/
if(tp/6<flag1)
{
GPIO_SetBits(GPIOC,GPIO_Pin_0);
GPIO_ResetBits(GPIOC,GPIO_Pin_1);
}
if(tp/6>flag2)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_0);
GPIO_SetBits(GPIOC,GPIO_Pin_1);
}
if(flag2-flag1!=2&&tp/6>=flag1+3&&tp/6<=flag2-3)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_0);
GPIO_ResetBits(GPIOC,GPIO_Pin_1);
}
LCD_ShowString(10,120,200,16,16,"the temperature is:");
LCD_ShowFloat(160,120,16,tp/6,3,2);
LCD_ShowString(10,150,200,16,16,"low temperature :");
LCD_ShowNum(160,150,flag1,2,16);
LCD_ShowString(10,180,200,16,16,"high temperature :");
LCD_ShowNum(160,180,flag2,2,16);
LCD_ShowString(10,210,200,16,16,"set temperature :");
LCD_ShowNum(160,210,flag3,2,16);
printf("%lf\r\n",tp/6);
delay_ms(500);
}
}
下位机max6675放大模块通过SPI和单片机通讯
PA5->SCK
PA6->SO
PA7->SI
#include "spi.h"
/**
* @brief 硬件spi1初始化
* @param None
* @retval None
*/
void spi1_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //PORTA时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //SPI1时钟使能
/* PA5 SPI1_SCK */
/* PA6 SPI1_MISO */
/* PA7 SPI1_MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PA5/6/7复用推挽输出 SPI
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第1个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //定义波特率预分频的值:波特率预分频值为256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI1, ENABLE); //使能SPI外设
}
/**
* @brief 设定spi1的速度
* @param SPI_BaudRatePrescaler:分频数 参数如下:
* SPI_BaudRatePrescaler_2 2分频
* SPI_BaudRatePrescaler_8 8分频
* SPI_BaudRatePrescaler_16 16分频
* SPI_BaudRatePrescaler_256 256分频
* @retval None
*/
void spi1_setSpeed(uint8_t SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI1->CR1&=0XFFC7;
SPI1->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度
SPI_Cmd(SPI1,ENABLE);
}
/**
* @brief 通过硬件spi1读写一个字节的数据
* @param txData:要发送的数据
* @retval 通过spi接收到的数据
*/
uint8_t spi1_readWriteByte(uint8_t txData)
{
uint8_t retry = 0;
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
{
retry++;
if(retry > 200) return 0;
}
SPI_I2S_SendData(SPI1, txData); //通过外设SPIx发送一个数据( 只有先发送数据才能使能SCK引脚产生时钟)
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
{
retry++;
if(retry > 200) return 0;
}
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}
max6675驱动模块代码
#include "MAX6675.h"
#include "spi.h"
/**
* @brief max66675模块初始化
* @param None
* @retval None
*/
void max6675_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(MAX6675_CS1_CLK, ENABLE); //PORTA时钟使能
GPIO_InitStructure.GPIO_Pin = MAX6675_CS1_PIN; // PA4 推挽 T_CS
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MAX6675_CS1_PORT, &GPIO_InitStructure);
GPIO_SetBits(MAX6675_CS1_PORT,MAX6675_CS1_PIN); // T_CS=1
spi1_init();
}
/**
* @brief max6675模块读写一个字节的数据
* @param txData:要发送的数据
* @retval 接收到的数据
*/
uint8_t max6675_readWriteByte(uint8_t txData)
{
return spi1_readWriteByte(txData);
}
/**
* @brief max6675模块读取测得的原始数据
* @param None
* @retval 温度的原始数据
*/
uint16_t max6675_readRawValue(void)
{
uint16_t tmp;
GPIO_ResetBits(MAX6675_CS1_PORT,MAX6675_CS1_PIN); //enable max6675
tmp = max6675_readWriteByte(0XFF); //read MSB
tmp <<= 8;
tmp |= max6675_readWriteByte(0XFF); //read LSB
GPIO_SetBits(MAX6675_CS1_PORT,MAX6675_CS1_PIN); //disable max6675
if (tmp & 4)
{
// thermocouple open
tmp = 2000; //未检测到热电偶
}
else
{
tmp = tmp >> 3;
}
return tmp;
}
对max6675模块采集到的数据进行数据分段拟合
/**
* @brief 对max6675模块做分段拟合
* @param None
* @retval 温度值(单位:℃)
*/
float max6675_readTemperature(void)
{
double T;
double temperature;
temperature = max6675_readRawValue();
if(0 < temperature && temperature <= 44)
T = 0.2786*temperature-1.9982;
else if(44 < temperature && temperature <= 80)
T= 0.2713*temperature- 1.7796;
else if(80 < temperature && temperature <= 121)
T= 0.2639*temperature - 1.3407;
else if(121 < temperature && temperature <= 156)
T=0.29*temperature-4.57;
else if(156 < temperature && temperature <= 190)
T=0.29*temperature-6.02;
else if(190 < temperature && temperature <= 226)
T=0.27*temperature-2.82;
else if(226 < temperature && temperature <= 276)
T=0.20*temperature+14.2;
else if(276 < temperature && temperature <= 314)
T=0.24*temperature+4.29;
else if(314 < temperature && temperature <= 355)
T=0.2419*temperature +4.0977;
else if(355 < temperature )
T=-0.0014*temperature*temperature +1.2583*temperature - 185.93;
return(T);
}
下位机蓝牙通讯
这里的flag1代表温度下限,flag2代表温度上限,flag3代表恒定温度。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "string.h"
#include "math.h"
#include "time.h"
//
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
u8 flag1=30,flag2=60,flag3=40;
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
/*使用microLib的方法*/
/*
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}
return ch;
}
int GetKey (void) {
while (!(USART1->SR & USART_FLAG_RXNE));
return ((int)(USART1->DR & 0x1FF));
}
*/
#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
void HC06_receive(void) //接收函数
{
u8 reclen=0;
if(USART_RX_STA&0X8000) //接收到一次数据了
{
reclen=USART_RX_STA&0X7FFF; //得到数据长度
USART_RX_BUF[reclen]=0; //加入结束符
if(strcmp(USART_RX_BUF,"1")==0&&flag1<=flag2)//舵机1开闭
{
flag1+=5;
printf("flag1\r\n");
}
if(strcmp(USART_RX_BUF,"2")==0&&flag1<flag2) //继电器开
{
flag1-=5;
printf("flag2\r\n");
}
if(strcmp(USART_RX_BUF,"3")==0&&flag1<=flag2)//继电器关,舵机2开闭
{
flag2+=5;
printf("flag3\r\n");
}
if(strcmp(USART_RX_BUF,"4")==0&&flag1<=flag2)//继电器关,舵机2开闭
{
flag2-=5;
printf("flag4\r\n");
}
if(strcmp(USART_RX_BUF,"5")==0&&flag1<=flag2)//继电器关,舵机2开闭
{
flag3+=1;
flag1=flag3-1;
flag2=flag3+1;
printf("flag5\r\n");
// printf("jidianqi4\r\n");
}
if(strcmp(USART_RX_BUF,"6")==0&&flag1<=flag2)//继电器关,舵机2开闭
{
flag3-=1;
flag1=flag3-1;
flag2=flag3+1;
printf("flag6\r\n");
// printf("jidianqi4\r\n");
}
if(flag1>flag2)
{
flag1-=10;
printf("flag1\r\n");
}
USART_RX_STA=0;
}
}
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
#endif
上位机
上位机主函数
这里采用6个按键对上下限温度与恒定温度进行设置
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
int main(void)
{
extern u8 flag1;
extern u8 flag2,flag3;
vu8 key=0;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
LED_Init(); //LED端口初始化
KEY_Init(); //初始化与按键连接的硬件接口
LCD_Init();
LCD_ShowString(10,60,200,16,16,"the temperature is:");
LCD_ShowString(10,90,200,16,16,"low temperature :");
LCD_ShowString(10,120,200,16,16,"high temperature :");
LCD_ShowString(10,150,200,16,16,"set temperature :");
while(1)
{
HC06_receive();
key=KEY_Scan(0); //得到键值
if(key)
{
switch(key)
{
case KEY0_PRES:
printf("1\r\n");
break;
case KEY1_PRES:
printf("2\r\n");
break;
case KEY2_PRES:
printf("3\r\n");
break;
case KEY3_PRES:
printf("4\r\n");
break;
case KEY4_PRES:
printf("5\r\n");
break;
case KEY5_PRES:
printf("6\r\n");
break;
}
}
}
}
上位机蓝牙通讯
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "string.h"
#include "math.h"
#include "time.h"
#include "lcd.h"
//
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
u8 flag1=30,flag2=60,flag3=40;
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
void HC06_receive(void) //接收函数
{
u8 reclen=0;
double t;
if(USART_RX_STA&0X8000) //接收到一次数据了
{
reclen=USART_RX_STA&0X7FFF; //得到数据长度
USART_RX_BUF[reclen]=0; //加入结束符
if(strcmp(USART_RX_BUF,"flag1")==0&&flag1<=flag2)
{
flag1+=5;
}
else if(strcmp(USART_RX_BUF,"flag2")==0&&flag1<=flag2)
{
flag1-=5;
}
else if(strcmp(USART_RX_BUF,"flag3")==0&&flag1<=flag2)
{
flag2+=5;
}
else if(strcmp(USART_RX_BUF,"flag4")==0&&flag1<=flag2)
{
flag2-=5;
}
else if(strcmp(USART_RX_BUF,"flag5")==0&&flag1<=flag2)
{
flag3+=1;
flag1=flag3-1;
flag2=flag3+1;
}
else if(strcmp(USART_RX_BUF,"flag6")==0&&flag1<=flag2)
{
flag3-=1;
flag1=flag3-1;
flag2=flag3+1;
}
else if(flag1>flag2)
{
flag1-=10;
}
else
{
t=strtod(USART_RX_BUF,NULL);
LCD_ShowFloat(160,60,16,t,3,2);
LCD_ShowNum(160,90,flag1,2,16);
LCD_ShowNum(160,120,flag2,2,16);
LCD_ShowNum(160,150,flag3,2,16);
if(t<flag1)
{
LCD_ShowString(10,180,200,16,16,"heating ");
}
if(t>flag2)
{
LCD_ShowString(10,180,200,16,16,"cooling ");
}
if(flag2-flag1!=2&&t>=flag1+3&&t<=flag2-3)
{
LCD_ShowString(10,180,200,16,16,"no working");
}
}
USART_RX_STA=0;
}
}
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
#endif