武汉芯源CW32L083 LCD计数器

描述

【目的】实现一个计数器,按下按键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. 初始化按键

板载按键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;

}

}

}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分