这一场考到了之前从没有考过的一个题,那就是利用输入捕获测量555的输出频率,再把它和PA7的输出频率结合到一起,实现一个分频的作用!因此还是非常有意义的!今年也可能考到测量频率或者测量周期!
一、题目
二、模块
常考的按键,LED和LCD,再加上ADC输入和信号输入输出。
其中信号输入是以前没有考到过的,今年值得注意一下,也可能考测量信号的占空比!
三、代码
uint32_t lcd_uwTick;//减速变量
uint32_t key_uwTick;//减速变量
uint8_t LCD_DispString[20];
uint16_t key_value,key_old,key_up,key_down;
uint8_t Interface = 0,LED_Status = 0;
uint16_t FRQ,R = 2;
uint8_t led1,led2,led3,led4;
void SystemClock_Config(void);
void LCD_Proc(void);
void LED_Disp(uint8_t ucled);
uint16_t KEY_Scan(void);
void KEY_Proc(void);
float get_adc(void);
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);
void LED_Proc(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC2_Init();
MX_TIM2_Init();
MX_TIM17_Init();
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
HAL_TIM_Base_Start(&htim2);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
while (1)
{
LCD_Proc();
KEY_Proc();
LED_Proc();
}
}
void LCD_Proc(void)
{
if(uwTick - lcd_uwTick < 50) return ;
lcd_uwTick = uwTick;
if(Interface==0)
{
sprintf((char *)LCD_DispString," Data");
LCD_DisplayStringLine(Line1,LCD_DispString);
sprintf((char *)LCD_DispString," FRQ:%3dHZ",1000000/FRQ);
LCD_DisplayStringLine(Line3,LCD_DispString);
__HAL_TIM_SET_AUTORELOAD(&htim17,FRQ*R);
sprintf((char *)LCD_DispString," R37:%.2fV",get_adc());
LCD_DisplayStringLine(Line5,LCD_DispString);
}
else
{
sprintf((char *)LCD_DispString," Para");
LCD_DisplayStringLine(Line1,LCD_DispString);
sprintf((char *)LCD_DispString," R:%2d",R);
LCD_DisplayStringLine(Line3,LCD_DispString);
}
}
void KEY_Proc(void)
{
if(uwTick - key_uwTick < 20) return ;
key_uwTick = uwTick;
key_value = KEY_Scan();
key_down = key_value & (key_value ^ key_old);
key_up = ~key_value & (key_value ^ key_old);
key_old = key_value;
if(key_down==1)
{
Interface ^= 0x01;
LCD_Clear(Black);
}
if(key_down==2)
{
R+=2;
if(R>=10) R=10;
}
if(key_down==3)
{
R-=2;
if(R<=2) R=2;
}
if(key_down==4)
{
LED_Status ^= 0x01;
}
}
void LED_Proc(void)
{
if(LED_Status==0)
{
if(Interface==0)
{
led1=0x01;
led2=0x00;
}
else
{
led1=0x00;
led2=0x02;
}
if(get_adc()<1 || get_adc() >= 3)
led3=0x04;
else
led3=0x00;
if(FRQ<1000 || FRQ >= 5000)
led4=0x08;
else
led4=0x00;
LED_Disp(led1|led2|led3|led4);
}
else
{
LED_Disp(0x00);
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
FRQ = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2)+1;
}
}
}
float get_adc(void)
{
float value;
HAL_ADC_Start(&hadc2);
value = (HAL_ADC_GetValue(&hadc2)*3.3)/4096;
return value;
}
uint16_t KEY_Scan(void)
{
uint16_t value;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
value = 1;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
value = 2;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0)
value = 3;
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)
value = 4;
return value;
}
void LED_Disp(uint8_t ucled)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, ucled<<8, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
其中我比较纠结的地方在于
__HAL_TIM_SET_AUTORELOAD(&htim17,FRQ*R);
这个函数!我利用直接对htim17的period值进行赋值,但是没有啥用!但是又不想每次改变他的ARR值得时候重新配置这个定时器,于是我参考到这个函数可以直接进行对period值的修改。
对于以后对这些值的修改,可以直接利用_HAL_TIM_SET_中去寻找。
四、总结
第二场难度相较于第一场难度要低很多,我差不多是一个多小时写完的,比较简单,但是最开始竟然忘记要把555信号输出其的J9,J10引到PA1那里去才会测试频率…太蠢了
还有一个问题是LCD显示这个显示分频的时候,如果是个位数,需要对应着第9位,而我这里采用的%2d,使得个位数的时候对应的第10位,但是如果不用%2d的话,会导致每次调到10之后再调回来需要进行一次清屏,这就使得屏幕会在那一行一直闪…难搞!希望各位有好的方法能够交流一下!
还有三天就比赛了,冲!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)