【专题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); } }