这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取手持数字示波器】ACM32F070LCD屏和触控按键功驱动蜂鸣器分享

共3条 1/1 1 跳转至

【换取手持数字示波器】ACM32F070LCD屏和触控按键功驱动蜂鸣器分享

工程师
2024-04-19 19:58:35   被打赏 40 分(兑奖)     打赏

实现步骤与计划:

ACM32F070是一款功能强大的MCU,它提供了丰富的外设接口和强大的性能,非常适合用于各种嵌入式应用的开发。

关于点亮LCD屏和触控按键功能操作,以及驱动蜂鸣器测评,下面是一些建议和指导:



  1. 硬件连接:首先,确保LCD屏与开发板之间的连接正确无误。通常,你需要将LCD屏的电源、地线、数据线等接口与开发板上的对应接口相连。

  2. 驱动配置:查阅ACM32F070的文档,了解如何配置LCD控制器或相关的GPIO接口。根据LCD屏的规格和要求,设置正确的数据格式、时序等参数。

  3. 编程实现:编写代码来初始化LCD控制器,并发送图像数据到LCD屏上显示。这通常涉及到对LCD控制器的寄存器进行操作,以及准备和发送图像帧数据。

触控按键功能操作

  1. 硬件连接:同样,确保触控按键模块与开发板之间的连接正确。这通常包括电源、地线以及用于传输触控数据的接口。

  2. 驱动配置:配置相关的GPIO接口或触控控制器,以接收和处理触控数据。

  3. 编程实现:编写代码来读取触控数据,并根据需要执行相应的操作。例如,你可以编写一个函数来检测是否有按键被按下,并根据按下的按键执行不同的操作。

驱动蜂鸣器测评

  1. 硬件连接:将蜂鸣器模块与开发板上的PWM或GPIO接口相连。确保连接正确,避免短路或损坏设备。

  2. 驱动配置:根据蜂鸣器的类型(有源或无源)和规格,配置相应的PWM或GPIO接口。对于有源蜂鸣器,你可能只需要控制其电源线的通断;对于无源蜂鸣器,你可能需要使用PWM信号来调节其发声频率和音量。

  3. 编程实现:编写代码来驱动蜂鸣器发声。你可以根据需要调整PWM信号的频率和占空比,以产生不同的音效和节奏。

原理图:

蜂鸣器

image.png

触摸按键

image.png


image.png

LCD:

image.png


代码:

COM0 COM1 COM2 COM3分别是接PA9 PA10 PA11 PA12,其它的就请见上图,和上上图。
下面我上代码:
蜂鸣器
#define BUZZER_GPIO_PORT GPIOD
#define BUZZER_GPIO_PIN  GPIO_PIN_1
定义GPIOD口的Pin的1脚。
void BUZZER_Init(void)
{
    GPIO_InitTypeDef GPIOx_Handle;    
    GPIOx_Handle.Pin       = BUZZER_GPIO_PIN;
    GPIOx_Handle.Mode      = GPIO_MODE_OUTPUT_PP;
    GPIOx_Handle.Pull      = GPIO_NOPULL;
    GPIOx_Handle.Alternate = GPIO_FUNCTION_0;
    HAL_GPIO_Init(BUZZER_GPIO_PORT, &GPIOx_Handle);  
    HAL_GPIO_WritePin(BUZZER_GPIO_PORT, BUZZER_GPIO_PIN, GPIO_PIN_CLEAR);
}
蜂鸣器工作函数:
    GPIOCD->SET = (GPIO_PIN_1<<16);
    System_Delay_MS(200);
    GPIOCD->CLR = (GPIO_PIN_1<<16);
这里延时200MS,蜂鸣器的声音更加响亮。
触摸按键:
uint8_t TouchKey_Init(void)
{
    uint8_t ret = 0;
    TKEY_Init();
    TKEY_Calibrate_ParaInit();
    ret = TKEY_Quick_Calibrate(); //校准无触摸时的读取数据寄存器值 
    TKEY_Timer_ScanInit();
    TKEY_Timer_Scan_Start(); 
    TKEY_DEBUG("sgu16_RawDataRangRatio = %d\n", sgu16_RawDataRangRatio);
    TKEY_DEBUG("sgu8_TKEYScanTime = %d\n", sgu8_TKEYScanTime); 
    return ret;
}
按键的滤波:
#define TKEY_DEBIN        2  
#define TKEY_DEBOUT    2 
扫描按键获取值:
uint8_t TK_TimerSacn_GetKeyVal(void)
{
    uint8_t  ucKey = 0xFF;
    TKEY_Timer_Scan_Result(&ucKey);
#ifdef TKEY_WAVEFORM_OUTPUT    
    TK_DebugDataOut();
#endif
    return ucKey;
}
void TKEY_Timer_Scan_Result(uint8_t *pucKey)
{
    *pucKey = 0xFF;
#ifdef TKEY_FIFO_ENABLE
    if(FIFO_Query(&TKEY_Fifo))
    {
        FIFO_Out(&TKEY_Fifo, pucKey);
    }
#endif
}
按键如果看不明白,可以看原DEMO,我这里不多介绍。
下面是屏的相关代码,我把我用的全赋上,屏是用的YR1618。
先上初始化:
void LCD_Init_YR1618A(void)
{  
    memset(&lcdhandle_YR1618A,0,sizeof(lcdhandle_YR1618A));//初始化清零Handle
    lcdhandle_YR1618A.Instance=LCD;
    lcdhandle_YR1618A.Init.Bias=LCD_BIAS_1_3;
    lcdhandle_YR1618A.Init.Duty=LCD_DUTY_1_4;
    lcdhandle_YR1618A.Init.DisplayMode=LCD_DisplayMode_1;
    lcdhandle_YR1618A.Init.LCDFrequency=LCD_LCDFrequency_512HZ;
    lcdhandle_YR1618A.Init.Driving_Waveform=LCD_Driving_Waveform_B;
    lcdhandle_YR1618A.Init.BiasSrc=LCD_BiasSrc_InRes_Seg31_35_Normal;//内部电阻模式
    //   lcdhandle_YR1618A.Init.BlinkEN=LCD_BlinkEN_Enable;//闪频使能
    lcdhandle_YR1618A.Init.BlinkFrequency =0x3;//帧间隔时间,影响帧中断时间和LCD DMA请求时间 以及闪烁时间
    HAL_LCD_Init(&lcdhandle_YR1618A);
    LCD_InResInitTypeDef  Resstrcut;
    memset(&Resstrcut,0,sizeof(Resstrcut));//初始化清零Handle
    Resstrcut.Contrast=LCD_Contrast_903VDD;
    Resstrcut.BiasRes=LCD_BiasRes_240k;//LCD_BiasRes_240k  LCD_BiasRes_4M
    Resstrcut.FastCharge=LCD_FastCharge_Enable;//快速充电配置
    Resstrcut.PONTime=0x3f;
    Resstrcut.DriveMod=LCD_DriveMod_FC;//LCD_DriveMod_FC
    HAL_LCD_InResConfig(&lcdhandle_YR1618A,&Resstrcut);
    LCD_GPIO_Config_YR1618A();
    LCD_SegCom_Config_YR1618A(); 
}
再上一个IO的配置:这里我介绍一下,担心会有看不明白的。
void LCD_GPIO_Config_YR1618A(void)
{
清GPIO的YR1618初始化
    memset(&GPIO_Init_YR1618A,0,sizeof(GPIO_Init_YR1618A));
下面的是配置COM0 COM1 COM2 COM3的GPIO,这个端口是PA口,分别是PA9 PA10 PA11 PA12
还有SEG14 SEG0和SEG13的PA4 PA8 PA0;
    /* COM0-COM3:PA9-PA12  SEG0:PA8  */
    GPIO_Init_YR1618A.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_8|GPIO_PIN_4|GPIO_PIN_0;    
    GPIO_Init_YR1618A.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOA, &GPIO_Init_YR1618A);//
    这里是配置SEG1-4的GPIO口对应的脚位是PC6到PC9
    /* SEG1-4:PC9-6 */
    GPIO_Init_YR1618A.Pin = GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_0;    
    GPIO_Init_YR1618A.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOC, &GPIO_Init_YR1618A);    
    
    /* SEG5-7:PB15-13 */
    GPIO_Init_YR1618A.Pin = GPIO_PIN_0|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_15|GPIO_PIN_14|GPIO_PIN_13;    
    GPIO_Init_YR1618A.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOB, &GPIO_Init_YR1618A);  
    /* SEG5-7:PD5, =1*/
    GPIO_Init_YR1618A.Pin = GPIO_PIN_5;    
    GPIO_Init_YR1618A.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOD, &GPIO_Init_YR1618A);      
}
void LCD_SegCom_Config_YR1618A(void)
{
    LCD_SegComInitStructure2.SEG0_31=0xF0371C00;//开启SEG0-SEG70xF0371C00
    LCD_SegComInitStructure2.Stc_SEG32_39_COM0_8.SEG32_39_COM0_8=0xFFFFFFFF;//初始化LCD_POEN1寄存器 关闭全部输出
    LCD_SegComInitStructure2.Stc_SEG32_39_COM0_8.SEGCOM_bit.COM0_3=0;//开启COM0-COM3
    LCD_SegComInitStructure2.Stc_SEG32_39_COM0_8.SEGCOM_bit.SEG32_35=0xf;//关闭SEG32_35和COM4-7
    LCD_SegComInitStructure2.Stc_SEG32_39_COM0_8.SEGCOM_bit.SEG36_COM7=1;
    LCD_SegComInitStructure2.Stc_SEG32_39_COM0_8.SEGCOM_bit.SEG37_COM6=1;
    LCD_SegComInitStructure2.Stc_SEG32_39_COM0_8.SEGCOM_bit.SEG38_COM5=1;
    LCD_SegComInitStructure2.Stc_SEG32_39_COM0_8.SEGCOM_bit.SEG39_COM4=1;
    HAL_LCD_SegComConfig(&lcdhandle_YR1618A,&LCD_SegComInitStructure2);
}
再上显示数字:这里我上传两断DEMO中比较经典的,个人写的非常的乱,只上传图片好了。
void LCD_DisplayNum_YR1618A(uint32_t Num)
 {
    uint32_t ram_buff[4];
    ram_buff[0]=0;
    ram_buff[1]=0;
    ram_buff[2]=0;
    ram_buff[3]=0;
//  ram_buff[4]=0;
    if(Num>9999) Num=9999;//4位数,最大显示9999
    Get_RAM_NUM_DATA(ram_buff,Num,Num);
    HAL_LCD_Write(&lcdhandle_YR1618A,0,ram_buff[0]);
    HAL_LCD_Write(&lcdhandle_YR1618A,1,ram_buff[1]);
    HAL_LCD_Write(&lcdhandle_YR1618A,2,ram_buff[2]);
    HAL_LCD_Write(&lcdhandle_YR1618A,3,ram_buff[3]);
//   HAL_LCD_Write(&lcdhandle_YR1618A,4,ram_buff[4]);
 }
8位动态显示0-9
void LCD_DisplayNum_YR1618A_INIT()
{
    uint16_t i=0; 
    uint32_t ram_buff[5];
    uint16_t numi=6;//5
    for(numi=0;numi<8;numi++)
    {
        System_Delay_MS(100);
        for(i=0;i<10;i++)
        {
            ram_buff[0]=0;
            ram_buff[1]=0;
            ram_buff[2]=0;
            ram_buff[3]=0;
            if(numi==4)
            {
            ram_buff[0]=NUM5_RAM0_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[1]=NUM5_RAM1_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[2]=NUM5_RAM2_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[3]=NUM5_RAM3_DIS<<NUM_RAM_OFFSET[numi];
            }
            else if(numi==6)
            {
            ram_buff[0]=NUM7_RAM0_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[1]=NUM7_RAM1_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[2]=NUM7_RAM2_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[3]=NUM7_RAM3_DIS<<NUM_RAM_OFFSET[numi];
            }
            else
            {
            ram_buff[0]=NUM123468_RAM0_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[1]=NUM123468_RAM1_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[2]=NUM123468_RAM2_DIS<<NUM_RAM_OFFSET[numi];
            ram_buff[3]=NUM123468_RAM3_DIS<<NUM_RAM_OFFSET[numi];
            }
            HAL_LCD_Write(&lcdhandle_YR1618A,0,ram_buff[0]);
            HAL_LCD_Write(&lcdhandle_YR1618A,1,ram_buff[1]);
            HAL_LCD_Write(&lcdhandle_YR1618A,2,ram_buff[2]);
            HAL_LCD_Write(&lcdhandle_YR1618A,3,ram_buff[3]);
            System_Delay_MS(100);//初始化时每个项显示时间,方便检测每一段显示状态
        }
    }
}

实现效果:

image.png

点亮LCD屏image.png

实现0-9显示:

image.png




专家
2024-04-20 00:07:55     打赏
2楼

感谢楼主分享


菜鸟
2024-04-20 10:42:07     打赏
3楼

好腻害,谢谢分享


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]