嵌入式开发7279A数码管 键盘

摘要

HD7279A硬件电路图HD7279A是一种管理键盘和LED显示器的专用智能控制芯片。它能对8位共阴极LED显示器或64个LED发光管进行管理和驱动,同时能对多达8×8的键盘矩阵的按键情况进行监视,具有自动消除键抖动并识别按键代码的功能,从而可以提高CPU工作的效率。HD7279A和微处理器之间采用串行接口,其接口电路和外围电路简单,占用口线少,加之它具有较高的性能价格比,因此,在微型控制器、智能仪表、控制面板和家用电器等领域中日益获得广泛的应用。

关键词: HD7279A 接口电路 接口程序

一.引脚说明与接口电路

要求: 了解即可(编程涉及)

  1. RC引脚用于连接HD7279A的外接振荡元件

  1. RESET为复位端,该端由低电平变成高电平并保持25ms即复位结束

  1. IG0~DIG7分别为8个LED管的位驱动输出端

  1. SA~SG分别为LED数码管的A段~G段的输出端

  1. DP为小数点的驱动输出端

  1. DIG0~DIG7和SA~SG同时还分别是64键盘的列线和行线端口,完成对键盘的监视、译码和键码的识别。

  1. 在8×8阵列中每个键的键码是用十六进制表示的,可用读键盘数据指令读出,其范围是00H~3FH。

  1. HD7279与微处理器仅需4条接口线,其中CS为片选信号(低电平有效)。

  1. 当微处理器访问HD7279A(读键号或写指令)时,应将片选端置为低电平。

  1. DATA为串行数据端,当向HD7279A发送数据时,DATA为输入端;

  1. 当HD7279A输出键盘代码时,DATA为输出端。

  1. CLK为数据串行传送的同步时钟输入端,时钟的上升沿表示数据有效。

  1. KEY为按键信号输出端,在无键按下时为高电平;而有键按下时此引脚变为低电平并且一直保持到键释放为止。

二.控制指令

要求: 了解皆可(编程涉及)

  1. 复位指令。指令代码为A4H,其功能为清除所有显示,包括字符消隐属性和闪烁属性。

  1. 测试指令。指令代码为BFH,其功能为将所有的LED点亮并闪烁,可用于自检。

  1. 左移指令。指令代码为A1H,其功能为将所有的显示左移1位,移位后,最右位空(无显示),不改变消隐和闪烁属性。

  1. 右移指令。指令代码为A0H,其功能与左移指令相似,只是方向相反。

  1. 循环左移指令。指令代码为A3H,其功能为将所有的显示循环左移1位。移位后,最左位内容移至最右位,不改变消隐和闪烁属性。

  1. 循环右移指令。指令代码为A2H,其功能与循环左移指令相似,只是方向相反。

三.时序

要求:会看更好(代码涉及)

备注: 暂时可以只会第一种

1.纯指令时序:微处理器发出8个CLK脉冲,向HD7279A传送8位指令。DATA引脚为高阻状态

带数据指令时序:微处理器发出16个CLK脉冲,前8个向HD7279A传送8位指令;后8个向HD7279A传送8位数据。DATA引脚为高阻状态

读键盘指令时序:微处理器发出16个CLK脉冲,前8个向HD7279A传送8位指令, DATA引脚为高阻状态;后8个由HD7279A向微处理器返回8位按键代码,DATA引脚为输出状态。在最后1个CLK脉冲的下降沿DATA引脚恢复高阻状态

四.7279数码管显示案例

要求:都要看懂哦

#include "stm32f4xx.h"

#define      CMD_RESET         0xA4    //  7279的复位命令
#define      CMD_TEST          0xBF    //  7279的测试命令
#define      CMD_LEFT          0xA1    //  7279的左移位命令
#define      CMD_READ          0x15    //  7279的读缓冲命令
#define      DECODE1           0xC8    //  7279的译码显示命令

// 硬件资源引脚定义
// HD7279CS          PC12
// HD7279CLK         PA3
// HD7279DATA        PA5
// HD7279INT         PA0

// HD7279CS  PC12
#define      HD7279CS_L          GPIO_ResetBits(GPIOC, GPIO_Pin_12)   //PC12输出0
#define      HD7279CS_H          GPIO_SetBits(GPIOC, GPIO_Pin_12)     //PC12输出1

// HD7279CLK PA3
#define      HD7279CLK_L         GPIO_ResetBits(GPIOA, GPIO_Pin_3)    //PA3输出0
#define      HD7279CLK_H         GPIO_SetBits(GPIOA, GPIO_Pin_3)      //PA3输出1

// HD7279DATA PA5
#define      HD7279DATA_L        GPIO_ResetBits(GPIOA, GPIO_Pin_5)    //PA5输出0
#define      HD7279DATA_H        GPIO_SetBits(GPIOA, GPIO_Pin_5)      //PA5输出1

// 函数名称:GPIO配置函数
// 输入参数:无
// 输出参数:无
// HD7279CS      PC12
// HD7279CLK     PA3
// HD7279DATA    PA5
void HD7279_GPIO_Configuration(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    //  HD7279CS PC12
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    //  HD7279CLK PA3、HD7279DATA PA5
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    HD7279CS_H;
    HD7279CLK_H;
    HD7279DATA_H;
}

// 函数名称:发送1字节数据函数
// 输入参数:数据
// 输出参数:无

void send_byte(unsigned char out_byte )
{
    unsigned short  i;                   //    设置循环变量
    HD7279CS_L;                          //    置低片选信号
    delay_us(50);
    for (i = 0; i < 8; i++)             //    写入8 bit数据
    {   
         if (out_byte & 0x80)           //    最高位为1
        {
            HD7279DATA_H;               //    数据线输出高电平
         }
        else
        {
            HD7279DATA_L;               //    否则输出低电平
        }
        HD7279CLK_H;                    //    置高时钟位
        delay_us(50);
        HD7279CLK_L;                    //    置低时钟位
        delay_us(50);
        out_byte <<= 1;                //    输出参数变量右移一位
    }
}

// 函数名称:写数据和命令函数
// 输入参数:命令、数据
// 输出参数:无

void write7279(unsigned char cmd, unsigned char dat)  //    向LED写显示数据和命令
{    
    if (cmd != 255) 
    {  
        send_byte(cmd);                              //    写命令
    }
//    delay_ms(10);
    if (dat != 255) 
    {
        send_byte(dat&15);                           //    写显示数据
    } 
}
// 小案例
unsigned char Int_flag = 0;
int main(void)
{ 
    unsigned char i = 0;
    unsigned char j = 0;
    SysTick_Init();                    //  系统滴答定时器初始化
    HD7279_GPIO_Configuration();
    send_byte(CMD_RESET);              //    复位7279 
    delay_ms(1000);
    test7279();                        //    7279运行测试程序
    while(1)
    {
        write7279(DECODE1 + i, j);                                        
        i++;   
        j++;        
        if (i > 7) 
        {
            i = 0;
        }
        if (j > 9) 
        {
            j = 0;
        }
        delay_ms(1000);
    }
}

五.7279键盘案例

要求:都要会哦


// 函数名称:DATA设置为输入模式
// 输入参数:无
// 输出参数:无
// HD7279DATA    PA5
void DATA_IN(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    //HD7279DATA PA5    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);             
//  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);              
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;                      
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                     
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;          
    GPIO_Init(GPIOA, &GPIO_InitStructure);  
}

// 函数名称:DATA设置为输出模式
// 输入参数:无
// 输出参数:无
// HD7279DATA    PA5

void DATA_OUT(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    //HD7279DATA PA5
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

// 函数名称:中断配置函数
// 输入参数:无
// 输出参数:无
// HD7279INT  PA0

void INT_Configuration(void)
{         
    EXTI_InitTypeDef   EXTI_InitStructure;
    GPIO_InitTypeDef   GPIO_InitStructure;
    NVIC_InitTypeDef   NVIC_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);               //  使能IO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);              //  使能SYSCFG时钟

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;                        //  输入
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                        //  设置上接
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                           //  IO口为0
    GPIO_Init(GPIOA, &GPIO_InitStructure);                             

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);       //  初始化中断线0

    EXTI_InitStructure.EXTI_Line = EXTI_Line0;                          //  配置中断线为中断线0
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                 //  配置中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;             //  配置为下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                           //  配置中断线使能
    EXTI_Init(&EXTI_InitStructure);                              

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;             
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

// 函数名称:接收1字节数据函数
// 输入参数:数据
// 输出参数:无
unsigned char receive_byte (void)                                  
{
    unsigned char i, in_byte = 0;                        
    unsigned char temp = 0;    
    HD7279DATA_H;                                                            
    Delay_us(15);
    for (i = 0; i < 8; i++)                            //    读出8 bit数据
    {
        HD7279CLK_H;                                    //    置高时钟位
        Delay_us(10);
        in_byte <<= 1;                                 //    已收到的数据移位
        DATA_IN();  
        temp = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);
        if (temp == 1)  
        {
            in_byte |= 1;                               //    向数据中增加一位
        }
        HD7279CLK_L;                                    //    置低时钟位
        Delay_us(10);
    }
    DATA_OUT();
    HD7279DATA_L;                                        //    数据线输出低电平
    Delay_us(10); 
    return(in_byte);                                    //    返回接收到的数据
}

// 函数名称:读7279
// 输入参数:无
// 输出参数:无

unsigned char read7279(void)                              //    读键值
{
    unsigned char temp = 0;
    send_byte(CMD_READ);                                 //    发送读键值命令
    temp = receive_byte();
    return temp;                                         //    返回键值
}
// 测试
void test7279(void)                                                   //    显示测试程序
{
     send_byte(CMD_TEST);                                            //    发送测试命令
     Delay_ms(1000);                                                 //    等待以便观察
     send_byte(CMD_RESET);                                           //    发送复位命令
}

int main(void)
{     
    unsigned char temp = 0;
    char buf[5] = {0};
    SysTick_Init();                                                     //  系统滴答定时器初始化
    lcd_init();                                                         //  液晶初始化
    lcd_clear(Black);                                                   //  设置液晶背景
    LCD_DrawRectangle(0,0, 479, 271, Green);
    LCD_DrawRectangle(5,5, 474, 266, Green);
    LCD_ShowString(10, 60, "由于IO口复用,所以请打开所有模块的电源开关", Red, Black); 
    LCD_ShowString(10, 100, "现象:", Red, Black); 
    LCD_ShowString(10, 120, "1.按下按键,观察数码管和液晶上显示的数据", Red, Black); 
    HD7279_GPIO_Configuration();  
    INT_Configuration();                                                 //  7279中断引脚配置
    send_byte(CMD_RESET);                                                //    复位7279
    Delay_ms(1000);
    test7279();                                                          //    7279测试
    while(1)
    {            
        if (Int_flag == 1)
        {    
            Int_flag = 0;   
            temp = read7279();
            write7279(CMD_LEFT, 0xff);
            sprintf(buf, "%2X", temp);
            LCD_ShowString(200, 180, (unsigned char*)buf, White, Black);
            write7279(DECODE1, temp);
        }
    }
}

六.球球关注

关注b站 : Chasbaby bili_24795983555

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
嵌入式系统中,矩阵键盘数码管通常是通过GPIO口进行控制。下面是一个简单的程序示例,可以实现矩阵键盘控制数码管显示0-F。 首先,需要在程序中定义矩阵键盘的引脚和数码管的引脚,以及矩阵键盘的键值和数码管的数字对应关系。例如,假设我们使用4x4的矩阵键盘和共阴数码管,可以定义如下: ``` #define KEY_PORT GPIOA #define KEY_PIN GPIO_Pin_0 #define DIG_PORT GPIOB #define DIG_PIN_0 GPIO_Pin_0 #define DIG_PIN_1 GPIO_Pin_1 #define DIG_PIN_2 GPIO_Pin_2 #define DIG_PIN_3 GPIO_Pin_3 const uint8_t key_map[16] = { 0x01, 0x02, 0x03, 0x0A, 0x04, 0x05, 0x06, 0x0B, 0x07, 0x08, 0x09, 0x0C, 0x0E, 0x00, 0x0F, 0x0D }; const uint8_t dig_map[16] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x00, 0x3F, 0x5E }; ``` 接下来,可以编写初始化函数,配置GPIO口为输入和输出模式,并设置中断触发方式。例如,可以使用下面的代码初始化矩阵键盘数码管: ``` void init_keypad(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = KEY_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(KEY_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = DIG_PIN_0 | DIG_PIN_1 | DIG_PIN_2 | DIG_PIN_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DIG_PORT, &GPIO_InitStructure); } ``` 然后,可以编写一个轮询函数,检测矩阵键盘的按键状态,并根据按键值更新数码管的显示。例如,可以使用下面的代码实现: ``` void update_display(void) { static uint8_t cur_dig = 0; static uint8_t prev_key = 0; uint8_t key = 0; // 检测矩阵键盘的按键状态 GPIO_ResetBits(KEY_PORT, KEY_PIN); for (uint8_t i = 0; i < 4; i++) { GPIO_SetBits(DIG_PORT, 1 << i); if (GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN) == RESET) { key = key_map[i * 4 + cur_dig]; break; } GPIO_ResetBits(DIG_PORT, 1 << i); } GPIO_SetBits(KEY_PORT, KEY_PIN); // 更新数码管的显示 if (key != prev_key) { uint8_t dig_val = dig_map[key]; GPIO_ResetBits(DIG_PORT, DIG_PIN_0 | DIG_PIN_1 | DIG_PIN_2 | DIG_PIN_3); GPIO_SetBits(DIG_PORT, dig_val << 8); prev_key = key; } // 切换下一个数码管 cur_dig = (cur_dig + 1) & 0x03; GPIO_SetBits(DIG_PORT, 1 << cur_dig); } ``` 最后,在主函数中循环调用轮询函数即可实现矩阵键盘控制数码管显示。例如,可以使用下面的代码实现: ``` int main(void) { init_keypad(); while (1) { update_display(); delay_ms(10); } } ``` 其中,`delay_ms`是一个自定义的延时函数,可以根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值