STM32F103RB 实作笔记(四)- LED 7 节显示(正点原子 STM32F103 nano开发板)程式解析(下)

这一篇,我们延续解析 LED 7 节显示 的寄存器设定方法。虽然 Header 档 被 include 了好多个,却没有全部都用到;所以,我们还是从 main() 的主程式寻找那些被用到的 变数与涵式做解析。
我们从下面三个出发:
1. LED_SMG_Init(); //
2. LED_Init(); //LED
3. TIM3_Init(19,7199);//
(其中 Stm32_Clock_Init(9); 、 delay_init(72); 和 uart_init(72,115200); 这三个不在这次说明。)

先分析线路图

STM32F103RB 实作笔记(四)- LED 7 节显示(正点原子 STM32F103 nano开发板)程式解析(下)
从 MCU 的配置了解到

  1. GPIOB 3/4/5 输出到 74HC595 的 SCKL/LCKL/DATA
  2. GPIOC 10/11/12 输出到 74HC138 的 A0/A1/A2
    STM32F103RB 实作笔记(四)- LED 7 节显示(正点原子 STM32F103 nano开发板)程式解析(下)
  3. 74HC138 是一颗 3 对 8 的选择器,3 个 bit 可以有 8 种状态负责控制 8 个 7 节显示管。
  4. 74HC595 是一颗 ”串入并出“ 8-bits 移位寄存器:

74HC595 解析

STM32F103RB 实作笔记(四)- LED 7 节显示(正点原子 STM32F103 nano开发板)程式解析(下)

这个是 脚位的定义图,不过,名称写法不一样,我用红色字体补上了!注意 脚位 11、12、14 四个就好。
下图就是这几个脚位对输出的影响:
STM32F103RB 实作笔记(四)- LED 7 节显示(正点原子 STM32F103 nano开发板)程式解析(下)
请观察最上面的三条时序线,这是写程式是要使用的,

74HC138 解析

74HC138 比较简单,前面三根线一上讯号,后面的对应输出会立即反应。
STM32F103RB 实作笔记(四)- LED 7 节显示(正点原子 STM32F103 nano开发板)程式解析(下)
STM32F103RB 实作笔记(四)- LED 7 节显示(正点原子 STM32F103 nano开发板)程式解析(下)

smg.h 内容

#ifndef _LED_SMG_H
#define _LED_SMG_H
#include "sys.h"
//	 
// 

74HC138 
#define LED_A0 PCout(10) //A0 == GPIOC bit 10
#define LED_A1 PCout(11) //A1 == GPIOC bit 11
#define LED_A2 PCout(12) //A2 == GPIOC bit 12

74HC595 
#define LED_DS		PBout(3) // 
#define LED_LCLK	PBout(4) // 
#define LED_SCK		PBout(5) // 

void LED_SMG_Init(void); //设定几个寄存器的结构
void LED_Refresh(void); // 把 74HC595 后端到 7 节显示管的资料更新
void LED_Write_Data(u8 duan,u8 wei);// 把要显示的字型用串联的方式送进 74HC595

#endif

LED_Init();

这些是和前几篇一样的,所以,不再这里解析了。

void LED_Init(void)
{
	 RCC->APB2ENR|=1<<4;       
	 GPIOC->CRL&=0X00000000; 
	 GPIOC->CRL|=0X33333333;  		
   GPIOC->ODR|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7);//PC.0~7 
}

LED_SMG_Init();

以下的程式是 smg.c 的内容,我把说明写在注解上:

#include "smg.h"
#include "delay.h"

//	 
/  
{
   RCC->APB2ENR|=1<<3;    // 选择 GPIOB 
   RCC->APB2ENR|=1<<4;    // 选择 GPIOC
   RCC->APB2ENR|=1<<0;    // 选择 AFIO
   
   JTAG_Set(SWD_ENABLE); //这个在nano 板上还没有用到
      
   GPIOB->CRL&=0XFF000FFF; 
   GPIOB->CRL|=0X00333000;// 设定 GPIOB PB3~5
    
   GPIOC->CRH&=0XFFF000FF; 
   GPIOC->CRH|=0X00033300;//设定 GPIOC PC10~12(高位)
    	
   GPIOB->BRR = 1<<3|1<<5; // 设定bit 3--DATA 、bit 5--SCKL 为 ”0“
   GPIOB->BSRR = 1<<4; //设定 bit 4 --LCKL 为 ”1”
   GPIOC->BSRR = 1<<10|1<<11|1<<12;  //设定 bit 10/11/12 为 ”1”
   
}
//74HC138 digital selected 
//num: the digital of 7_seg LED  0-7()
void LED_Wei(u8 num)
{
    LED_A0=num&0x01; //把需求的 3 个 bit 的 bit-0 送到 GPIOC bit 10 (见smg.h 的定义)
	LED_A1=(num&0x02)>>1; //把需求的 3 个 bit 的 bit-1 送到GPIOC bit 11 (见smg.h 的定义)
	LED_A2=(num&0x04)>>2; //把需求的 3 个 bit 的 bit-2 送到 GPIOC bit 12 (见smg.h 的定义)
}

//74HC595 Serial_in_parall_out 
//duan: 已经被转化成字型图案的资料,可以被成为 7-节显示管图案
//wei: 8 个 7-节显示管位置  0-7 
void LED_Write_Data(u8 duan,u8 wei)
{
	u8 i;
	for( i=0;i<8;i++)//
	{
		LED_DS=(duan>>i)&0x01;
		LED_SCK=0;
		delay_us(5);
		LED_SCK=1;
	}
	// LED_SCK 在 “0”、 “1”的过程 就是把 8 bit 一个一个推进74HC595,
    LED_Wei(wei);// 驱动 74HC138的位置显示
}
//74HC595 
void LED_Refresh(void)
{
	LED_LCLK=1;
	delay_us(5);
	LED_LCLK=0;
}
// LED_LCLK 在 “0”、 “1”的过程 就是把 已经 一个一个推进74HC595 的 8 bit 送到后端输出。

//整个写入动作一定是,下面两个涵式连续执行
LED_Write_Data(u8 duan,u8 wei);
LED_Refresh();
有兴趣的,可以看看下面这张线路图:
STM32F103RB 实作笔记(四)- LED 7 节显示(正点原子 STM32F103 nano开发板)程式解析(下)

TIM3_Init(19,7199);

下面这个,本片不解析留在中断时再一起说明

void TIM3_Init(u16 arr,u16 psc)
{
  RCC->APB1ENR|=1<<1; //TIM3 
 	TIM3->ARR=arr;  	//  
	TIM3->PSC=psc;  	// 
	TIM3->DIER|=1<<0;   // 				
	TIM3->CR1|=0x01;    // 
  MY_NVIC_Init(0,3,TIM3_IRQn,2);// 							 
}

下面这个涵式在 sys.c 的档案里,本片不解析留在中断时再一起说明

//在 sys.c 的档案里,
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)	 
{ 
	u32 temp;	
	MY_NVIC_PriorityGroupConfig(NVIC_Group);// 
	temp=NVIC_PreemptionPriority<<(4-NVIC_Group);	  
	temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
	temp&=0xf;//  
	NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel%32);// 
	NVIC->IP[NVIC_Channel]|=temp<<4;// 	    	  				   
} 

以上,七节显示管在(正点原子 STM32F103 nano开发板)上的程式解析到此

上一篇:AcWing 164 可达性统计


下一篇:中英文两端对齐DEMO