【专题STM32F103】四位阳数码管显示 stm32 HAL库

 芯片595的引脚与原理

这里 LOAD引脚,连接HC595的引脚RCK上。

 

 

 头文件

#ifndef __LED595_H
#define __LED595_H
#include "main.h"
#define SDI_595   PCout(8) /*1bit数据*/
#define SCLK_595  PCout(9) /*将串行数据锁存到并口驱动LED,一个高低电平变化*/
#define LOAD_595  PCout(10) /*将串行数据锁存到并口驱动LED,一个高低电平变化*/

void led595_init(void);// 相关GPIO初始化
void SendByte(uint8_t byte);//发送一位数码管数据
void freshData(void);//显示新数据
void seg_test(void);//测试

////位带操作,实现51类似的GPIO控制功能
////具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
////IO口操作宏定义
//#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
//#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
//#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
////IO口地址映射
//#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
//#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
//#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
//#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
//#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
//#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
//#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

//#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
//#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
//#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
//#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
//#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
//#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
//#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
// 
////IO口操作,只对单一的IO口!
////确保n的值小于16!
//#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
//#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

//#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
//#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

//#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
//#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

//#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
//#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

//#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
//#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

//#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
//#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

//#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
//#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#endif /* __LED595_H */

 源文件:

将8位数据,从最高位开始送出。按照1或0设置SDI的高低电平,然后SCLK一个高然后低电平变化作为时钟,将数据写入HC595内的移位寄存器。

依此将4位显示8位数据送进4片HC595。

然后 RCK做一次高低电平变化,将 HC595内的数据送到HC595的并口引脚上。

#include "led595.h"
//const uint8_t seg7led[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴数码管显示码
// 依次是 0,1,2,---,9
const uint8_t seg7led[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  //共阳数码管显示码

void led595_init(void)// 相关GPIO初始化
{
    
    
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  __HAL_RCC_GPIOC_CLK_ENABLE (  );
     
  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull  = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

void SendByte(uint8_t byte)//发送一位数码管数据
{
   uint8_t i;
     LOAD_595=0;
     SCLK_595=0;
    for(i=0;i<8;i++)
    {
        if((byte&0x80)==0x80)
            SDI_595=1;
        else
            SDI_595=0;    
        SCLK_595=1;
        SCLK_595=1;
        SCLK_595=0;
        byte=byte<<1;
  }    

}
void freshData(void)//显示新数据
{
  LOAD_595=1;
    LOAD_595=1;
    LOAD_595=0;
}
void seg_test(void)//测试
{
  uint8_t j;   
    uint8_t i;
    uint8_t byte;    
    for(j=0;j<10;j++)
    {
    byte =seg7led[j];
        byte =byte&0x7F;//点亮小数点
        SendByte(byte);//发送一位数码管数据
        freshData();//显示新数据
    HAL_Delay(2000);
    }

}

 

posted @ 2023-05-19 22:07  辛河  阅读(486)  评论(0编辑  收藏  举报