MiniEBKBoard 入门指南

资料链接:https://pan.baidu.com/s/11JklSzoyv1CjAnqpbhyuRQ
提取码:ydlk
入手方式:https://item.taobao.com/item.htm?spm=a213gs.success.result.1.37ea7a86YvlVTU&id=669595178572
在线文档:https://www.cnblogs.com/Li-Share/p/15728772.html
视频教程:https://www.bilibili.com/video/BV1Pu411S7bh/

第一部分、硬件概述

1.1 MiniEBKBoard实物概图

  • 图1.1MiniEBKBoard实物概图
    image
  • 如图1.1所示MiniEBKBoard配置了3个6*6轻触按键,两个LED;引出了DC005和micro-usb;

1.2 MiniEBKBoard原理图

  • 图1.2MiniEBKBoard实物概图
    image
  • MiniEBKBoard原理图如图1.2所示,如看不清可打开Doc目录下的PDF文档查阅

第二部分、软件工具

2.1 软件概述

在 /Software 目录下是常用的工具软件:

  1. MDK:常用编译器;
  2. STM32CubeMX:代码生成工具;

第三部分、实战训练

3.1 实例Eg1_LED

目标是实现跑马灯;

3.1.1硬件设计

  • 图1.3 LED原理图
    image
  • 如图1.3是LED原理图,其中LED1与LED2分别连接到MCU的PB0和PB1;

3.1.2 软件设计

  • 首先是初始化代码,我们通过STM32cubeMX软件去生成代码,具体配置请打开Eg1_LED.ioc查阅,这里不再赘述; 我们的工程使用的是Keil-MDK编译器,生成的工程目录如图1.5
  • 图1.5 工程目录
    image

其中

  • Application/MDK-ARM 存放的是启动代码;
  • Application/User/Core: main函数,中断Handler,MSP相关代码;
  • Drivers/STM32F1xx_HAL_Driver: HAL库驱动代码
  • Drivers/CMSIS: CMSIS相关代码
  • My_Device: 这是我们自定义的代码;

工程目录这里只做一次介绍,后面的样例目录大同小异。
我们打开LED.h

#define   LED1_OFF()   GPIOB->BSRR = GPIO_PIN_0
#define   LED1_ON()    GPIOB->BRR = GPIO_PIN_0

#define   LED2_OFF()   GPIOB->BSRR = GPIO_PIN_1
#define   LED2_ON()    GPIOB->BRR = GPIO_PIN_1

我们看到的是操作GPIO的BSRR和BRR寄存器;我们打开参考手册GPIO章节,可以看到
image
image
BSSR寄存器是置位寄存器, 写0无效,GPIOB->BSRR = GPIO_PIN_0就是把BS0置1,也就是PB0输出高电平;同理BRR是清除寄存器,GPIOB->BRR = GPIO_PIN_0就是PB0输出低电平;结合原理图看,高电平LED灯熄灭,低电平LED打开;
最后,跳转到Blink函数;

void Blink(void)
{
	LED1_ON();
	LED2_OFF();
	HAL_Delay(300);
	LED1_OFF();
	LED2_ON();
	HAL_Delay(300);	
}

最后我们在main函数的while循环中调用即可实现跑马灯;
至此,软件设计完成。(对于没有基础的同学,还是建议多看代码)

3.1.3 下载验证

我们把烧录器的SWDIO接PA13,SWCLK接PA14,GND接GND,3.3V接3.3V,固件程序下载进去可以,可以看到led1和led2轮流亮灭;

3.2 实例Eg2_KEY

目标是实现按键控制LED;

3.2.1硬件设计

  • 图1.4 KEY原理图
    image
  • 如图1.4是KEY原理图,其中SW2与SW3分别连接到MCU的PA0和PA1;

3.2.2 软件设计

首先是初始化代码,我们通过STM32cubeMX软件去生成代码,具体配置请打开Eg2_KEY.ioc查阅;
我们打开KEY.c

void Key_Scan(void)
{
	static uint8_t bounce=0,bounce1=0;
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
	{
		bounce=1;
	}else{
		if(bounce)
		{
			bounce=0;
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
		}
	}
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==0)
	{
		bounce1=1;
	}else{
		if(bounce1)
		{
			bounce1=0;
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
		}
	}
	HAL_Delay(10);
}

bounce和bounce1记录按键按下了标志,当按键弹起时候清零并响应,做出切换LED翻转的动作;
HAL_GPIO_ReadPin函数是读取GPIO的状态, HAL_GPIO_TogglePin是翻转GPIO的电平;
最后在main函数while循环中调用即可;

3.2.3 下载验证

我们固件程序下载进去可以,按下SW2翻转LED2;按下SW3翻转LED1;

3.3 实例Eg3_UART

目标是实现UART串口回传功能,即通过串口调试工具发送数据到mcu,mcu原封不动回传;

3.3.1硬件设计

  • 图1.5 UART原理图
    image
  • 如图1.5是UART原理图,MCU的PA9和PA10分别是MCU串口的TX和RX;

3.3.2 软件设计

首先是初始化代码,我们通过STM32cubeMX软件去生成代码,具体配置请打开Eg3_UART.ioc查阅;
我们打开Application/User/Core目录下的usart.c,加入以下代码,支持 printf 函数,而不需要选择 use MicroLIB

#if 1
#pragma import(__use_no_semihosting)                             
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;          
void _sys_exit(int x) 
{ 
	x = x; 
} 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0); 
    USART1->DR = (uint8_t) ch;      
	return ch;
}
#endif

并在HAL_UART_RxCpltCallback和MX_USART1_UART_Init中加入HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuffer, RXBUFFERSIZE)以使能接收中断;
同时修改按键扫描函数如下,HAL_GPIO_ReadPin用以监控LED状态并打印;

void Key_Scan(void)
{
	static uint8_t bounce=0,bounce1=0;
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
	{
		bounce=1;
	}else{
		if(bounce)
		{
			bounce=0;
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
			if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1))
			{
				printf("LED2 OFF!\r\n");
			}else{
				printf("LED2 ON!\r\n");
			}		
		}
	}
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==0)
	{
		bounce1=1;
	}else{
		if(bounce1)
		{
			bounce1=0;
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
			if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0))
			{
				printf("LED1 OFF!\r\n");
			}else{
				printf("LED1 ON!\r\n");
			}	
		}
	}
	HAL_Delay(10);
}

3.3.3 下载验证

我们固件程序下载进去可以,按下SW2翻转LED2;按下SW3翻转LED1,并通过串口打印led状态,同时我们通过串口调试工具验证串口回传功能;

3.4 实例Eg4_TIM_Updata

本节的目标是测试TIM1的定时更新中断功能,我们设置10ms定时器去轮询按键扫描,并通过led指示,同时因为是上节基础上修改而来,因此串口回传功能也不变;

3.4.1硬件设计

同上一章节

3.4.2 软件设计

首先是TIM1的初始化代码,我们通过STM32cubeMX软件去配置生成代码,具体配置请打开Eg4_TIM_Updata查阅;
我们打开Application/User/Core目录下的tim.c,我们在MX_TIM1_Init最后加入HAL_TIM_Base_Start_IT(&htim1),目的是启动定时器中断;同时加入以下代码,定时器周期回调函数,在回调函数中调用了上节的Key_Scan;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == htim1.Instance)
	{
		Key_Scan();
	}
}

3.4.3 下载验证

我们固件程序下载进去可以,按下SW2翻转LED2;按下SW3翻转LED1,并通过串口打印led状态,同时我们通过串口调试工具验证串口回传功能;

3.5 实例Eg5_TM1650_Digtal

本节的目标是通过IO口模拟I2C对TM1650编程以驱动4位共阴极数码管;

3.5.1硬件设计

驱动TM1650使用PB0作为SDA,PB1作为SCL信号;参考原理图;

3.5.2 软件设计

首先我们通过STM32cubeMX软件去配置生成代码,具体配置请打开Eg5_TM1650_Digtal.ioc查阅;基本同上一章节,只是把PB0和PB1初始化为上拉;
我们打开My_Device目录下,我们加入了delay.c,myiic.c,TM1650.c三个驱动文件,delay.c是延迟相关函数,myiic是实现io口模拟iic,这两个文件是常有的,在我们其他视频中有讲解,这里不做过多介绍;我们主要讲解一下TM1650.c;
现在我们一起看看我们的代码;

3.5.3 下载验证

我们固件程序下载进去可以,每隔一秒,4位数码管模块计数一次;

3.6 实例Eg6_TM1650_Digtal_K3

本节的在上一节的基础上,增加了key读取,本次用到的是带按键的数码管模块。通过读取三个按键在数码管上显示对应的按键并通过串口打印出键值码;

3.6.1硬件设计

驱动TM1650使用PB0作为SDA,PB1作为SCL信号;参考原理图;

3.6.2 软件设计

本节我们直接在定时器回调函数上调用TM1650.c中的按键扫描函数,我们直接看代码,代码如下:


u8 TM1650_Read_KEY(void)
{	
	u8 temp;
	IIC_Start();
	IIC_Send_Byte(0x49);
	IIC_Wait_Ack();
	temp=IIC_Read_Byte(0);
	IIC_Wait_Ack();
	IIC_Stop();
	return temp;
}


u8 KEY_Scan(void)
{	
	u8 kv=TM1650_Read_KEY();
	switch(kv)
	{
		case KEY1:
		{
			DisplayNumber_4BitDig(1);
			printf("KEY1=%X\r\n",kv);
		}break;
		case KEY2:
		{
			DisplayNumber_4BitDig(2);
			printf("KEY2=%X\r\n",kv);
		}break;
		case KEY3:
		{
			DisplayNumber_4BitDig(3);
			printf("KEY3=%X\r\n",kv);
		}break;	
		default:break;
	}
	return kv;	
}

3.6.3 下载验证

我们固件程序下载进去可以,按下对应按键数码管显示对应的按键号,并通过串口打印键码,如k1按下,则数码管显示“0001”,串口打印“KEY1=44”;

3.7 实例Eg7_TM1650_Digtal_K28

本节用到的是带28个按键的数码管模块。通过读取每个按键在数码管上显示对应的按键号;

3.7.1硬件设计

驱动TM1650使用PB0作为SDA,PB1作为SCL信号;参考原理图;

3.7.2 软件设计

本节我们直接在定时器回调函数上调用TM1650.c中的按键扫描函数,我们直接看代码,代码如下:

//按键处理函数
//注意:该程序未处理按键松开时的情况
void TM1650ReadKey(void)
{
		unsigned char KeyDate=0x00;
	    KeyDate = TM1650_read();
		switch(KeyDate)
		{
			/**单个按键**/
			case 0x44:TM1650Disp2Num(1);break;    //KI1+DIG1
			case 0x45:TM1650Disp2Num(2);break;		//KI1+DIG2
			case 0x46:TM1650Disp2Num(3);break;		//KI1+DIG3
			case 0x47:TM1650Disp2Num(4);break;		//KI1+DIG4
			
			case 0x4C:TM1650Disp2Num(5);break;		//KI2+DIG1
			case 0x4d:TM1650Disp2Num(6);break;		//KI2+DIG2
			case 0x4e:TM1650Disp2Num(7);break;		//KI2+DIG3
			case 0x4f:TM1650Disp2Num(8);break;		//KI2+DIG4
			
			case 0x54:TM1650Disp2Num(9);break;		//KI3+DIG1
			case 0x55:TM1650Disp2Num(10);break;		//KI3+DIG2
			case 0x56:TM1650Disp2Num(11);break;		//KI3+DIG3
			case 0x57:TM1650Disp2Num(12);break;		//KI3+DIG4
			
			case 0x5C:TM1650Disp2Num(13);break;		//KI4+DIG1
			case 0x5d:TM1650Disp2Num(14);break;		//KI4+DIG2
			case 0x5e:TM1650Disp2Num(15);break;		//KI4+DIG3
			case 0x5f:TM1650Disp2Num(16);break;		//KI4+DIG4
			
			case 0x64:TM1650Disp2Num(17);break;		//KI5+DIG1
			case 0x65:TM1650Disp2Num(18);break;		//KI5+DIG2
			case 0x66:TM1650Disp2Num(19);break;		//KI5+DIG3
			case 0x67:TM1650Disp2Num(20);break;		//KI5+DIG4
			
			case 0x6C:TM1650Disp2Num(21);break;		//KI6+DIG1
			case 0x6d:TM1650Disp2Num(22);break;		//KI6+DIG2
			case 0x6e:TM1650Disp2Num(23);break;		//KI6+DIG3
			case 0x6f:TM1650Disp2Num(24);break;		//KI6+DIG4
			
			case 0x74:TM1650Disp2Num(25);break;		//KI7+DIG1
			case 0x75:TM1650Disp2Num(26);break;		//KI7+DIG2
			case 0x76:TM1650Disp2Num(27);break;		//KI7+DIG3
			case 0x77:TM1650Disp2Num(28);break;		//KI7+DIG4
			
			/**组合按键**/
			case 0x7C:TM1650Disp2Num(29);break;		//KI1_KI2+DIG1
			case 0x7d:TM1650Disp2Num(30);break;		//KI1_KI2+DIG2
			case 0x7e:TM1650Disp2Num(31);break;		//KI1_KI2+DIG3
			case 0x7f:TM1650Disp2Num(32);break;  	//KI1_KI2+DIG4
			
			default: break;
		}
}

3.7.3 下载验证

我们固件程序下载进去可以,按下对应按键数码管显示对应的按键号,如k1按下,则数码管显示“01”;并测试4个组合按键,如按下KI1_KI2+DIG1,则显示“29”;

3.8 实例Eg8_TM1639_Digtal

本节用到的是另外一款数码管模块,TM1639数码管模块,TM1639可以驱动8位共阴极数码管;下面让我们一起点亮这款数码管模块;

3.8.1硬件设计

驱动TM1639用到三根信号线,使用PB0作为SDA,PB1作为SCL信号,PB2作为STB信号;

3.8.2 软件设计

本节我们依旧在定时器回调函数上调用TM1639.c中的显示扫描函数,我们直接看代码,代码如下:

void send_8bit(unsigned char dat)	
{
  unsigned char i;
  for(i=0;i<8;i++)
  {	 
    CLK=0;
    if(dat&0x01) 
	  DIO=1;
	 else 
	  DIO=0;
		delay_us(2);
	 CLK=1;
	 dat>>=1;
  }
  CLK=0;
  DIO=0;
}

void send_command(unsigned char word)
{
 STB=1;
 delay_us(1);
 STB=0;
 send_8bit(word);
}



void display(uint8_t num)	
{
 unsigned char i;

 send_command(0x40);	
 send_command(0xc0);
 for(i=0;i<8;i++)
 {
    send_8bit(CODE[num]&0x0F);
	send_8bit((CODE[num]>>4)&0x0F);
 }
 send_command(0x8C);	
 STB=1;
}

3.8.3 下载验证

我们固件程序下载进去可以,初始化为0,每个一秒数据增加步长1,0~F一共16次,最后关闭数码管,重新循环;

posted @ 2021-12-24 19:52  LiJin_hh  阅读(514)  评论(0编辑  收藏  举报