利用cubemax配置stm32f103c8t6在lcd1602上显示一个计时器
时间: 2023-08-09 21:08:56 浏览: 333
STM32F103C8T6--时间(内部低速时钟).zip_STM32f103基于内部低速时钟的日期_f103c_f103c8t
5星 · 资源好评率100%
好的,以下是一个利用Cubemx配置STM32F103C8T6,在LCD1602上显示一个计时器的示例程序:
1. 首先,在Cubemx中进行如下配置:
- 选择STM32F103C8T6芯片;
- 配置时钟源为外部晶体振荡器,频率为8MHz;
- 配置SysTick定时器,1ms中断一次;
- 配置TIM2定时器,计数频率为1kHz;
- 配置GPIO,设置PA0为输入,PA1-PA7和PB0-PB3为输出,用于连接LCD1602;
- 配置TIM2的中断,使能Update事件中断;
2. 生成代码,打开生成的main.c文件,加入下面的代码:
```c
#include "main.h"
#include "lcd1602.h"
volatile uint32_t ms_ticks = 0;
volatile uint32_t elapsed_time = 0;
volatile uint8_t timer_started = 0;
void SysTick_Handler(void)
{
ms_ticks++;
}
void TIM2_IRQHandler(void)
{
if (TIM2->SR & TIM_SR_UIF)
{
TIM2->SR &= ~TIM_SR_UIF; // 清除中断标志位
if (timer_started)
elapsed_time++;
}
}
int main(void)
{
// 初始化系统时钟
HAL_Init();
// 配置外部晶体振荡器,频率为8MHz
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
// 配置PLL时钟源,设置SYSCLK为72MHz
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
// 初始化SysTick定时器,1ms中断一次
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
// 初始化TIM2定时器
__HAL_RCC_TIM2_CLK_ENABLE();
TIM_HandleTypeDef htim2;
htim2.Instance = TIM2;
htim2.Init.Prescaler = HAL_RCC_GetHCLKFreq() / 1000 - 1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0xFFFFFFFF;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK)
{
Error_Handler();
}
// 初始化GPIO
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3
| GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3
| GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, GPIO_PIN_RESET);
// 初始化LCD1602
lcd1602_init();
while (1)
{
// 检测PA0按键状态
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
{
if (!timer_started) // 开始计时
{
elapsed_time = 0;
timer_started = 1;
}
else // 停止计时
{
timer_started = 0;
}
HAL_Delay(50); // 延时去抖动
}
// 显示计时结果
if (timer_started || elapsed_time > 0)
{
// 将毫秒转换为秒和毫秒
uint32_t seconds = elapsed_time / 1000;
uint32_t milliseconds = elapsed_time % 1000;
// 将秒和毫秒显示在LCD1602上
lcd1602_gotoxy(0, 0);
lcd1602_printf("%02d:%02d.%03d", seconds / 60, seconds % 60, milliseconds);
}
else
{
lcd1602_clear();
}
}
}
```
这个程序使用了HAL库来进行初始化和操作,同时使用了lcd1602.h中的函数来控制LCD1602的显示。在程序中,我们使用PA0按键来控制计时器的开始和停止,并且在LCD1602上显示计时结果。你需要将lcd1602.h和lcd1602.c文件添加到工程中,并根据需要修改GPIO口和显示格式。
阅读全文