这一届的省题用到的外设比较多一点,有用到i2c、key、led、usart、rtc、adc。并且考点相对比较全一点,但我们只要会了上述的外设配置,总体的main函数的逻辑代码编写,难度不大。
题目分析
我们接下来看看任务要求:
我们再来看看主要的考点并且分析:
RTC时钟
rtc时钟,并且要设置三个时分秒的变量,与RTC时钟去对比,当RTC时钟与设置的阈值相等的时候上报信息。即:
unsigned char shi=0; //上报时间:时
unsigned char fen=0; //上报时间:分
unsigned char miao=0; //上报时间:秒
ADC测量功能
这里主要就是ADC的变量配置和led的显示配置、串口。我们看到题目要求说要我们要输出R32输出的电压V1的值,并且判断V1>Vddk是否成立和通过按键可关闭led闪烁、k的值可以通过串口修改。所以我们读出他的题目要求:
①输出R37模拟电压的值
②可以通过按键开启或者关闭led的闪烁功能
③当led开启闪烁的时候,判断V1>Vddk是否成立,成立则以0.2s闪烁,否则led不闪。
④k值可以通过串口修改并且保存于i2c。
我们这里设置led的标志位,是否闪烁的标志位、Vdd、k的初始化的值,存储R37的电压值。即:
unsigned char B1=0; //led打开和关闭
unsigned char k=1; //后面处理时要k/10.0
float Vdd=3.3; //Vdd初始化的值
unsigned int adc_val; //adc存储值
串行功能
这里主要就是说嘛串口的要实现的功能。我们可以看出主要有两部分是要我们去实现的。“收”和“发”。
我们看设定k的时候我们就知道我们要想PC机发送“k0.x”,这里我们看到首先发送的是k,因此我们可以以这个为一个判断的条件,判断收到的数组里面的首个字符是否为k。然后我们还要将后面k设定的值传输给变量k。并且要传输给i2c。
即:
if(Rxflay) //接受到中断
{
Rxflay=0;
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
if(RxBuffer[0]=='k')
{
usart_sending(USART2,"OK\n \r\n");
k=(RxBuffer[3]-48); //传输给变量k
i2c_wirth(0x01,k);
Delay_LCD(30);
i2c_val=i2c_read(0x01);
}
memset(RxBuffer,'\0',sizeof(RxBuffer)); //清空字符串
}
我们在看看第二部分。这里与第一部分相关联。就是上报的时钟变量与RTC时钟去对比,当RTC时钟与设置的阈值相等的时候上报信息(adc的电压值、k的值、rtc时间)。
即:
if(((time/3600)==shi)&&(((time%3600)/60)==fen)&&(((time%3600)%60)==miao))
{
sprintf((char *)str,"%4.2f+%4.2f+%0.2d%0.2d%0.2d\r\n",(float)adc_val*3.3/4095,(float)k/10.0,time/3600,(time%3600)/60,(time%3600)%60);
usart_sending(USART2,str);
}
LCD显示
在LCD设置上我们看到这主要有两个界面。参数界面和设置上报时间界面。
在参数界面上主要有R37模拟电压、k值、LED是否闪烁、RTC时间。
在设置界面上主要就是三个上报时钟的设置。
在lcd上也是一样的要有个标志位进行界面的切换。即为0时参数界面,为1时设定界面。
即;
unsigned char B2=0; //界面切换
按键功能
在这里主要就是设定按键的功能了。我们可以看出主要有一下的几种功能:
①B1(按键1)led闪烁的打开和关闭。
②B2(按键2)界面切换设置
③B3(按键3)选择上报的参数。即高亮的设置。
④B4(按键4)对上报参数进行加的操作。
即:
unsigned char B3=0; //高亮切换
unsigned char key_val; //key存储值
void key_caozuo(void)
{
key_val=key_scanf(); //读取按键值 即key_val=1时第一个按键按下 =2时第二个按键按下。。。以此类推
if(key_val==1)
{
switch(B1) //led开关的设置
{
case 0:B1=1;break;
case 1:B1=0;break;
}
}
if(key_val==2)
{
switch(B2) //界面切换
{
case 0:B2=1;break;
case 1:B2=0;break;
}
}
if(key_val==3) //高亮切换
{
switch(B3)
{
case 0:B3=1;break;
case 1:B3=2;break;
case 2:B3=3;break;
case 3:B3=0;break;
}
}
if(key_val==4) //上报数值的+
{
if(B2==1)
{
if(B3==1) //检测为时
{
if(shi!=24)
shi++;
if(shi==24)
shi=0;
}
if(B3==2) //检测为分
{
if(fen!=60)
fen++;
if(fen==60)
fen=0;
}
if(B3==3) //检测为秒
{
if(miao!=60)
miao++;
if(miao==60)
miao=0;
}
}
}
}
这样本文对于题目要求分析全部结束,我们接下来在看看对于main函数的编写。
代码
main
#include "stm32f10x.h"
#include "stdio.h"
#include "string.h"
#include "usart.h"
#include "led.h"
#include "adc.h"
#include "key.h"
#include "i2c.h"
#include "rtc.h"
#include "lcd.h"
u32 TimingDelay = 0;
u8 RxBuffer[20];
u8 RxCounter=0;
u8 Rxflay=0;
u8 str[40];
unsigned char shi=0; //上报时间:时
unsigned char fen=0; //上报时间:分
unsigned char miao=0; //上报时间:秒
unsigned char B1=0; //led打开和关闭
unsigned char B2=0; //界面切换
unsigned char B3=0; //高亮切换
unsigned char k=1;
float Vdd=3.3;
unsigned int adc_val; //adc存储值
unsigned char key_val; //key存储值
unsigned char i2c_val;
extern unsigned long time; //rtc
void Delay_Ms(u32 nTime);
void rtc_widon(void) //rtc时钟显示
{
time=RTC_GetCounter();
sprintf((char *)str," T:%0.2d-%0.2d-%0.2d ",time/3600,(time%3600)/60,(time%3600)%60); //拆分时分秒
LCD_DisplayStringLine(Line7,str);
}
void lcd_caozuo(void)
{
if(B2==0) //显示界面
{
adc_val=adc_scanf(); //读取adc
sprintf((char *)str," V1:%4.2fV ",(float)adc_val*3.3/4095);
LCD_DisplayStringLine(Line1,str);
sprintf((char *)str," K:%4.2f ",(float)k/10.0);
LCD_DisplayStringLine(Line3,str);
if(B1==0) //led闪烁
LCD_DisplayStringLine(Line5," LED:OFF ");
else if(B1==1) //led不闪
LCD_DisplayStringLine(Line5," LED:ON ");
rtc_widon(); //显示时间
}
if(B2==1) //设置界面
{
LCD_DisplayStringLine(Line1," ");
LCD_DisplayStringLine(Line7," ");
LCD_DisplayStringLine(Line3," Setting ");
if(B3==0) //不高亮
{
sprintf((char *)str," %0.2d-%0.2d-%0.2d ",shi,fen,miao);
LCD_DisplayStringLine(Line5,str);
}
if(B3==1) //shi高亮
{
sprintf((char *)str," %0.2d-%0.2d-%0.2d ",shi,fen,miao);
LCD_DisplayStringLine(Line5,str);
LCD_SetBackColor(Yellow);
LCD_DisplayChar(Line5,(320 - (16 * 5)),str[5]);
LCD_DisplayChar(Line5,(320 - (16 * 6)),str[6]);
LCD_SetBackColor(Blue);
}
if(B3==2) //fen高亮
{
sprintf((char *)str," %0.2d-%0.2d-%0.2d ",shi,fen,miao);
LCD_DisplayStringLine(Line5,str);
LCD_SetBackColor(Yellow);
LCD_DisplayChar(Line5,(320 - (16 * 8)),str[8]);
LCD_DisplayChar(Line5,(320 - (16 * 9)),str[9]);
LCD_SetBackColor(Blue);
}
if(B3==3) //miao高亮
{
sprintf((char *)str," %0.2d-%0.2d-%0.2d ",shi,fen,miao);
LCD_DisplayStringLine(Line5,str);
LCD_SetBackColor(Yellow);
LCD_DisplayChar(Line5,(320 - (16 * 12)),str[12]);
LCD_DisplayChar(Line5,(320 - (16 * 11)),str[11]);
LCD_SetBackColor(Blue);
}
}
}
void key_caozuo(void)
{
key_val=key_scanf();
if(key_val==1)
{
switch(B1) //led
{
case 0:B1=1;break;
case 1:B1=0;break;
}
}
if(key_val==2)
{
switch(B2) //界面
{
case 0:B2=1;break;
case 1:B2=0;break;
}
}
if(key_val==3) //高亮
{
switch(B3)
{
case 0:B3=1;break;
case 1:B3=2;break;
case 2:B3=3;break;
case 3:B3=0;break;
}
}
if(key_val==4)
{
if(B2==1)
{
if(B3==1)
{
if(shi!=24)
shi++;
if(shi==24)
shi=0;
}
if(B3==2)
{
if(fen!=60)
fen++;
if(fen==60)
fen=0;
}
if(B3==3)
{
if(miao!=60)
miao++;
if(miao==60)
miao=0;
}
}
}
}
void usart_caozuo(void)
{
if(Rxflay) //接受到中断
{
Rxflay=0;
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
if(RxBuffer[0]=='k')
{
usart_sending(USART2,"OK\n \r\n");
k=(RxBuffer[3]-48);
i2c_wirth(0x01,k);
Delay_LCD(30);
i2c_val=i2c_read(0x01);
}
memset(RxBuffer,'\0',sizeof(RxBuffer));
}
if(((time/3600)==shi)&&(((time%3600)/60)==fen)&&(((time%3600)%60)==miao))
{
sprintf((char *)str,"%4.2f+%4.2f+%0.2d%0.2d%0.2d\r\n",(float)adc_val*3.3/4095,(float)k/10.0,time/3600,(time%3600)/60,(time%3600)%60);
usart_sending(USART2,str);
}
}
//Main Body
int main(void)
{
SysTick_Config(72000);
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
i2c_init();
usart_init();
key_init();
led_init();
rtc_init();
adc_init();
while(1)
{
lcd_caozuo();
key_caozuo();
usart_caozuo();
}
}
//
/*void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}*/
void SysTick_Handler(void)
{
led_init(); //不加初始化就会混乱,不知道为什么
if(B1==0) //led闪烁功能打开
{
if((float)adc_val*3.3/4095>((float)k/10.0)*Vdd) //判断V1>Vdd*k是否成立
{/*0.2s频率闪烁*/
TimingDelay++;
if(TimingDelay<100)
led_scanf(0,led1);
else if(TimingDelay==200)
TimingDelay=0;
else if(TimingDelay>100)
led_scanf(1,led1);
}
}
else if(B1==1) //led闪烁关闭,led1关闭
{
led_scanf(1,led1);
}
}
现象:
另外,对于其他的资源(adc、rtc、usart、pwm等等)的配置在我的其他蓝桥杯嵌入式专栏里面都有写——蓝桥杯嵌入式专栏。
对于不懂的可以留言,我看到尽量去解答。