【目的】實現一個計數器,按下按鍵1開始計時,再次按下按鍵1實現暫停,再次按下,繼續計時。按下按鍵2實現清零。
【實現步驟】
1、初始化時鐘,代碼如下:
void RCC_Configuration(void)
{
/* 0. HSI使能并校準 */
// RCC_HSI_OUT();
RCC_HSI_Enable(RCC_HSIOSC_DIV6);
/* 1. 設置HCLK和PCLK的分頻系數 */
RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
// RCC_HCLK_OUT();
// __breakpoint(0);
/* 2. 使能PLL,通過HSI倍頻到64MHz */
RCC_PLL_Enable(RCC_PLLSOURCE_HSI, 8000000, RCC_PLL_MUL_8); // HSI 默認輸出頻率8MHz
// RCC_PLL_OUT();
///< 當使用的時鐘源HCLK大于24M,小于等于48MHz:設置FLASH 讀等待周期為2 cycle
///< 當使用的時鐘源HCLK大于48M,小于等于72MHz:設置FLASH 讀等待周期為3 cycle
__RCC_FLASH_CLK_ENABLE();
FLASH_SetLatency(FLASH_Latency_3);
/* 3. 時鐘切換到PLL */
RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL);
RCC_SystemCoreClockUpdate(64000000);
/* 4. 配置外設時鐘 */
// __RCC_GPIOF_CLK_ENABLE();
// __RCC_GPIOE_CLK_ENABLE();
// __RCC_GPIOD_CLK_ENABLE();
// __RCC_GPIOC_CLK_ENABLE();
// __RCC_GPIOB_CLK_ENABLE();
// __RCC_GPIOA_CLK_ENABLE();
// __RCC_LCD_CLK_ENABLE();
}
- 初始化按鍵
板載按鍵1為PA4,按鍵2為PA5,根據原理圖,都接了上位電阻,所以需要配置為下拉中斷觸發。
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* 配置PA4、PA5為按鍵輸入 */
GPIO_InitStruct.IT = GPIO_IT_FALLING;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pins = GPIO_PIN_4 | GPIO_PIN_5;
__RCC_GPIOA_CLK_ENABLE();
GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
}
3、中斷配置
void NVIC_Configuration(void)
{
__disable_irq();
// NVIC_EnableIRQ(WDT_IRQn);
NVIC_SetPriority(GPIOA_IRQn, 0);
// NVIC_SetPriority(SysTick_IRQn, 1);
NVIC_EnableIRQ(GPIOA_IRQn);
__enable_irq();
}
4、中斷回調函數,在中斷回調中只清除中斷標志,業務處理在主函數中處理:
/**
- @brief This funcation handles GPIOA
*/
void GPIOA_IRQHandler(void)
{CW_GPIOA->ICR = 0; //清除中斷標志
}
5、LCD驅動
在LCD驅動中,我們初始化LCD(具體見官方示例),然后是書寫LCD數字顯示驅動,具體代碼如下:
#include "lcd.h"
// 7 6 5 4 3 2 1 0
// RAM01 RAM00 RAM03 RAM02 RAM801 RAM10 RAM13 RAM12 RAM92 RAM91
/* 段碼低8(左) */
static uint8_t num_L[10] = {
0x0d, //0
0x00, //1
0x0e, //2
0x0a, //3
0x03, //4
0x0b, //5
0x0f, //6
0x00, //7
0x0f, //8
0x0b, //9
};
/* 段碼高8(右) */
static uint8_t num_H[10] = {
0x07,
0x06,
0x03,
0x07,//3
0x06,//4
0x05, //5
0x05, //
0x07, //7
0x07, //8
0x07, //9
};
void show_nums(uint32_t num)
{
uint8_t i=0;
uint8_t j;
uint32_t temp;
temp = num;
//空顯示
CW_LCD->RAM0 = 0;
CW_LCD->RAM1 = 0;
CW_LCD->RAM8 = 0;
CW_LCD->RAM9 = 0;
if(temp == 0)
show_num(0,0);
while(temp>0)
{
j = temp%10;
show_num(i,j);
temp /=10;
i++;
}
}
void show_num(uint8_t wei, uint8_t num)
{
switch(wei)
{
case 7:
{
//顯示第7個數碼管
CW_LCD->RAM0 |= num_H[num]<<8 | num_L[num];
break;
}
case 6:
{
//顯示第6個數碼管
CW_LCD->RAM0 |= (num_H[num]<<8 | num_L[num]) <<16;
break;
}
case 5:
{
//顯示第5個數碼管
CW_LCD->RAM1 |= num_L[num];
CW_LCD->RAM8 |= num_H[num];
break;
}
case 4:
{
//顯示第4個數碼管
CW_LCD->RAM8 |= num_H[num]<<16 | num_L[num]<<8;
break;
}
case 3:
{
//顯示第3個數碼管
CW_LCD->RAM8 |= num_L[num]<<24;
CW_LCD->RAM9 |= num_H[num];
break;
}
case 2:
{
//顯示第2個數碼管
CW_LCD->RAM9 |= num_H[num]<<16 | num_L[num]<<8;
break;
}
case 1:
{
//顯示第1個數碼管
CW_LCD->RAM1 |= num_H[num]<<8;
CW_LCD->RAM9 |= num_L[num]<<24;
break;
}
case 0:
{
//顯示第0個數碼管
CW_LCD->RAM1 |= num_H[num]<<24 | num_L[num]<<16;
break;
}
}
}
void LCD_Configuration(void)
{
LCD_InitTypeDef LCD_InitStruct = {0};
LCD_InitStruct.LCD_Bias = LCD_Bias_1_3;
LCD_InitStruct.LCD_ClockSource = LCD_CLOCK_SOURCE_LSI;
LCD_InitStruct.LCD_Duty = LCD_Duty_1_4;
LCD_InitStruct.LCD_ScanFreq = LCD_SCAN_FREQ_256HZ;
LCD_InitStruct.LCD_VoltageSource = LCD_VoltageSource_Internal;
__RCC_LCD_CLK_ENABLE();
RCC_LSI_Enable();
LCD_Init(&LCD_InitStruct); //基本配置
// BTL004 LCD 對應的連接
//PA12 COM3
//PA11 COM2
//PA10 COM1
//PA09 COM0
//PA08 SEG0
//PC09 SEG1
//PC08 SEG2
//PC07 SEG3
//PC06 SEG4
//PD15 SEG32
//PD14 SEG33
//PD13 SEG34
//PD12 SEG35
//PD11 SEG36
//PD10 SEG37
//PD09 SEG38
//PD08 SEG39
//PB15 SEG5
//PB14 SEG6
//PB13 SEG7
// 分配引腳
LCD_COMConfig(LCD_COM0 | LCD_COM1 | LCD_COM2 | LCD_COM3, ENABLE);
LCD_SEG0to23Config(0x0000FF, ENABLE);
LCD_SEG32to55Config(0x0000FF,ENABLE);
CW_LCD->RAM[0] = 0;
CW_LCD->RAM[1] = 0;
CW_LCD->RAM2 = 0;
CW_LCD->RAM3 = 0;
CW_LCD->RAM4 = 0;
CW_LCD->RAM5 = 0;
CW_LCD->RAM6 = 0;
CW_LCD->RAM7 = 0;
CW_LCD->RAM8 = 0;
CW_LCD->RAM9 = 0;
CW_LCD->RAM10 = 0;
CW_LCD->RAM11 = 0;
CW_LCD->RAM12 = 0;
CW_LCD->RAM13 = 0;
LCD_Cmd(ENABLE);
CW_LCD->RAM0 = 0x0f0f;
LCD_ContrastConfig(LCD_Contrast_Level_2);
LCD_DriveVoltageConfig(LCD_INRS_LEVEL_0);
}
5、主函數中,我們檢查按鍵1、按鍵2,并做出相應的處理。具體代碼如下:
#include "main.h"
void NVIC_Configuration(void);
void RCC_Configuration(void);
uint8_t Key1Count = 0;
uint8_t Key2Count = 0;
int32_t main(void)
{
uint32_t show_conut=0;
uint32_t time_count = 0;
CW_SYSCTRL->AHBEN_f.GPIOC = 1U; //Open GPIOA Clk
CW_GPIOC->ANALOG_f.PIN2 = 0U; //Digital
CW_GPIOC->BRR_f.BRR2 = 1U; //Reset PA00
CW_GPIOC->DIR_f.PIN2 = 0U; //Output
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
LCD_Configuration();
show_nums(show_conut);
while(1)(//file1.elecfans.com/web2/M00/8A/01/wKgaomSOTM-AOJUkAAWbBlv4TTM763.zip)
{
if(PA04_GETVALUE() == 0)
{
FirmwareDelay( 20000 );
if(PA04_GETVALUE() == 0)
{
Key1Count++;
}
}
if(PA05_GETVALUE() == 0)
{
FirmwareDelay( 20000 );
if(PA05_GETVALUE() == 0)
{
Key2Count++;
}
}
//如果按下2暫停顯示
if(Key1Count == 2 )
{
Key1Count=0;
}
//按下K2清零,停止顯示
if(Key2Count==1)
{
show_conut = 0;
Key1Count = 0;
Key2Count = 0;
show_nums(show_conut);
}
FirmwareDelay( 200 );
time_count ++;
if(time_count > 1000)
{
time_count = 1;
//如果按下1開始顯示
if(Key1Count ==1)
{
show_conut ++;
show_nums(show_conut);
}
//溢出清零
if(show_conut==65535)
{
show_conut=0;
}
//翻轉LED1
CW_GPIOC->TOG = bv2;
}
}
}
-
lcd
+關注
關注
34文章
4424瀏覽量
167400 -
計數器
+關注
關注
32文章
2256瀏覽量
94476 -
RCC
+關注
關注
0文章
93瀏覽量
26932 -
LCD驅動
+關注
關注
4文章
88瀏覽量
26639
發布評論請先 登錄
相關推薦
評論