基于stm32+oled显示屏+AIDA64的电脑性能监视器

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;
	}
}

效果

在这里插入图片描述
不足:接收信息部分的代码有很大的优化空间。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值