AIDA64设置
文件->设置->LCD
一、
选择一种LCD屏幕,但没有也没事,不同选项的区别主要在于串口数据包格式不同,这里我选择的是Pertelian。LCD端口号选择当前单片机连接到的端口号,LCD类型是屏幕大小,我用的是0.96英寸的OLED屏幕,所以选择16*4。
二、
在右下侧的“新建”处添加想要监视的性能信息,比如新建内存使用率,此时界面如下:
发送中文会出现乱码,因此Label为Mem,同时在Unit加上“@”方便确定每一行尾部。修改后如下:
依次添加想要的信息,最后点击应用。
三、
使用串口监控软件查看串口数据包的格式。
可以看到每一行信息均以0xFE为第一个字节,表示一行的开始,而第二个字节标志了当前数据属于第几行,最后则以0x40,即“@”(先前在Unit选项中自行添加)结束。将每一行信息看作一个Hex数据包,利用状态机的形式处理每一行信息。
代码
Serial.c
#include "stm32f10x.h"
uint8_t RxFlag; //中断标志位
char Serial_RxPacket_CPU[20]; //第一行信息
char Serial_RxPacket_Mem[20]; //第二行信息
char Serial_RxPacket_CPUTemp[20]; //第三行信息
char Serial_RxPacket_GPUTemp[20]; //第四行信息
void Serial_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //串口输出端口初始化
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //串口输入端口初始化
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure; //串口初始化
USART_InitStructure.USART_BaudRate=9600; //波特率9600
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //无硬件流控制
USART_InitStructure.USART_Mode=USART_Mode_Rx; //串口模式为接收模式
USART_InitStructure.USART_Parity=USART_Parity_No; //无校验
USART_InitStructure.USART_StopBits=USART_StopBits_1; //停止位1位
USART_InitStructure.USART_WordLength=USART_WordLength_8b; //串口字长8位
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1,ENABLE);
}
void USART1_IRQHandler()
{
if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){
static uint8_t RxState=0; //状态机的状态,初始状态为0
static uint8_t RxDataNum=0; //字符串下标
uint8_t RxData=USART_ReceiveData(USART1);//当前接收到的字节
switch(RxState){ //根据当前状态机的状态选择处理方式
case 0:
if(RxData==0xFE){ //每一行信息,即每一个数据包的起始字节
RxState=1; //变更状态为1,同时设置下标为0
RxDataNum=0;
}
break;
case 1:
if(RxData==0x80) //若第二个字节为0x80,则为第一行数据,转为状态2
RxState=2;
else if(RxData==0xC0) //若第二个字节为0xC0,则为第二行数据,转为状态3
RxState=3;
else if(RxData==0x94) //若第二个字节为0x94,则为第三行数据,转为状态4
RxState=4;
else if(RxData==0xD4) //若第二个字节为0xD4,则为第一行数据,转为状态5
RxState=5;
break;
case 2:
if(RxData==0x40) //如果接收到0x40,则表示当前行的信息接收完毕,转为状态6
RxState=6;
else //否则将当前数据添加至字符串
Serial_RxPacket_CPU[RxDataNum++]=RxData;
break;
case 3:
if(RxData==0x40) //如果接收到0x40,则表示当前行的信息接收完毕,转为状态7
RxState=7;
else
Serial_RxPacket_Mem[RxDataNum++]=RxData;
break;
case 4:
if(RxData==0x40) //如果接收到0x40,则表示当前行的信息接收完毕,转为状态8
RxState=8;
else
Serial_RxPacket_CPUTemp[RxDataNum++]=RxData;
break;
case 5:
if(RxData==0x40) //如果接收到0x40,则表示当前行的信息接收完毕,转为状态9
RxState=9;
else
Serial_RxPacket_GPUTemp[RxDataNum++]=RxData;
break;
case 6:
Serial_RxPacket_CPU[RxDataNum]='\0'; RxState=0; RxFlag=1; break; //在字符串末尾添'\0'表示结束,同时恢复状态为0,并变更中断标志位
case 7:
Serial_RxPacket_Mem[RxDataNum]='\0'; RxState=0; RxFlag=1; break;
case 8:
Serial_RxPacket_CPUTemp[RxDataNum]='\0'; RxState=0; RxFlag=1; break;
case 9:
Serial_RxPacket_GPUTemp[RxDataNum]='\0'; RxState=0; RxFlag=1; break;
}
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
}
main.c
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "Serial.h"
extern uint8_t RxFlag;
extern char Serial_RxPacket_CPU[20];
extern char Serial_RxPacket_Mem[20];
extern char Serial_RxPacket_CPUTemp[20];
extern char Serial_RxPacket_GPUTemp[20];
int main()
{
OLED_Init();
Serial_Init();
while(1){
if(RxFlag==1){
OLED_ShowString(1,1," ");
OLED_ShowString(1,1,Serial_RxPacket_CPU);
OLED_ShowString(2,1," ");
OLED_ShowString(2,1,Serial_RxPacket_Mem);
OLED_ShowString(3,1," ");
OLED_ShowString(3,1,Serial_RxPacket_CPUTemp);
OLED_ShowString(4,1," ");
OLED_ShowString(4,1,Serial_RxPacket_GPUTemp);
}
RxFlag=0;
}
}
效果
不足:接收信息部分的代码有很大的优化空间。