STM32初学——OLED调试4-1 5-1/5-2

  • 串口调试advantage:借助强大的电脑来调试
  • 点灯调试法
  • 注释调试法
  • 对照法

OLED_ShowChar(1, 1, 'A');

显示一个字符

指定起始行,指定起始列,显示字符

OLED_ShowNum(2, 1, 12345, 5);

显示十进制数字

OLED_ShowSignedNum(2, 7, -66, 2);

显示有符号十进制数字

OLED_ShowHexNum(3, 1, 0xAA55, 4);

显示十六进制数字

OLED_ShowBinNum(4, 1, 0xAA55, 16);

显示二进制数字

最后一位是显示数字的长度

4-1 OLED显示编程中的一些思想:

OLED的供电孔同时也会接到STM32的PB6、PB7引脚,只要不初始化这两个引脚,

不初始化的话——默认为浮空输入模式——引脚不会输出电平,无影响

方法2:也可不接PB6、PB7的两根跳线,直接给PB6 0 ,给PB7 1,使用GPIO口直接给OLED供电,OLED功率小,但不是很规范

C语言不支持直接写二进制的数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"

uint8_t KeyNum;    //KeyNum在这里是全局变量

int main(void)
{
	OLED_Init();
	OLED_ShowString(1, 1, "WangMengYuan");  //字符用单引号括起''
	OLED_ShowString(2,1,"so bang!!!");
	OLED_ShowString(3,1,"CHEER FOR");
	OLED_ShowString(4,1,"SPORT MEETING");
//	OLED_ShowNum(3,1,12345,7);
//	OLED_ShowSignedNum(3,9,-77,2);
//	OLED_ShowHexNum(4,1,0XAA55,4);
//	OLED_ShowBinNum(2,1,0XAA55,16);
	
	//OLED_Clear();
	while(1)
	{	
		
	}
}

我给小王的应援哈哈哈!!! 

中断系统和外部中断

  • 中断系统——管理和执行中断的逻辑结构,
  • 外部中断EXIT——众多能产生中断的外设之一
  • 程序中的中断函数,其地址是由编译器来分配的,不固定的
  • 中断跳转——硬件限制——只能跳到固定的执行程序
  • 为了使硬件跳转到一个不固定的中断函数中——solution——需要在内存里定义一个地址的列表——列表地址固定,中断发生后,跳到这个固定位置——编译器+一条跳转到中断函数的代码——》中断跳转可跳到任意位置

中断地址的列表——中断向量表——中断跳转的跳板

STM32初学——OLED调试4-1 5-1/5-2_第1张图片

NVIC——嵌套中断向量控制器——统一分配中断优先级和管理中断(叫号系统)

内核外设,CPU(医生)小助手

STM32初学——OLED调试4-1 5-1/5-2_第2张图片

 插队看病——响应优先级

决定是不是可以中断嵌套的优先级——抢占优先级

第一个病人——EXTI外部中断

STM32初学——OLED调试4-1 5-1/5-2_第3张图片

为什么这四个要来外部中断蹭网呢? 

外部中断有个功能——从低功耗模式的停止模式下,唤醒STM32

中断响应与事件响应

  • 中断响应:申请中断,让CPU执行中断函数
  • 正常流程,引脚电平变化触发中断
  • 事件响应:对外部中断增加的一种额外功能,当外部中断检测到引脚电平变化时,正常流程选择触发中断,在STM32中,也可选择触发一个事件——外部中断信号不会通向CPU,而是通向其他外设,用来触发其他外设的操作,例如:触发ADC转换、触发DMA
  • 不会触发中断,而是触发别的外设操作,属于外设之间的联合工作

STM32初学——OLED调试4-1 5-1/5-2_第4张图片

AFIO——数据选择器

  • 在前面GPIO外设的16个引脚里选择其中一个连接到后面的EXTI通道中,可以解释《支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断  ——例如:PA1、PB1、PC1不可同时使用,只能选择一个作为中断引脚)》 
  • 即所有的GPIO口都能够触发中断,但相同的Pin不能同时触发中断的原因。

配合外部中断我们所要选择的硬件模块

  • 什么样的设备需要用到外部中断?
  • 使用外部中断的好处?

使用外部中断模块的特性:

1、对于STM32来讲,想要获取的信号时外部驱动很快的突发信号(突发信号——STM32不知道信号什么时候到来)

2、它是外部驱动的,STM32只能被动读取

3、此信号非常快,STM32稍微晚一点读取,就会错过很多波形

有脉冲过来,STM32立即进入中断函数处理,没有脉冲时,STM32就专心做其他事情

一些注意的点:

  • 红外遥控接收头的输出——接收到遥控数据后,会输出一段波形,转瞬即逝,不会等你——solution——用外部中断来读取
  • 按键——其动作也是外部驱动的突发事件,但不推荐使用外部中断读取按键——why——因为用外部中断不好处理按键抖动和松手检测的问题,且对于按键来说,其输出波形不是转瞬即逝,要求不高,可以在主程序中循环读取或者定时器中断读取——advantage——既可以后台读取按键值、不阻塞主程序,还可以很好处理按键抖动和松手检测

旋转编码器:STM32初学——OLED调试4-1 5-1/5-2_第5张图片

通过B相是滞后还是超前A相90°,来判断其正转还是反转

相位相差90度的波形——正交波形

带正交波形信号输出的编码器——可以用来测方向

单相输出和两相正交输出

5-1 对射式红外传感器sensor计次

外部中断的配置流程

  • 涉及外设——RCC/GPIO/AFIO/EXTI/NVIC
  •     //1.初始化打开时钟,使外设工作 
  •     //2.配置GPIO,选择我们的端口为输入模式
  •     //3.配置AFIO,选择我们用的这一路GPIO,连接到后面的EXTI
  •     //4.配置EXTI,选择边沿触发方式、触发响应方式
  •     //5.配置NVIC,给中断选择合适优先级,通过NVIC,中断信号进入CPU,CPU才能收到中断信号,才能跳转到中断函数中执行中断程序
  • EXTI、NVIC两个外设,其时钟是一直打开的,不需要我们再开启时钟了
  • EXTI作为独立外设按理说是应该需要开启时钟的
  • NVIC是内核外设——内核外设无需开启时钟,内核外设和CPU一起住在皇宫里
  • RCC管的都是内核外的外设

现在进入程序模块的编写 

GPIO的外设重要函数:

  • 364——进行引脚重映射,
  • 365——配置AFIO的数据选择器,来选择我们想要的中断引脚 

 主程序中查看、清除标志位:

一般的读写标志位,没有额外的处理,能不能触发中断的标志位都能读取 

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
void EXTI_ClearFlag(uint32_t EXTI_Line);

 在中断函数里查看和清除标志位:

只能读写与中断有关的标志位,并且对中断是否允许做出判断

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

 本质上,以上四个函数都是对状态寄存器的读写

STM32初学——OLED调试4-1 5-1/5-2_第6张图片

STM32初学——OLED调试4-1 5-1/5-2_第7张图片

 优先级在多个中断源同时申请,产生拥挤时才有作用

	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

 抢占优先级和响应优先级都设置为1,这里只有一个中断,优先级就随便了

在STM32中,中断函数的名字都是固定的,每个中断通道对应于一个中断函数,中断函数的名字可以参考启动文件

  • 以_IRQHandler结尾的名字——中断函数的名称,中断函数名可千万不要写错,写错了就进不了中断了。
  • 中断函数里,先进行中断标志位的判断——确保是我们想要的中断源触发的函数,在此程序中,EXTI10—EXTI15都能进来,——所以判断是否是我们想要的EXTI14进来的
  • 中断函数不需要声明——因为中断函数不需要调用,它是自动执行的

STM32初学——OLED调试4-1 5-1/5-2_第8张图片

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"

uint8_t KeyNum;    //KeyNum在这里是全局变量

int main(void)
{
	OLED_Init();
	CountSensor_Init();

	OLED_ShowString(1,1,"COUNT:");

	
	//OLED_Clear();
	while(1)
	{	
		OLED_ShowNum(1, 7, CountSensor_Get(), 5);
		
	}
}

但实验结果是——我遮一下有时会增加近10次,弹幕有人说——换一个好一点的遮光片

5-2旋转编码器计次

STM32初学——OLED调试4-1 5-1/5-2_第9张图片

 前期准备:A、B相都触发中断

 老师一点关于中断编程的建议:

  • 1.在中断函数中,最好不要执行耗时过长的代码,中断函数要简短快速,别一进中断就delay_ms(),
  • 中断是处理突发事件
  • 2.不要在中断函数和主函数调用相同的函数——尤其是硬件显示函数(例如:OLED显示函数)或者操作同一个硬件
  • 问题出现在中断结束之后——需要继续原来的显示,好了!出问题了!——》硬件的显示位置被挪到了其他地方,再回来时,继续显示的内容就会跟着跑到其他地方去。虽然在中断进入和退出时,会有保护现场和恢复现场——只能保证CPU程序能正常返回不出问题,对于外部硬件,并没有在进入中断时,进行现场保护,——》所以,中断返回后,出现问题
  • 避免此问题——最好不要在主程序和中断程序里,操作可能产生冲突的硬件——实现功能时,在中断里操作变量或标志位,当中断返回时,再对此变量进行显示和操作——既保证中断函数的简短、快速,又能保证不产生冲突的硬件操作
  • 以及在其他地方,也都可以多使用变量和标志位——减少代码的耦合性,让各部分间代码相互独立,仅使用变量、标志位或者函数作为接口,——advantage——让程序更加清晰,代码更加强健

你可能感兴趣的:(stm32,单片机,arm)