技能梳理7@stm32+OLED+flash掉电保存+按键

124 阅读2分钟

学校违纪分数记录,按键,1.3寸OLED显示,数据掉电保存

1、项目简介

在这里插入图片描述

2、实现逻辑

在这里插入图片描述
#如上图为显示屏显示内容
#三个物理按键,一个是选择对哪一项进行控制,两个是加减对应项的分数
#控制范围±10,精度0.1
#对所有分数进行求和运算然后显示
#将所有数据保存到单片机flash

3、应用场景

#对学生违纪情况进行记录

4、核心代码梳理

int8_t big_small(int32_t value, uint8_t handle)
{
    if(handle)//++
    {
        if(value < 100)
            value++;
    }
    else//--
    {
        if(value > -100)
            value--;
    }
    return value;
}



uint32_t addr = 0x08007000;

//FLASH写入数据测试
void writeFlashTest(void)
{
    //1、解锁FLASH
    HAL_FLASH_Unlock();

    //2、擦除FLASH
    //初始化FLASH_EraseInitTypeDef
    FLASH_EraseInitTypeDef f;
    f.TypeErase = FLASH_TYPEERASE_PAGES;
    f.PageAddress = addr;
    f.NbPages = 1;
    //设置PageError
    uint32_t PageError = 0;
    //调用擦除函数
    HAL_FLASHEx_Erase(&f, &PageError);

    //3、对FLASH烧写
    HAL_FLASH_Program(TYPEPROGRAM_WORD, addr, Wei_Ji);
    HAL_FLASH_Program(TYPEPROGRAM_WORD, addr+10, SuShe_WeiSheng);
    HAL_FLASH_Program(TYPEPROGRAM_WORD, addr+20, JiaoShi_WeiSheng);
    HAL_FLASH_Program(TYPEPROGRAM_WORD, addr+30, Pao_Cao);
    //4、锁住FLASH
    HAL_FLASH_Lock();
}


    OLED_Init();
    OLED_ColorTurn(0);//0正常显示,1 反色显示
    OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
    OLED_Refresh();
    OLED_Clear();
    //OLED_ShowString(0,0," weiji:   .    C ",16);
    OLED_ShowChinese(2,0,0,16); //一个汉字横15个格 冒号加12  竖加16
    OLED_ShowChinese(17,0,1,16);
    OLED_ShowChinese(29,0,2,16);

    OLED_ShowChinese(2,16,3,16);
    OLED_ShowChinese(17,16,4,16);
    OLED_ShowChinese(32,16,7,16);
    OLED_ShowChinese(47,16,8,16);
    OLED_ShowChinese(59,16,2,16);

    OLED_ShowChinese(2,32,5,16);
    OLED_ShowChinese(17,32,6,16);
    OLED_ShowChinese(32,32,7,16);
    OLED_ShowChinese(47,32,8,16);
    OLED_ShowChinese(59,32,2,16);

    OLED_ShowChinese(2,48,9,16);
    OLED_ShowChinese(17,48,10,16);
    OLED_ShowChinese(29,48,2,16);

    OLED_ShowChinese(70,48,11,16);
    OLED_ShowChinese(85,48,12,16);
    OLED_ShowChinese(97,48,2,16);

    OLED_Refresh();

    Wei_Ji = *(__IO uint32_t*)(addr);
    SuShe_WeiSheng = *(__IO uint32_t*)(addr+10);
    JiaoShi_WeiSheng = *(__IO uint32_t*)(addr+20);
    Pao_Cao = *(__IO uint32_t*)(addr+30);
    writeFlashTest();

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        HAL_Delay(5);
        if(!HAL_GPIO_ReadPin(GPIOA, SET_Pin))
            set_a++;
        else
            set_a = 0;

        if(!HAL_GPIO_ReadPin(GPIOB, BIG_Pin))
            big_a++;
        else
            big_a = 0;

        if(!HAL_GPIO_ReadPin(GPIOB, SMALL_Pin))
            small_a++;
        else
            small_a = 0;

        if(set_a==5)
        {
            set_a = 0;
            set_num++;
            set_num = set_num%5;
        }
        if(big_a==5)
        {
            big_a = 0;

            if(set_num == 1)
                Wei_Ji = big_small(Wei_Ji, 1);
            else if(set_num == 2)
                SuShe_WeiSheng = big_small(SuShe_WeiSheng, 1);
            else if(set_num == 3)
                JiaoShi_WeiSheng = big_small(JiaoShi_WeiSheng, 1);
            else if(set_num == 4)
                Pao_Cao = big_small(Pao_Cao, 1);

            writeFlashTest();

        }
        if(small_a==5)
        {
            small_a = 0;

            if(set_num == 1)
                Wei_Ji = big_small(Wei_Ji, 0);
            else if(set_num == 2)
                SuShe_WeiSheng = big_small(SuShe_WeiSheng, 0);
            else if(set_num == 3)
                JiaoShi_WeiSheng = big_small(JiaoShi_WeiSheng, 0);
            else if(set_num == 4)
                Pao_Cao = big_small(Pao_Cao, 0);

            writeFlashTest();
        }

        if(set_num == 0)
        {
            OLED_ShowChinese(29,0,2,16);
            OLED_ShowChinese(59,16,2,16);
            OLED_ShowChinese(59,32,2,16);
            OLED_ShowChinese(29,48,2,16);
        }
        else if(set_num == 1)
        {
            OLED_ShowString(29,0,".",12);
            OLED_ShowChinese(59,16,2,16);
            OLED_ShowChinese(59,32,2,16);
            OLED_ShowChinese(29,48,2,16);
        }
        else if(set_num == 2)
        {
            OLED_ShowChinese(29,0,2,16);
            OLED_ShowString(59,16,".",12);
            OLED_ShowChinese(59,32,2,16);
            OLED_ShowChinese(29,48,2,16);
        }
        else if(set_num == 3)
        {
            OLED_ShowChinese(29,0,2,16);
            OLED_ShowChinese(59,16,2,16);
            OLED_ShowString(59,32,".",12);
            OLED_ShowChinese(29,48,2,16);
        }
        else if(set_num == 4)
        {
            OLED_ShowChinese(29,0,2,16);
            OLED_ShowChinese(59,16,2,16);
            OLED_ShowChinese(59,32,2,16);
            OLED_ShowString(29,48,".",12);
        }
				
				
        SUM = Wei_Ji+SuShe_WeiSheng+JiaoShi_WeiSheng+Pao_Cao;
        OLED_ShowMY(45,2,Wei_Ji);
        OLED_ShowMY(75,18,SuShe_WeiSheng);
        OLED_ShowMY(75,34,JiaoShi_WeiSheng);
        OLED_ShowMY(45,50,Pao_Cao);
        OLED_ShowMY(106,50,SUM);
        OLED_Refresh();

    }

5、部分参考资料

#oled资料
#hal库的flash操作

6、注意事项

#注意oled的通信协议(可以通过0欧姆电阻选择),程序中未列出
#按键检测未列出

完整可运行项目地址