前言
本次记录的是第十一届的省赛题目,这届题目比较好实现,非常适合我^_^
一、程序设计题目介绍
二、实现的功能模块
1.LCD显示
//数据界面显示
void data_menu_show(double v,uint menu_mode)
{
//当前模式,当前显示界面对应的LED显示
Led_Display(menu_mode,view_chart);
//显示数据界面
LCD_DisplayStringLine(Line0 ,(unsigned char *)" Data ");
sprintf(text1," V:%.2fV ",v);
LCD_DisplayStringLine(Line2 ,(unsigned char *)text1);
if(menu_mode)
LCD_DisplayStringLine(Line4 ,(unsigned char *)" Mode:MXNU ");
else
LCD_DisplayStringLine(Line4 ,(unsigned char *)" Mode:AUTO ");
}
//参数界面显示
void para_menu_show(uint pa6_duty,uint pa7_duty)
{
LCD_DisplayStringLine(Line0 ,(unsigned char *)" Para ");
sprintf(text1," PA6:%d%% ",pa6_duty);
LCD_DisplayStringLine(Line2 ,(unsigned char *)text1);
sprintf(text1," PA7:%d%% ",pa7_duty);
LCD_DisplayStringLine(Line4 ,(unsigned char *)text1);
}
2.LED模块
/*******************************************************************************
* 函数名 : Led_Display
* 功能 : 两种运行模式分别对应的LED亮灭情况
* 输入 : mode---当前运行模式 0---自动模式 1---手动模式
:view_chart---当前显示界面 0---数据界面 1---参数界面
* 返回值 : 无
*******************************************************************************/
void Led_Display (unsigned int mode,unsigned int view_chart)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
if(mode==0)
{
HAL_GPIO_WritePin(GPIOC,0x01<<8,GPIO_PIN_RESET);
}
else
HAL_GPIO_WritePin(GPIOC,0x01<<8,GPIO_PIN_SET);
if(view_chart==0)
HAL_GPIO_WritePin(GPIOC,0x02<<8,GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GPIOC,0x02<<8,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
3.按键模块:
cubemx设置:
这里我就把pwm的设置也放在这里,就正好ヽ(ー_ー)ノ
//回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM4)
{
keys[0].key_state=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
keys[1].key_state=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
keys[2].key_state=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
keys[3].key_state=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
int i;
for(i=0;i<4;i++)
{
switch(keys[i].key_tip)
{
case 0:
{
if(keys[i].key_state==0)
{
keys[i].key_tip=1;
}
}
break;
case 1:
{
if(keys[i].key_state==0)
{
keys[i].key_tip=2;
}
else
{
keys[i].key_tip=0;
}
}
break;
case 2:
{
if(keys[i].key_state==1)
{
keys[i].key_tip=0;
keys[i].key_flag=1;
signal=i;
//若是切换显示界面,则将界面的标志进行改变
if(signal==0)
view_chart=!view_chart;
//若是切换模式,则将模式的标志进行改变
if(signal==3)
menu_mode=!menu_mode;
}
}
break;
}
}
}
}
4.ADC模块:
uint16_t getADC(void)
{
uint16_t adc1=0;
HAL_ADC_Start(&hadc2);
adc1= HAL_ADC_GetValue(&hadc2);
HAL_ADC_Stop(&hadc2);
return adc1;
}
这里我把测量的模拟信号计算没有放到这个函数中,是直接在外面进行计算
5.其他功能实现函数:
//自动模式下,占空比的设置
void changePwmFrd_Auto(void)
{
//自动模式 电压值为0V
if(menu_mode%2 == 0 && volt == 0)
{
__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,999);
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,999);
}
//自动模式 电压值为3.3V
else if(menu_mode%2 == 0 && volt >= 3.3)
{
__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,0);
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,0);
}
}
//LCD显示,LED显示
void Display()
{
if(view_chart%2==0)
data_menu_show(volt,menu_mode);
else
para_menu_show(pa6_duty,pa7_duty);
Led_Display (menu_mode,view_chart);
}
void Work()
{
volt=getADC()*3.3/4096;
Key_Contr(signal,view_chart,menu_mode);
changePwmFrd_Auto();
Display();
}
这里使用到的函数__HAL_TIM_SetCompare的第三个参数需要根据你想要的占空比以及你设置的ARR来进行确定,他们三者有以下关系:
ARR--表示一个周期内的总计数
只要当前的计数小于该函数的第三个参数,那么就是高电平,一旦大于就是低电平。
占空比--高电平占整个周期的一个比重。
(这里你们可以稍微看下,具体的你们可以自行搜索,因为这里我不太会描述,加上就是自己记录,所以就没有那么的完美表达,)
main函数部分:
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
//标明按下的键是哪个键 例如 signal=0 --- 按下B1键
uint signal=100;
//标明当前所处界面是数据界面还是参数界面 view_chart=0---数据界面显示 view_chart=1---参数界面显示
uint view_chart=0;
uint menu_mode=0; //运行模式的标志 0--自动模式 1--手动模式
char text[30];
uint pa6_duty=10;
uint pa7_duty=10;
float volt;
uint count=0;
//保存两种运行模式的显示部分
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM4_Init();
MX_TIM16_Init();
MX_TIM17_Init();
MX_ADC1_Init();
MX_ADC2_Init();
/* USER CODE BEGIN 2 */
LCD_Init(); //LCD初始化
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
//打开定时器TIM4
HAL_TIM_Base_Start_IT(&htim4);
//打开pwm输出
HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
//上电初始化
data_menu_show(getADC(&hadc1),menu_mode);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Work();
}
/* USER CODE END 3 */
}
总结
好啦,十一届省赛的题目就记录到这了,希望在记录的同时也可以帮助到同样在学习的你们。
最后,也希望记录当中存在的错误或者不足可以得到你们的指正get!٩( 'ω' )و