【蓝桥杯嵌入式】9届程序题刷题记录及反思

一、题目内容分析

 

二、LCD单字符高亮显示实现 

本次要求显示两个字符,此函数高亮pos及它后面一个字符

void highlight(uint8_t *str,uint8_t pos)
{
	int i = 0;
	for(i = 0; i <= 20; i++)
	{
		if(i != pos && i!= (pos+1))
			LCD_DisplayChar(Line3,(320 - (16 * i)),str[i]);
	}
	LCD_SetBackColor(Yellow);
	LCD_DisplayChar(Line3,(320 - (16 * pos)),str[pos]);
    LCD_SetBackColor(Yellow);
    LCD_DisplayChar(Line3,(320 - (16 * (pos+1))),str[pos+1]);
	LCD_SetBackColor(Black);	
}

 三、EEPROM

我们主要编写这两个函数

//字节写函数
void at24c02_Byte_Write(unsigned char addr,unsigned char cSendByte);
//随机读
unsigned char at24c02_Byte_read(unsigned char addr);

 找到竞赛平台里的资料

字节写: 

  •  起始信号
  • 器件地址————write为低电平 -> 0xa0
  • 等待应答
  • 发送字节地址
  • 等待应答
  • 发送数据
  • 等待应答
  • 结束信号
//字节写函数
void at24c02_Byte_Write(unsigned char addr,unsigned char cSendByte)
{
    I2CStart();
    I2CSendByte(0xa0);
    I2CWaitAck();
    I2CSendByte(addr);
    I2CWaitAck();
    I2CSendByte(cSendByte);
    I2CWaitAck();
    I2CStop();
}

随机读时序 

  • 开始信号
  • 器件地址写——0xa0
  • 等待应答
  • 发送字节地址
  • 等待应答
  • 器件地址读——0xa1
  • 等待应答
  • 接收字节
  • 发送无应答
  • 结束信号
//随机读
unsigned char at24c02_Byte_read(unsigned char addr)
{
    unsigned char dat;
    I2CStart();
    I2CSendByte(0xa0);
    I2CWaitAck();
    I2CSendByte(addr);
    I2CWaitAck();
    I2CStart();
    I2CSendByte(0xa1);
    I2CWaitAck();
    dat = I2CReceiveByte();
    I2CSendNotAck();
    I2CStop();
    return dat;
}

四、usr.c

#include "usr.h"
/* values ------------------------------------------------------------------*/
char time_state = Runing;
struct keys key[4] = {0,0,0,0};
uint8_t storage_location = 1;
uint8_t hour = 1,min = 2,sec = 10;
char timer_run_flag = 0;
int hightlight_sel = -1;
unsigned char read_data = 0;
void read_initial_data(void){
    hour = at24c02_Byte_read(1);
    min  = at24c02_Byte_read(2);
    sec  = at24c02_Byte_read(3);
}
//led
void led_set(uint8_t display)
{
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC,display<<8,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

//lcd
void display_init(void)
{
    LCD_Init();
    LCD_Clear(Black);
    LCD_SetBackColor(Black);
    LCD_SetTextColor(White);
    led_set(0x00);
}
void highlight(uint8_t *str,uint8_t pos)
{
	int i = 0;
	for(i = 0; i <= 20; i++)
	{
		if(i != pos && i!= (pos+1))
			LCD_DisplayChar(Line3,(320 - (16 * i)),str[i]);
	}
	LCD_SetBackColor(Yellow);
	LCD_DisplayChar(Line3,(320 - (16 * pos)),str[pos]);
    LCD_SetBackColor(Yellow);
    LCD_DisplayChar(Line3,(320 - (16 * (pos+1))),str[pos+1]);
	LCD_SetBackColor(Black);	
}

//pwm开始输出
void pwm_out_start(void)
{
    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
}
//pwm停止输出
void pwm_out_off(void)
{
    HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);
}

void menu_display(void)
{
    if(time_state!=Runing){
        led_set(0x00);
        pwm_out_off();
    }
    if(timer_run_flag == 1){
        time_state = Runing;
        pwm_out_start();
        
    }else if(timer_run_flag == 0){
        time_state = Pause;

    }else if(timer_run_flag == 2){
        time_state = Standby;
    }else{
        time_state = Setting;
    }
    char text[30];
    sprintf(text,"  No %d              ",storage_location);
    LCD_DisplayStringLine(Line1,(u8*)text);
    
    if(min < 10 && hour <10 && sec<10){                                // 0 0 0
        sprintf(text,"       0%d:0%d:0%d           ",hour,min,sec);
    }else if(hour <10 && min < 10 && sec >= 10){                       // 0 0 1
        sprintf(text,"       0%d:0%d:%2d           ",hour,min,sec);
    }else if(hour <10 && min >= 10 && sec < 10){                       // 0 1 0
        sprintf(text,"       0%d:%2d:0%d           ",hour,min,sec);
    }else if(hour <10 && min >= 10 && sec >= 10){                      // 0 1 1
        sprintf(text,"       0%d:%2d:%2d           ",hour,min,sec);
    }else if(hour >= 10 && min < 10 && sec < 10){                      // 1 0 0
        sprintf(text,"       %2d:0%d:0%d           ",hour,min,sec);
    }else if(hour >= 10 && min < 10 && sec >= 10){                     // 1 0 1
        sprintf(text,"       %2d:0%d:%2d           ",hour,min,sec);
    }else if(hour >= 10 && min >= 10 && sec < 10){                     // 1 1 0
        sprintf(text,"       %2d:%2d:0%d           ",hour,min,sec);
    }else if(hour >= 10 && min >= 10 && sec >= 10){                    // 1 1 1
        sprintf(text,"       %2d:%2d:%2d           ",hour,min,sec);
    }
 
    if(time_state == Setting){
        if(hightlight_sel == hightlight_sel_1){
            highlight((u8*)text,Hightlight_location1);
        }else if(hightlight_sel == hightlight_sel_2){
            highlight((u8*)text,Hightlight_location2);
        }else if(hightlight_sel == hightlight_sel_3){
            highlight((u8*)text,Hightlight_location3);
        }
    }else{
        LCD_DisplayStringLine(Line3,(u8*)text);  
    }
    

    if(time_state == Runing){
        sprintf(text,"       Running          ");
    }else if(time_state == Standby){
        sprintf(text,"       Standby          ");
    }else if(time_state == Setting){
        sprintf(text,"       Setting          ");
    }else if(time_state == Pause){
        sprintf(text,"       Pause          ");
    }
    LCD_DisplayStringLine(Line6,(u8*)text);

}

void timer_cnt(void){
    if(sec == 0){
        sec = 60;
        min --;
        if(min == 0){
            min = 59;
            hour --;
            if(hour == 0){
                hour = 0;
            }
        }
    }
}

void key_control(void){
    //短按
    if(key[0].key_short_flag == 1){        
        //read_data = at24c02_Byte_read(1);
        key[0].key_short_flag = 0;
        storage_location ++;
        if(storage_location > No_5){storage_location = No_1;}
    }else if(key[1].key_short_flag == 1){
        key[1].key_short_flag = 0;
        timer_run_flag = 3;
        time_state = Setting;
        if(time_state == Setting){
            hightlight_sel++;
            hightlight_sel %= 3;
           
        }
    }else if(key[2].key_short_flag == 1){
        key[2].key_short_flag = 0;
        //数字增加
        if(time_state == Setting){
            if(hightlight_sel == hightlight_sel_1){
                hour ++;
                hour %= 60;
            }else if(hightlight_sel == hightlight_sel_2){
                min ++;
                min %= 60;
            }else {
                sec ++;
                sec %= 60;
            }
        }
    }else if(key[3].key_short_flag == 1){
        key[3].key_short_flag = 0;
//        at24c02_Byte_Write(1,2);
//        HAL_Delay(5);
//        at24c02_Byte_Write(2,39);
//        HAL_Delay(5);
//        at24c02_Byte_Write(3,11);
        if(time_state == Setting){
            HAL_TIM_Base_Start_IT(&htim7);
            timer_run_flag = 1;
        }else if(time_state == Standby){            //取消定时器运行
                HAL_TIM_Base_Stop_IT(&htim7);
                timer_run_flag = 0;
        }else{
            //定时器启动
            if(timer_run_flag == 0){
                HAL_TIM_Base_Start_IT(&htim7);
                timer_run_flag = 1;
            }else if(timer_run_flag == 1){
            //定时器暂停   
                HAL_TIM_Base_Stop_IT(&htim7);
                timer_run_flag = 0;
            }
        }
    }
    //长按
    if(key[0].key_long_flag == 1){
        key[0].key_long_flag = 0;
        
    }else if(key[1].key_long_flag == 1){
        key[1].key_long_flag = 0;
        if(time_state == Setting){
            at24c02_Byte_Write(storage_location*3-2,hour);
            HAL_Delay(5);
            at24c02_Byte_Write(storage_location*3-1,min);
            HAL_Delay(5);
            at24c02_Byte_Write(storage_location*3  ,sec);
            HAL_Delay(5);
        }
    }else if(key[2].key_long_flag == 1){
       // key[2].key_long_flag = 0;
        if(time_state == Setting){
            if(hightlight_sel == hightlight_sel_1){
                hour ++;
                hour %= 60;
            }else if(hightlight_sel == hightlight_sel_2){
                min ++;
                min %= 60;
            }else {
                sec ++;
                sec %= 60;
            }
            if(key[2].key_sta == 1){
                key[2].key_long_flag = 0;
            }
        }
    }else if(key[3].key_long_flag == 1){
        key[3].key_long_flag = 0;
        //长按取消定时器运行,回到Standby状态
       // if(timer_run_flag == 1){
            timer_run_flag = 2; 
       // }
    }

}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim -> Instance == TIM6){
        key[0].key_sta = HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin);
        key[1].key_sta = HAL_GPIO_ReadPin(B2_GPIO_Port,B2_Pin);
        key[2].key_sta = HAL_GPIO_ReadPin(B3_GPIO_Port,B3_Pin);
        key[3].key_sta = HAL_GPIO_ReadPin(B4_GPIO_Port,B4_Pin);
        for(uint8_t i = 0;i < 4;i++){
            switch(key[i].key_judge){
                case 0:{
                    if(key[i].key_sta ==  0){
                        key[i].key_judge = 1;
                    }else{
                        key[i].key_judge = 0;
                    }
                }break;
                case 1:{
                    if(key[i].key_sta ==  0){
                        key[i].key_judge = 2;
                    }else{
                        key[i].key_judge = 0;
                    }
                }break;
                case 2:{
                    if(key[i].key_sta ==  1){
                        if(key[i].key_time <= Key_shorttime){
                            key[i].key_short_flag = 1;
                            key[i].key_time = 0;
                            key[i].key_judge = 0;
                        }
                    }else{
                        if(key[i].key_time >= Key_longtime){
                            key[i].key_time = 0;
                            key[i].key_long_flag = 1;
                            key[i].key_judge = 0;
                        }
                        key[i].key_time ++;
                    }
                }break;
            } 
        }
    }
    if(htim -> Instance == TIM7){               //倒计时计时器
        if(timer_run_flag == 1){
            timer_cnt();
            sec --;
        }
    }
    if(htim -> Instance == TIM17){              //led闪烁定时器
        static uint8_t cnt = 0;
        if(timer_run_flag == 1){
            if(cnt<5){
                led_set(0x01);
            }else{
                led_set(0x00);
            }
            cnt++;
            cnt %= 10;        
        }
        else{
             cnt = 0;
        }                                                          

    }
}

五、usr.h

#ifndef __USR_H
#define __USR_H

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "lcd.h"
#include "tim.h"
#include "stdio.h"
#include "i2c_hal.h"
/* defines -------------------------------------------------------------------*/
#define Runing  0 
#define Setting 1
#define Standby 2
#define Pause   3

#define No_1    1     //1-3
#define No_2    2     //4-6
#define No_3    3     //7-9
#define No_4    4     //10-12
#define No_5    5     //13-15

#define Key_longtime  80
#define Key_shorttime 30

#define Hightlight_location1 7
#define Hightlight_location2 10
#define Hightlight_location3 13

#define hightlight_sel_1     0
#define hightlight_sel_2     1
#define hightlight_sel_3     2
/* structs -------------------------------------------------------------------*/
struct keys{
    uint8_t key_sta;
    uint8_t key_judge;
    uint8_t key_short_flag;
    uint8_t key_long_flag;
    uint16_t key_time;
};


void display_init(void);
void menu_display(void);
void key_control(void);
void timer_cnt(void);
void read_initial_data(void);
#endif 

六、总结

 I2C的两个引脚不需要额外配置(在cubemx配置)

记得调用"i2c_hal.c"里提供的I2CInit()

cubemx在配置定时器的时候记得开启中断,在while前启动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值