这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » TI » 初级教程一驱动74HC595数码管任务

共1条 1/1 1 跳转至

初级教程一驱动74HC595数码管任务

工程师
2024-05-19 17:29:51     打赏

MSPM0L1306微控制器上使用74HC595移位寄存器来驱动数码管并实现读秒功能,

以下步骤:

硬件连接

  • MSPM0L1306GPIO引脚连接到74HC595的输入引脚:数据输入(DIO)、移位寄存器时钟输入(SHCP)和存储寄存器时钟输入(STCP)。

  • 74HC595的输出引脚连接到数码管的段选和位选引脚。

  • 如果数码管是共阳的,你还需要一个公共端连接到正电源(VCC),并通过适当的电阻限制电流。如果是共阴的,公共端连接到地(GND)。

  • 根据设计,需要使用额外的GPIO引脚来控制数码管的位选。

  • 上面说的好像不是那么回事,还是要来点实在的,上面的都略过。
         DIO--PA4
         RCLK--PA5--STCP
         CLK--PA6--SHCP
         VCC--3.3V

IC的各引脚定义:

1716110749239.jpg图表 描述已自动生成

引脚功能定义:

1716110771424.jpg

各引脚的电平描述:

1716110785897.jpg

. 编写驱动函数

  • 根据74HC595的时序编写函数将数据发送到74HC595,操作GPIO引脚,点亮数码管。

时序图:1716110815415.jpg


4. 实现数码管显示

  • 根据数码管的编码表,为每个数字(0-9)准备一个字节的数据。

  • 编写一个函数来根据给定的数字选择正确的段选数据,并使用位选来控制哪个数码管显示。

数码管原理:

1716110828510.jpg

显示对应的编码:

1716110849303.jpg

显示字段对照表:

1716110886578.jpg

 

 

数码管原理图:

1716110895517.jpg

 

软件实现方法:

74HC595芯片来驱动8位共阳极数码管时,其中一个74HC595用于数据移位(数据寄存器),而另一个用于片选(可能是通过另一个GPIO引脚直接控制,或者使用第二个74HC595的某个输出作为片选信号)。

以下是驱动步骤:

. 初始化GPIO

  • 初始化GPIO引脚,包括用于数据输入的PA4(连接到第一个74HC595DIO),两个时钟引脚(SHCPSTCP),以及可能用于片选的GPIO引脚。

. 数据传输到第一个74HC595(数据寄存器)

  • 将需要显示的8位数据通过PA4引脚串行发送到第一个74HC595的数据输入(DIO)引脚。

  • 使用L1306GPIO引脚(连接到SHCP)生成8个上升沿,每个上升沿将DI上的下一位数据移入移位寄存器。先送高位,后送低位。

. 数据从移位寄存器传输到存储寄存器

  • 使用L1306GPIO引脚(连接到STCP)生成一个上升沿,将移位寄存器中的数据传输到存储寄存器中。

. 控制OE引脚

  • 将第一个74HC595OE引脚设置为低电平,以允许存储在存储寄存器中的数据从Q0Q7并行输出。

 

. 数码管显示

  • 根据数码管的编码表,为每个数字(0-9)准备一个字节的数据,并将其发送到第一个74HC595

  • 通过片选控制选择需要显示的数码管,并确保OE引脚处于低电平状态以允许数据输出。

. 周期性更新显示

  • 使用L1306的定时器或软件延时来周期性地更新数码管的显示。

  • 递增秒数变量,并在需要时重置为0并递增分钟数。

. 主循环

  • 在主循环中,不断地检查是否需要更新数码管的显示,并调用相应的函数来更新。

 

 

学习GPIO的输出配置,驱动74HC595数码管显示

CCS配置数码管引脚:

1716110916508.jpg

 

 

#define DELAY (16000000)

#define HC595_DAT(x) ((x)?( DL_GPIO_setPins(GPIO_LEDS_PORT,GPIO_LEDS_HC595_DAT_PIN)):( DL_GPIO_clearPins(GPIO_LEDS_PORT,GPIO_LEDS_HC595_DAT_PIN) ))

#define HC595_CLK(x) ((x)?( DL_GPIO_setPins(GPIO_LEDS_PORT,GPIO_LEDS_HC595_CLK_PIN)):( DL_GPIO_clearPins(GPIO_LEDS_PORT,GPIO_LEDS_HC595_CLK_PIN) ))

#define HC595_RCK(x) ((x)?( DL_GPIO_setPins(GPIO_LEDS_PORT,GPIO_LEDS_HC595_RCK_PIN)):( DL_GPIO_clearPins(GPIO_LEDS_PORT,GPIO_LEDS_HC595_RCK_PIN) ))

uint16_t keyTmep;

uint16_t DutyTmep = 0;

uint16_t i,j;

uint8_t dir = 1;

 

uint8_t Disp_DX[ 16 ] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF };

uint8_t Disp_PX[ 8 ] = {1,2,3,4,5,6,7,8};

 

void Display_Out()

{

    delay_cycles(1000);

    HC595_RCK(0);

    delay_cycles(1000);

    HC595_RCK(1);

}

 

void HC595_WriteData(uint8_t data)

{

    uint8_t i;

    for(i = 0;i < 8;i++)

    {

       if (data & 0x80)

       {

           HC595_DAT(1);

       }

        else

        {

           HC595_DAT(0);

        }

        data <<= 1;

        delay_cycles(1000);

        HC595_CLK(0);

        delay_cycles(1000);

        HC595_CLK(1);

    }

}

 

void HC595_SEND_DATA(uint8_t dis_num, uint8_t dis_bit)

{

    HC595_WriteData(dis_num);

    HC595_WriteData(1<<dis_bit);

    Display_Out();

}

 

 

void Disp_Data(uint16_t dataH,uint16_t dataL)

{

    uint16_t tempH,tempL ;

    uint8_t num_q,num_b,num_s,num_g;

    tempL = dataL;

    num_q = tempL/1000;

    num_b = tempL/100%10;

    num_s = tempL/10%10;

    num_g = tempL%10;

 

    HC595_SEND_DATA(Disp_DX[num_q],3);

    HC595_SEND_DATA(Disp_DX[num_b],2);

    HC595_SEND_DATA(Disp_DX[num_s],1);

    HC595_SEND_DATA(Disp_DX[num_g],0);

 

    tempH = dataH;

    num_q = tempH/1000;

    num_b = tempH/100%10;

    num_s = tempH/10%10;

    num_g = tempH%10;

 

    HC595_SEND_DATA(Disp_DX[num_q],7);

    HC595_SEND_DATA(Disp_DX[num_b],6);

    HC595_SEND_DATA(Disp_DX[num_s],5);

    HC595_SEND_DATA(Disp_DX[num_g],4);

}

 

int main(void)

{

    /* Power on GPIO, initialize pins as digital outputs */

    SYSCFG_DL_init();

   delay_cycles(10000);

 

    while (1) {

        Disp_Data(1234,5678);

    }

}

学习GPIO的输入配置,实现按键控制数码管数据的变化

按键控制数码管:

1716110934626.jpg

 

int main(void)

{

    /* Power on GPIO, initialize pins as digital outputs */

    SYSCFG_DL_init();

   delay_cycles(10000);

   uint16_t keyTmep;

   uint16_t DutyTmep = 0;

   uint16_t i=0,j=0;

   uint8_t dir = 1;

 

   uint16_t KeyTmp;

   uint16_t TmpVal = 0;

   uint16_t KeyBounce = 0;

    while (1) {

        keyTmep = DL_GPIO_readPins(GPIO_LEDS_PORT,KEY_SW1_PIN);

        delay_cycles(10);

        keyTmep = DL_GPIO_readPins(GPIO_LEDS_PORT,KEY_SW1_PIN);

        if(keyTmep == 0)

        {

            KeyBounce ++;

            if(KeyBounce >= 100)

            {

                TmpVal++;

                KeyBounce = 0;

            }

            if(TmpVal > 9999)

            {

                TmpVal += 10;

            }

        }

        Disp_Dataa(TmpVal);

}}

 

学习定时器的配置,实现数字秒表

定时器控制数码管:

1716110954787.jpg


 

void TIMER_0_INST_IRQHandler(void)

{

    switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST))      {

        case DL_TIMER_IIDX_ZERO:

            TimerCnt++;

            if(TimerCnt >= 100)

            {

                TimerCnt = 0;

                TmpVal++;

                if(TmpVal > 500)TmpVal=0;

            }

            break;

        default:

            break;

    }

}

int main(void)

{

    uint16_t keyTmep;

    uint16_t DutyTmep = 0;

    uint16_t i=0,j=0;

    uint8_t dir = 1;

 

    uint16_t KeyTmp;

    uint16_t TmpVal = 0;

    uint16_t KeyBounce = 0;

 

    /* Power on GPIO, initialize pins as digital outputs */

    SYSCFG_DL_init();

    delay_cycles(10000);

    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);

 

    while (1) {

        Disp_Dataa(TmpVal);

    }

}

 

用定时器中断实现数码管数值的递减:

void TIMER_0_INST_IRQHandler(void)

{

    switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST))      {

        case DL_TIMER_IIDX_ZERO:

            // 递减 TimerCnt,但避免它变成负数

            if (TimerCnt > 0) {

                TimerCnt--;

            }

            // 如果 TimerCnt 递减到 0(或某个其他你设定的阈值),则递减 TmpVal

            if (TimerCnt == 0) {

                // 重置 TimerCnt 为某个初始值(比如 99),以便它再次开始递减

                TimerCnt = 99; // 或者你想要的任何其他初始值

 

                // 递减 TmpVal,但避免它变成负数

                if (TmpVal > 0) {

                    TmpVal--;

                }

                // 如果需要,当 TmpVal 递减到 0 时,可以将其重置为某个初始值

                if (TmpVal == 0) {

                    TmpVal = 500; // 或者你想要的任何其他初始值

                }

            }

            break;

        default:

            break;

    }

}

 



共1条 1/1 1 跳转至

回复

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