一、STM32的调试方法
程序调试的基本思想是缩小范围、控制变量、对比测试等。常见的调试方法有串口调试法,显示屏调试法,Keil调试模式调试法、点灯调试法、注释调试法、对比调试法。
1.1 串口调试法
通过串口通信,将调试信息发送到电脑端,电脑使用串口助手显示调试信息。
这种方法调试的优势是可以借助强大的电脑来调试,不仅可以显示单独的参数,还可以显示曲线,图形,图像等。甚至方便自行设计软件,来实现强大的用户交互界面。弊端是调试时依赖电脑,且对于不断变化的数据需要刷屏显示。
1.2 显示屏调试法(本课程采用)
直接将显示屏连接到单片机,将调试信息打印在显示屏上。
这种调试方法的优势是对于不断变化的数据,可以覆盖刷新显示,也可以实现一定的人机交互界面,将显示屏当作产品的一部分。弊端是功能不像电脑那样强大,且显示的内容十分有限。
1.3 Keil调试模式调试法
借助Keil软件的调试模式,可使用单步运行、设置断点、查看寄存器及变量等功能。
二、OLED
2.1 OLED简介
OLED,全称Organic Light Emitting Diode,即有机发光二极管。它是一种新能优异的新型显示屏,具有功耗低、响应速度快,宽视角、轻薄柔韧等优点。
供电:3 V − 5.5 V 3V-5.5V3V−5.5V ,通信协议:I2C(4针脚)/SPI(7针脚),分辨率:128*64。
其硬件电路图如下图所示(本课程采用4阵脚版本):
在4针脚版本中的SCL和SDA引脚是I2C的通信引脚,需要接在单片机的I2C通信引脚上。在本课程的驱动函数中使用GPIO口模拟的I2C通信,故这两个引脚可以接在任意的GPIO口上。
OLED.c
#include "stm32f10x.h" #include "OLED_Font.h" /*引脚配置*/ #define OLED_W_SCL(x) GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x)) #define OLED_W_SDA(x) GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x)) /*引脚初始化*/ void OLED_I2C_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 把PB8和PB9配置为开漏输出的模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_Init(GPIOB, &GPIO_InitStructure); OLED_W_SCL(1); OLED_W_SDA(1); } /** * @brief I2C开始 * @param 无 * @retval 无 */ void OLED_I2C_Start(void) { OLED_W_SDA(1); OLED_W_SCL(1); OLED_W_SDA(0); OLED_W_SCL(0); } /** * @brief I2C停止 * @param 无 * @retval 无 */ void OLED_I2C_Stop(void) { OLED_W_SDA(0); OLED_W_SCL(1); OLED_W_SDA(1); } /** * @brief I2C发送一个字节 * @param Byte 要发送的一个字节 * @retval 无 */ void OLED_I2C_SendByte(uint8_t Byte) { uint8_t i; for (i = 0; i < 8; i++) { OLED_W_SDA(Byte & (0x80 >> i)); OLED_W_SCL(1); OLED_W_SCL(0); } OLED_W_SCL(1); //额外的一个时钟,不处理应答信号 OLED_W_SCL(0); } /** * @brief OLED写命令 * @param Command 要写入的命令 * @retval 无 */ void OLED_WriteCommand(uint8_t Command) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x00); //写命令 OLED_I2C_SendByte(Command); OLED_I2C_Stop(); } /** * @brief OLED写数据 * @param Data 要写入的数据 * @retval 无 */ void OLED_WriteData(uint8_t Data) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x40); //写数据 OLED_I2C_SendByte(Data); OLED_I2C_Stop(); } /** * @brief OLED设置光标位置 * @param Y 以左上角为原点,向下方向的坐标,范围:0~7 * @param X 以左上角为原点,向右方向的坐标,范围:0~127 * @retval 无 */ void OLED_SetCursor(uint8_t Y, uint8_t X) { OLED_WriteCommand(0xB0 | Y); //设置Y位置 OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位 OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位 } /** * @brief OLED清屏 * @param 无 * @retval 无 */ void OLED_Clear(void) { uint8_t i, j; for (j = 0; j < 8; j++) { OLED_SetCursor(j, 0); for(i = 0; i &