0
点赞
收藏
分享

微信扫一扫

蓝桥杯嵌入式_STM32学习_第六届省赛题

徐一村 2022-04-03 阅读 34

个人做题记录,仅供参考
main.c

#include "stm32f10x.h"
#include "stdio.h"
#include "string.h"
#include "key.h"
#include "lcd.h"
#include "rtc.h"
#include "adc.h"
#include "led.h"
#include "usart.h"

uint8_t RTC_Flag = 0;
uint8_t Lcd_flag =0;
uint8_t Sent_OK =0;
uint8_t Led_status = 0;
uint8_t hour = 0;
uint8_t min = 0;
uint8_t sec = 0;
uint16_t TimeVal = 0;
uint8_t Time_200ms = 0;
uint8_t Lcd_light = 0;
char Rx_Buf[10] = {0};
int SetTime_Buf[3] = {0,0,0};
unsigned char Buf[20] = {0};
float ADC_Val = 0;
float k = 0.1;
uint8_t RXOVER = 0;
u32 TimingDelay = 0;


void Delay_Ms(u32 nTime);
void Key_Proc(int *p);
void Lcd_Proc(void);
void RTC_Proc(void);
void Led_Proc(void);
void USART2_Proc(void);
void highlight(uint8_t *str,uint8_t pos);


int main(){
	
	SysTick_Config(SystemCoreClock/1000);

	Delay_Ms(200);
	
	STM3210B_LCD_Init();
	KEY_Init();
	rtc_init();Time_Adjust(23,59,55);
	ADC1_Init();
	LED_Init();
	USART2_Init(9600);
	
	
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	while(1){
		ADC_Val = (float)((int)((ADC1_Conv() * 3.3 / 4096)*100)) / 100;
		Key_Proc(SetTime_Buf);
		Led_Proc();
		Lcd_Proc();
		Time_Refresh();
		USART2_Proc();
		
	}
	
}

/*******************************************************************************
* 函数名	:Key_Proc
* 输入值	:整型指针变量p
* 返回值	:无
* 作者	:Moqim Flourite.
* 时间	:2022年3月30日
* 功能描述:按键设置
* 备注	:“B1”按键设定为“功能”按键,打开/关闭指示灯闪烁报警功能,默认为打开状态; 
          “B2”按键设定为“设置”按键,设置设备自动上报电压时间,
           按下B2后,LCD显示界面如图2所示,
           此时通过按键B3切换选择时、分、秒,通过按键B4进行调整,
           完成调整后,按下B2按键,更新自动上报时间,并返回图1所示的LCD显示界面。
*******************************************************************************/

void Key_Proc(int *p){
	static uint8_t Key_Val,Key_Down,Key_Old;
	static uint8_t i = 0;
	Key_Val = KEY_Scan();
	Key_Down = Key_Val & (Key_Val ^ Key_Old);
	Key_Old = Key_Val;
	switch(Key_Down){
		case 1:
			Led_status = !Led_status;break;
		case 2:
			if(Lcd_flag == 0){
				i = 0;
			}
		  Lcd_flag = !Lcd_flag;
			break;
		case 3:
			if(Lcd_flag == 1){
				if(++ i == 3)i = 0;
				
			}break;
		case 4:
			if(Lcd_flag == 1){
				p[i]++;
			}break;
		default:break;
	}
	Lcd_light = i;
}


/*******************************************************************************
* 函数名	:Lcd_Proc
* 输入值	:无
* 返回值	:无
* 作者	:Moqim Flourite.
* 时间	:2022年4月2日
* 功能描述:按键设置
* 备注	:功能页面:显示电位器输出电压V1(保留小数点后两位有效数字)、k值、
                      指示灯闪烁报警功能状态和系统时间;
            显示页面:显示“Setting”与上报时间的时分秒;设置时间时高亮设置部分;
*******************************************************************************/

void Lcd_Proc(void){
	if(Lcd_flag == 0){//显示模式
		sprintf((char*)Buf,"  V1:%.2fV          ",ADC_Val);
		LCD_DisplayStringLine(Line1,Buf);
		memset(Buf,0,(20 * sizeof(unsigned char)));
		
		sprintf((char*)Buf,"  k:%.1f          ",k);
		LCD_DisplayStringLine(Line3,Buf);
		memset(Buf,0,(20 * sizeof(unsigned char)));
		
		if(Led_status == 0)LCD_DisplayStringLine(Line5,"  LED:ON          ");
		else LCD_DisplayStringLine(Line5,"  LED:OFF          ");
		
		sprintf((char*)Buf,"  T:%02d-%02d-%02d         ",hour,min,sec);
		LCD_DisplayStringLine(Line7,Buf);
		memset(Buf,0,(20*sizeof(unsigned char)));
		
		LCD_DisplayStringLine(Line9,"                   1");
	}
	else{
		LCD_DisplayStringLine(Line1,"       Setting      ");
		
		sprintf((char*)Buf,"      %02d-%02d-%02d           ",SetTime_Buf[0],SetTime_Buf[1],SetTime_Buf[2]);
//		LCD_DisplayStringLine(Line3,Buf);
		switch(Lcd_light){
			case 0:highlight(Buf,6);break;
			case 1:highlight(Buf,9);break;
			case 2:highlight(Buf,12);break;
		}
		LCD_SetTextColor(White);	
		memset(Buf,0,(20 * sizeof(unsigned char)));
		
		LCD_DisplayStringLine(Line9,"                   2");
		
		LCD_ClearLine(Line5);
		LCD_ClearLine(Line7);
	}
}

/*******************************************************************************
* 函数名	:Led_Proc
* 输入值	:无
* 返回值	:无
* 作者	:Moqim Flourite.
* 时间	:2022年4月2日
* 功能描述:LED显示
* 备注	:当V1>VDD*k时,指示灯LD1以0.2秒为间隔闪烁,闪烁功能可以通过按键关闭,但上电默认开启;
*******************************************************************************/
void Led_Proc(void){
	static uint8_t led = 0;
	if(Led_status == 0){
		if(ADC_Val > (k * 3.3)){
			if(Time_200ms == 1){
				Time_200ms = 0;
				led = 0x01;
			}
			else led = 0;
		}
	}
	else{
		led = 0;
	}
	LED_Disp(led);
}


/*******************************************************************************
* 函数名	:USART2_IRQHandler
* 输入值	:无
* 返回值	:无
* 作者	:Moqim Flourite.
* 时间	:2022年4月2日
* 功能描述:串口2中断服务函数
* 备注	:接收数据,当接收到换行符‘\n’时,停止接收,并开启检测标志位;
*******************************************************************************/
void USART2_IRQHandler(void){
	static char temp;
	
  static int i = 0;
	if(USART_GetITStatus(USART2,USART_IT_RXNE)){
		USART_ClearITPendingBit(USART2,USART_IT_RXNE);
		temp = USART_ReceiveData(USART2);
		if(temp == 0x0a){
			i = 0;
			RXOVER = 1;
			USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//关闭中断
		}
		else{
			Rx_Buf[i] = temp;
			i++;
		}	
	}
}


/*******************************************************************************
* 函数名	:USART2_Proc
* 输入值	:无
* 返回值	:无
* 作者	:Moqim Flourite.
* 时间	:2022年4月2日
* 功能描述:串口2发送函数
* 备注	:1:检测是否接收到正确字符串,是就发送"OK";
          2:当时间到达设置发送时间时,按模版上报电压值;          
         这个检测的写的有点low,但是能用就行hhhh.
*******************************************************************************/
void USART2_Proc(void){
	static uint8_t Sent_Buf[20] = {0};
	if(RXOVER == 1){
		RXOVER = 0;
		if(Rx_Buf[0] == 'k'){
			 if(Rx_Buf[1] == '0'){
				if(Rx_Buf[2] == '.'){
					if((Rx_Buf[3] > 0x30) && (Rx_Buf[3] < 0x3a) ){
						Sent_OK = 1;
						k = (float)(Rx_Buf[3] - 48) / 10;
					}
				}
			}
		}
		memset(Rx_Buf,0,(10 * sizeof(char)));
		USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
	}
	if(Sent_OK == 1){
		Sent_OK = 0;
		USART_SendString(USART2, "ok\n");
	}
	if(SetTime_Buf[0] == hour && SetTime_Buf[1] == min && SetTime_Buf[2] == sec){
		sprintf((char*)Sent_Buf,"%.2f+%.1f+%02d%02d%02d\n",ADC_Val,k,hour,min,sec);
		USART_SendString(USART2,Sent_Buf);
		Delay_Ms(1000);
		memset(Sent_Buf,0,(20 * sizeof(uint8_t)));
	}
}

/*******************************************************************************
* 函数名	:highlight
* 输入值	:uint8_t *str,uint8_t pos
* 返回值	:无
* 作者	:Moqim Flourite.
* 时间	:2022年4月3日
* 功能描述:lcd高亮函数
* 备注	:使得pos位与pos+1位的字符高亮(变字体颜色),因为换背景颜色频闪更严重orz...
*******************************************************************************/
void highlight(uint8_t *str,uint8_t pos)
{
	int i = 0;
	for(i = 0; i <= 19; i++)
	{
		if(i != pos)
			LCD_DisplayChar(Line3,(320 - (16 * i)),str[i]);
	}
	LCD_SetTextColor(Red);
	LCD_DisplayChar(Line3,(320 - (16 * pos)),str[pos]);
	LCD_DisplayChar(Line3,(320 - (16 * (pos + 1))),str[pos+1]);
//	LCD_SetTextColor(White);	
}

void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

参考博客:
@FILWY_MS——TM32 - 蓝桥杯嵌入式 LCD 字符颜色、高亮显示

举报

相关推荐

0 条评论