蓝桥杯嵌入式第四届省赛做题笔记

 

        初始化我已经在我的处女作博文里写了,先把初始化学习了再做真题会更顺手

        第四届的题有一个坑就是TIM2的PA2口会和串口有冲突,所以他两不能同时使能,要解决这个问题就要写一个函数,让他在同一时间只能使能一个

        在关闭一个功能的使能函数时就要关闭他的时钟,然后打开另一个功能的使能也要先打开他对应的时钟

#define PWM_ENABLE 	1    //也就相当于定义一个标志位,更清楚点
#define UART_ENABLE 2

void PWM_UART_Enable(u8 flag)
{
	if(flag==PWM_ENABLE)
	{
		USART_Cmd(USART2, DISABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	
		TIM_Cmd(TIM2, ENABLE);
	}
	
	if(flag==UART_ENABLE)
	{
	    TIM_Cmd(TIM2, DISABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);		
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
		USART_Cmd(USART2, ENABLE);
	}
}

 最好都把各个模块分开写成函数,更加一目了然

先写LCD功能

_Bool PA1_out=0,PA2_out=0;//要定义两个布尔类的变量代表PA1和PA2的输出状态

u16 PA1_duty=200,PA2_duty=100;//代表PA1和PA2的占空比

//在写的过程中需要定义什么变量都可以加到最开头
_Bool pa1_output_flag=0,pa2_output_flag=0;
u16 PA1_duty=200,PA2_duty=100;//注意要使用u16类型
u8 PA1_buf[15],PA2_buf[15];


void LCD()
{
    //时间的显示可以直接写在rtc.c的Time_Display函数中
    //sprintf((char *)tim_buf,"Time: %0.2d:%0.2d:%0.2d", THH, TMM, TSS);
    //LCD_DisplayStringLine(Line3,tim_buf);
    //注意要包含头文件stdio.h

    if(PA1_out==0 && PA2_out==0)
	{
		sprintf((char *)PA1_buf,"PWM-PA1: %3d%%",0);
		LCD_DisplayStringLine(Line1,PA1_buf);

		sprintf((char *)PA1_buf,"PWM-PA1: %3d%%",0);
		LCD_DisplayStringLine(Line2,PA2_buf);

		LCD_DisplayStringLine(Line4,"Channel:None");
		led_Control(0xff,0);
	}
	if(PA1_out==1)
	{
		TIM_SetCompare2(TIM2,PA1_duty);			

		sprintf((char *)PA1_buf,"PWM-PA1: %3d%%",PA1_duty/10);
		LCD_DisplayStringLine(Line1,PA1_buf);

		LCD_DisplayStringLine(Line4,"Channel:PA1 ");
		led_Control(0x01,1);
	}
	else
	{		
		TIM_SetCompare2(TIM2,0);
		sprintf((char *)PA1_buf,"PWM-PA1: %3d%%",0);
		LCD_DisplayStringLine(Line1,PA1_buf);	
	}
	if(PA2_out==1)
	{
		TIM_SetCompare3(TIM2,PA2_duty);

		sprintf((char *)PA2_buf,"PWM-PA2: %3d%%",PA2_duty/10);
		LCD_DisplayStringLine(Line2,PA2_buf);

		LCD_DisplayStringLine(Line4,"Channel:PA2 ");
		led_Control(0x02,1);
	}
	else
	{			
		TIM_SetCompare3(TIM2,0);
		sprintf((char *)PA2_buf,"PWM-PA1: %3d%%",0);
		LCD_DisplayStringLine(Line2,PA2_buf);
	}

	
}

KEY功能

_Bool key_flag=0;
void KEY()
{
	if(key_flag)
	{
		key_flag=0;
		key_read();
		if(Trg==0x01)
		{
			PA1_out=!PA1_out;//只输出PA1
			PA2_out=0;
			if(PA1_out)
				PWM_UART_Enable(PWM_ENABLE);
			else
				PWM_UART_Enable(UART_ENABLE);
		}
		if(Trg==0x02)
		{
			PA1_duty+=100;
			if(PA1_duty>=1000)
				PA1_duty=0;
            //在这里进行EEPROM的写,在主函数里进行读取
            write(0x00,PA1_duty/10);
		}
		if(Trg==0x04)
		{
			PA2_out=!PA2_out;//只输出PA2
			PA1_out=0;
			if(PA2_out)
				PWM_UART_Enable(PWM_ENABLE);
			else
				PWM_UART_Enable(UART_ENABLE);
		}
		if(Trg==0x08)
		{
			PA2_duty+=100;
			if(PA2_duty>=1000)
				PA2_duty=0;
            write(0x01,PA2_duty/10);
		}
	}	
}

串口功能

//在串口中断里进行判断
u8 rx_buf[15];
u8 rx_count=0;
u8 rx_ideltime=0;
_Bool rx_flag=0;
void USART2_IRQHandler(void)
{
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
	{
		USART_ClearITPendingBit(USART2,USART_IT_RXNE);
		rx_buf[rx_count++]=USART_ReceiveData(USART2);
		if(rx_count==15 && rx_buf[14]=='S')
		{
			rx_flag=1;
			rx_count=0;
		}
		rx_idletime=0;
	}
}
//在TIM4中断里进行闲时判断
rx_ideltime++;
if(rx_ideltime>=50)
{
	rx_ideltime=0;
	rx_count=0;
	memset(rx_buf,0,15);		
}

//UART变量
u8 pa1_pwm_time,pa2_pwm_time;//持续输出的时间
u8 pa1_hour,pa1_min,pa1_sec;//PA1的时分秒,等时间到了就输出波形
u8 pa2_hour,pa2_min,pa2_sec;
void USART()
{
	if(rx_flag)
	{
		rx_flag=0;

		LCD_DisplayStringLine(Line6,rx_buf);//在LCD上显示发送的内容

		if(rx_buf[11]=='1')
		{
			pa1_pwm_time= rx_buf[13] - '0';
			pa1_hour = (rx_buf[0]-'0')*10 + rx_buf[1]-'0';
			pa1_min = (rx_buf[3]-'0')*10 + rx_buf[4]-'0';
			pa1_sec = (rx_buf[6]-'0')*10 + rx_buf[7]-'0';
		}
		
		if(rx_buf[11]=='2')
		{
			pa2_pwm_time= rx_buf[13] - '0';
			pa2_hour = (rx_buf[0]-'0')*10 + rx_buf[1]-'0';
			pa2_min = (rx_buf[3]-'0')*10 + rx_buf[4]-'0';
			pa2_sec = (rx_buf[6]-'0')*10 + rx_buf[7]-'0';
		}
	}
}

在main函数里需要进行的操作

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

	Delay_Ms(200);
	
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	key_init();                //各种初始化
	led_init();
	rtc_init();
    i2c_init();
	Time_Adjust(23,59,50);		//RTC初始时间设置
    THH=23;TMM=59;TSS=50;        //设置初值
	usart_init();
	tim4_init();
	tim_pwm_output();
    led_control(0xff,0);//如果对灯不放心可以在这里把灯先全灭了

    
//有一点小问题,要把这个固定的显示放在循环外,只运行一次
    LCD_DisplayStringLine(Line5,"Command:");
	LCD_DisplayStringLine(Line6,"           None");


    PA1_duty=read(0x00)*10;
	PA2_duty=read(0x01)*10;
	
	while(1)
	{	
		if (TimeDisplay == 1)
		{
		  /* Display current time */
		  Time_Display(RTC_GetCounter());
		  TimeDisplay = 0;
		  if(pa1_hour==THH && pa1_min==TMM && pa1_sec==TSS && pa1_output_flag==0)
			{
				pa1_output_flag=1;
				PA1_out=1;
				PWM_UART_Enable(PWM_ENABLE);
			}
			
			if(pa2_hour==THH && pa2_min==TMM && pa2_sec==TSS && pa2_output_flag==0)
			{
				pa2_output_flag=1;
				PA2_out=1;
				PWM_UART_Enable(PWM_ENABLE);
			}
		}

		LCD();
		KEY();
		USART();
	}
}

TIM4的中断函数

void TIM4_IRQHandler(void)
{
	static u16 key_count=0,pa1_one_sec_count=0,pa2_one_sec_count=0;			//定义为静态变量
	if (TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET)
	{
		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
		key_count++;
		rx_ideltime++;
		if(rx_ideltime>=50)
		{
			rx_ideltime=0;
			rx_count=0;
			memset(rx_buf,0,15);		
		}
		if(key_count==10)
		{
			key_flag=1;
			key_count=0;
		}

		if(pa1_output_flag)
		{
			pa1_one_sec_count++;
			if(pa1_one_sec_count==500) 	//pa1_pwm_time*1000
//这里不清楚有什么问题,但是运行的时候一直是两倍的时间,仿真也的结果也是串口输入的时间。
//所以我把1000改成了500,有知道的小伙伴可以评论告诉我一下
			{
				pa1_one_sec_count=0;
				pa1_pwm_time--;
			}
			
			if(pa1_pwm_time>0)
			{
				PA1_out=1;
			}
			else
			{
				PA1_out=0;
				pa1_output_flag=0;
				LCD_DisplayStringLine(Line6,"    None        ");
				PWM_UART_Enable(UART_ENABLE);
			}		
		}
		
		if(pa2_output_flag)
		{
			pa2_one_sec_count++;
			if(pa2_one_sec_count==500) 	//pa1_pwm_time*1000
			{
				pa2_one_sec_count=0;
				pa2_pwm_time--;
			}
			
			if(pa2_pwm_time>0)
			{
				PA2_out=1;
			}
			else
			{
				PA2_out=0;
				pa2_output_flag=0;
				LCD_DisplayStringLine(Line6,"    None        ");
				PWM_UART_Enable(UART_ENABLE);
			}		
		}
	}	
	
}

延时函数在他本来的工程模板里会带有

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

至此,第四届省赛的功能模块已经全部实现,感谢敢看!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值