74HC595/四位按键 驱动四位数码管

一、主要元器件和原理

GD32F303RCT6 74HC595 共阳数码管 按键(图片数码管名字有误)
风中凌乱的笔记:
A1A2A3A4下拉工作模式。给A1A2A3A4一个低电平。当abcdefg来一个高电平时,数码管亮。
GPIO_CTL0(GPIOB) &= 0x0FFFF000;表示配置PA3,PA4,PA5,PA6脚
GPIO_CTL0(GPIOB) |= 0x03333000;表示PA3,PA4,PA5,PA6的工作模式為推挽輸出0011=0x3(00為推挽輸出,11為50MHz)
局部static,只初始化一次,不再作第二次初始化。
void led_Init(void)
{
INT8U ucFlag = 0;
static INT8U ucNumber = 0;

     ucFlag++;      第一次初始化后,ucFlag = 1,第二次初始化也为1 

     ucNumber++;  第一次初始化后,ucNumbe = 1,第二次初始化为2,…

………………………
}
Define定义一般放在.h文件,.c可以直接调用.h文件。如果放在.c文件,其他的.c文件不能用。

const INT8U LED_data[]={0x3f,0x06,0x5b,0x4f,0x66, 0x71};数组值固定不变
static
extern const INT8U LED_data[]; 用于外部声明

线路连接:
DG_D1---->PB6
DG_D2---->PB5
DG_D3---->PB4
DG_D4---->PB3
按键原理等后续有空再补充

二、原理图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、程序

DigiDrv.c

#include "DigiDrv.h"
//数码管段选                       0     1     2    3      4     5     6     7     8     9     A     B     C      D    E     F     G      R     S     W    灭
const INT8U GucDigiDispData[] = {0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90, 0X88, 0X83, 0XC6, 0XA1, 0X86, 0X8E, 0XC2, 0XAF, 0X92, 0X81, 0XFF};
//const INT8U GucDigiDispData[] = {0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F, 0X77, 0X7C, 0X39, 0X5E, 0X79, 0X71, 0XBF};

void DigiDrvInit(void)
{
    rcu_periph_clock_enable(RCU_AF);
    rcu_periph_clock_enable(RCU_GPIOB);
    
    AFIO_PCF0 &= 0xF8FFFFFF;     //置零
    AFIO_PCF0 |= (1<<25);       // 置1     禁用JTAG,使能SWD模式 010(关闭JTAG功能,设为普通IO口使用)
    
    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, DIGI_PORT);   // 位控制脚
    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_15);
    
    
    gpio_bit_reset(GPIOB, DIGI_PORT);   //      关闭数码管显示 ,复位引脚值   
}
//74HC595驱动程序
void DigiDrvWriteData(INT8U ucData)
{
    INT8U i;                            
                          //时钟线低电平
    for (i = 0; i < 8; i++)            
    { 
        if (ucData & 0x80)              //判断数据高低            
            DIGI_DS_CLR;
        else 
            DIGI_DS_SET;
        
        ucData = (ucData << 1);         //数据左移1位
        //上升沿输出数据
        DIGI_SH_CLR;                    
        DIGI_SH_SET;
    }
    DIGI_ST_CLR;  
    delay_ms(1);
    DIGI_ST_SET;                        //时钟线高电平
    
}

void DigiRoutine(void)
{
    
    static INT8U ucNumber = 0;         //静态函数,程序重新进来不被刷新
   
    switch (ucNumber)
    {
    case 0:
        ucNumber = 1;
        DigiDrvDisp(GucDigiCnt[0]);     
        DigiSelect1();                 //显示第一位数码管
        break;
        
    case 1:
        ucNumber = 2;
        DigiDrvDisp(GucDigiCnt[1]);
        DigiSelect2();
        break;
        
    case 2:
        ucNumber = 3;
        DigiDrvDisp(GucDigiCnt[2]);                                                                                                                                      
        DigiSelect3();
        break;
        
    case 3:
        ucNumber = 0;
        DigiDrvDisp(GucDigiCnt[3]);
        DigiSelect4();
        break;
        
    default:
        ucNumber = 0;
        break;
    }
}

void DigiSelect1(void)
{
    DIGI_PORT1_SET;          //驱动第一位数码管,其他数码管拉低(关掉)
    DIGI_PORT2_CLR;
    DIGI_PORT3_CLR;
    DIGI_PORT4_CLR;
  
}

void DigiSelect2(void)
{
    DIGI_PORT1_CLR;
    DIGI_PORT2_SET;
    DIGI_PORT3_CLR;
    DIGI_PORT4_CLR;
}

void DigiSelect3(void)
{
    DIGI_PORT1_CLR;
    DIGI_PORT2_CLR;
    DIGI_PORT3_SET;
    DIGI_PORT4_CLR; 
}

void DigiSelect4(void)
{
    DIGI_PORT1_CLR;
    DIGI_PORT2_CLR;
    DIGI_PORT3_CLR;
    DIGI_PORT4_SET;
}
//数码管段码显示
void DigiDrvDisp(INT8U ucNum)
{
  
    DigiDrvWriteData(GucDigiDispData[ucNum]);
  
}

DigiDrv.h

#ifndef __DIGIDRV_H
#define __DIGIDRV_H

#include "sys.h"

/*********************************Define***************************************/
#define DIGI_GPIO_PORT  GPIOB
#define DIGI_PORT       (GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6)

#define DIGI_ST_CLR     gpio_bit_reset(DIGI_GPIO_PORT, GPIO_PIN_13)
#define DIGI_SH_CLR     gpio_bit_reset(DIGI_GPIO_PORT, GPIO_PIN_12)
#define DIGI_DS_CLR     gpio_bit_reset(DIGI_GPIO_PORT, GPIO_PIN_15)     

#define DIGI_ST_SET     gpio_bit_set(DIGI_GPIO_PORT, GPIO_PIN_13)
#define DIGI_SH_SET     gpio_bit_set(DIGI_GPIO_PORT, GPIO_PIN_12)
#define DIGI_DS_SET     gpio_bit_set(DIGI_GPIO_PORT, GPIO_PIN_15)  

#define DIGI_PORT1_CLR  gpio_bit_reset(DIGI_GPIO_PORT, GPIO_PIN_6)
#define DIGI_PORT2_CLR  gpio_bit_reset(DIGI_GPIO_PORT, GPIO_PIN_5)
#define DIGI_PORT3_CLR  gpio_bit_reset(DIGI_GPIO_PORT, GPIO_PIN_4)
#define DIGI_PORT4_CLR  gpio_bit_reset(DIGI_GPIO_PORT, GPIO_PIN_3)

#define DIGI_PORT1_SET  gpio_bit_set(DIGI_GPIO_PORT, GPIO_PIN_6)
#define DIGI_PORT2_SET  gpio_bit_set(DIGI_GPIO_PORT, GPIO_PIN_5)
#define DIGI_PORT3_SET  gpio_bit_set(DIGI_GPIO_PORT, GPIO_PIN_4)
#define DIGI_PORT4_SET  gpio_bit_set(DIGI_GPIO_PORT, GPIO_PIN_3)


extern INT8U  GucDigiCnt[]; //


/******************************void********************************************/
void DigiDrvInit(void);

void DigiDrvDisp(INT8U ucNum);

void DigiSelect1(void);

void DigiSelect2(void);

void DigiSelect3(void);

void DigiSelect4(void);

void DigiRoutine(void);

#endif

DigiDrvKey.c

#include "DigiDrvKey.h"
#include "DigiDrv.h"

extern INT8U GucDigiNumber;


//1、初始化按键(时钟使能,引脚)
void DigiDrvKeyInit(void)
{
    rcu_periph_clock_enable(RCU_GPIOC);
    
    gpio_init(GPIOC, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

}
//2、按键按下,位选数码亮
void keyScan(void)
{       
    if (!gpio_input_bit_get(GPIOC, GPIO_PIN_0)) 
    {
        GucDigiCnt[0]++;if (GucDigiCnt[0] > 21) GucDigiCnt[0] = 0;      //选中第一个数码管,按一下加1。当按第十下时,值为0
    }
    else if (!gpio_input_bit_get(GPIOC, GPIO_PIN_1))  
    {
        GucDigiCnt[1]++;if (GucDigiCnt[1] > 21) GucDigiCnt[1] = 0;      
    }
    else if (!gpio_input_bit_get(GPIOC, GPIO_PIN_2))    
    {
        GucDigiCnt[2]++;if (GucDigiCnt[2] > 21) GucDigiCnt[2] = 0;
    }
    else if (!gpio_input_bit_get(GPIOC, GPIO_PIN_3))  
    {
        GucDigiCnt[3]++;if (GucDigiCnt[3] > 21) GucDigiCnt[3] = 0;
    }
  
}

DigiDrvKey.h

#ifndef __DIGIDRVKEY_H
#define __DIGIDRVKEY_H

#include "main.h"
#include "DigiDrv.h"
#include "sys.h"

//#define P0  DIGI_PORT;

void KeyInit(void);

void KeyData(void);
void keyScan(void);

#endif

sys.c

#include "sys.h"

INT8U GucSysTick1ms = 0;

void SysTickInit(void)
{
    SysTick_Config(SystemCoreClock/1000U);
}

//void SysTick_Handler(void)
//{
//    GucSysTick1ms++;
//}
void delay_ms(INT8U nms)
{			 
    volatile INT8U i;
	
    do
    {
        for(i=0;i<20;i++); 
    }while(nms--);
}


//void delay_ms(INT16U nms)
//{			 
//    volatile INT16U i;
//	
//    do
//    {
//        for(i=0;i<17000;i++); 
//    }while(nms--);
//}


void delay_us(INT32U nus)
{
    volatile INT32U i;
	
    do
    {
        for(i=0;i<20;i++);
    }while(nus--);
}

sys.h

#ifndef __SYS_H
#define __SYS_H

#include "gd32f30x.h"

#define SIZE_OF_ARY(x)      (sizeof(x)/sizeof(x[0]))
    
#define APP_ADDR_OFFSET     (0x2800)
    
typedef char             INT8S;
typedef unsigned char    INT8U;
typedef short            INT16S;
typedef unsigned short   INT16U;
typedef long             INT32S;
typedef unsigned long    INT32U;
typedef char	         BOOL;



#endif

main.c

#include "main.h"
#include "gd32f30x.h"
#include "DigiDrv.h"
#include "DigiDrvKey.h"
#include "LED.h"
#include "MBI6023.h"

void SysTickInit(void);
void DigiDrvKeyInit(void);
void delay_ms(INT16U nms);
void DigiDrvKeyData(void);
INT8U GucDigiNumber = 0;
INT32U  GulSysTickCnt = 0;
INT8U  GucDigiCnt[4] = {0}; //数码管位选

int main(void)
{ 
   // INT8U j;
   // INT32U ulKeyScanCnt = 0; //定义数据类型放在函数名前面,即此位置
    SysTickInit();
    DigiDrvInit();
    DigiDrvKeyInit();
    
    while (1)
    {
//        DigiDrvDisp(GucDigiNumber);
     //   DigiDrvKeyData();
        
        Led();
        
        MBI6023_SendData();
    }
}

//
//void SysTickInit(void)
//{
//    SysTick_Config(SystemCoreClock/1000U);
//}
//按键延时中断处理函数
void SysTick_Handler(void)                                                //    Systick中断服务函数
{
    static INT32U ulKeyScanCnt = 0;
    GulSysTickCnt++;
    
    if (GulSysTickCnt > (ulKeyScanCnt+180))
    {
        ulKeyScanCnt = GulSysTickCnt;
        keyScan(); //按键扫描
    }
    DigiRoutine(); //数码管轮询(与按键的scan一个意思,不过我们一般不说DigiScan)
}

相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页