feat(base): 修改工程 README.md 文件,去除冗余的example文件
This commit is contained in:
parent
8be2866433
commit
ec2ca70a6f
21
README.md
21
README.md
@ -1,8 +1,9 @@
|
||||
## MSPM03507 FREERTOS C++ CLION TEMPLATE PROJECT 工程分享
|
||||
## MSPM03507 FREERTOS C++ CLION PWLINK TEMPLATE PROJECT 工程分享
|
||||
|
||||
> * 作者:博文
|
||||
> * 邮箱:boen.shi@qq.com
|
||||
> * 时间:2025/07/22
|
||||
> * 创建时间:2025/07/22
|
||||
> * 修改时间:2026/07/22
|
||||
|
||||
---
|
||||
|
||||
@ -14,11 +15,12 @@
|
||||
|
||||
> 由于博文已经给大家写好批处理文件了,所以配置起来很简单了
|
||||
|
||||
1. 按照[立创开发板](https://wiki.lckfb.com/zh-hans/tmx-mspm0g3507/keil-beginner/install.html)官方文档,配置好TI SDK以及SYSCONFIG
|
||||
2. 配置好`OpenOCD`驱动,配置好`arm-none-eabi-gcc/g++`工具链,并配置好环境变量。自行搜索,这里不再赘述
|
||||
3. 明确自己`sysconfig`和sdk的安装位置
|
||||
4. 打开`sysconfig_gui_cli.bat`,修改用户修改区的配置(注意结尾斜杠问题)
|
||||
5. 配置Clion,文件>设置>工具>外部工具,点击“+”添加,填写以下内容,保存关闭
|
||||
1. 按照[立创开发板](https://wiki.lckfb.com/zh-hans/tmx-mspm0g3507/keil-beginner/install.html)官方文档,配置好TI SDK以及SYSCONFIG。
|
||||
2. 强烈建议SDK用`mspm0_sdk_2_02_00_05`,Sysconfig使用`3772`版本,似乎下载最新版本的SDK,Sysconfig中GPIO配置页面会报错!
|
||||
3. 配置好`OpenOCD`驱动,配置好`CMake`,配置好`arm-none-eabi-gcc/g++`工具链,并配置进环境变量。自行搜索,这里不再赘述
|
||||
4. 明确自己`sysconfig`和sdk的安装位置
|
||||
5. 打开`sysconfig_gui_cli.bat`,修改用户修改区的配置(注意结尾斜杠问题)
|
||||
6. 配置Clion,文件>设置>工具>外部工具,点击“+”添加,填写以下内容,保存关闭
|
||||
|
||||
```bat
|
||||
名称:SysConfig
|
||||
@ -27,8 +29,9 @@
|
||||
工作目录:$ProjectFileDir$
|
||||
```
|
||||
|
||||
6. 右键`mspm0.syscfg`,选中`外部工具` `Sysconfig`,启动SysConfig进行编辑,退出后自动运行CLI进行文件生成
|
||||
7. 添加PWLINK配置文件,点击配置,编辑配置,添加OpenOCD,目标选中就行,面板文件选择`cmsis_dap.cfg`
|
||||
7. 右键`mspm0.syscfg`,选中`外部工具` `Sysconfig`,启动SysConfig进行编辑,退出后自动运行CLI进行文件生成
|
||||
8. 添加PWLINK配置文件,点击配置,编辑配置,添加OpenOCD,目标选中就行,面板文件选择`cmsis_dap.cfg`
|
||||
9. 如果你是其他JLink或其他Link,自己在OpenOCD中寻找对应的驱动文件即可!
|
||||
|
||||
### 注意事项
|
||||
* 请每次修改文件后重新加载CMAKE,否则会报错
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
#ifndef BEEP_H
|
||||
#define BEEP_H
|
||||
|
||||
#include "ti_msp_dl_config.h"
|
||||
|
||||
class Beep {
|
||||
public:
|
||||
static void init();
|
||||
static void inject();
|
||||
|
||||
static void start();
|
||||
static void stop();
|
||||
};
|
||||
|
||||
#endif //BEEP_H
|
||||
@ -1,36 +0,0 @@
|
||||
#ifndef __ENCODER_H
|
||||
#define __ENCODER_H
|
||||
|
||||
#include <cstdio>
|
||||
#include "ti_msp_dl_config.h"
|
||||
|
||||
class Encoder {
|
||||
public:
|
||||
struct Speed {
|
||||
int left;
|
||||
int right;
|
||||
};
|
||||
|
||||
static void init();
|
||||
static void inject();
|
||||
|
||||
static Speed getSpeeds();
|
||||
static Speed getRealSpeeds();
|
||||
|
||||
static int getLeftSpeed();
|
||||
static int getRealLeftSpeed();
|
||||
|
||||
static int getRightSpeed();
|
||||
static int getRealRightSpeed();
|
||||
|
||||
static int getLeftDirection();
|
||||
static int getRightDirection();
|
||||
|
||||
static Speed ticks;
|
||||
static Speed direction;
|
||||
static Speed speed;
|
||||
static Speed real_speed;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,44 +0,0 @@
|
||||
#ifndef HOST_H
|
||||
#define HOST_H
|
||||
|
||||
#include "ti_msp_dl_config.h"
|
||||
#include <stdint.h>
|
||||
#include <cstdio>
|
||||
#include "../../include/user/Print.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#define MAX_KEYS 10
|
||||
#define MAX_KEY_LENGTH 32
|
||||
|
||||
typedef struct {
|
||||
char key[MAX_KEY_LENGTH];
|
||||
double value;
|
||||
} KeyValuePair;
|
||||
|
||||
class Host {
|
||||
public:
|
||||
|
||||
static double posX;
|
||||
static double posY;
|
||||
static int x_count;
|
||||
static int y_count;
|
||||
|
||||
static void init(); // 模块初始化
|
||||
static void inject(char ch); // 数据注入(串口、I2C回调函数注入数据)
|
||||
static double get(const char* key, double defaultValue = 0.0);
|
||||
static double getWithoutClean(const char *key, double defaultValue = 0.0);
|
||||
|
||||
static void info(const char* format, ...);
|
||||
static void warn(const char* format, ...);
|
||||
static void error(const char* format, ...);
|
||||
static void plot(const char* key, double value);
|
||||
|
||||
private:
|
||||
static KeyValuePair data[MAX_KEYS];
|
||||
static int count;
|
||||
|
||||
static void log(const char* level, const char* format, ...);
|
||||
};
|
||||
|
||||
#endif //HOST_H
|
||||
@ -1,32 +0,0 @@
|
||||
#ifndef IMU_H
|
||||
#define IMU_H
|
||||
|
||||
#include "ti_msp_dl_config.h"
|
||||
|
||||
class Imu {
|
||||
public:
|
||||
struct Data {
|
||||
float roll;
|
||||
float pitch;
|
||||
float yaw;
|
||||
float ax;
|
||||
float ay;
|
||||
float az;
|
||||
};
|
||||
|
||||
static void init(); // 模块初始化
|
||||
static void inject(); // 数据注入(串口、I2C回调函数注入数据)
|
||||
|
||||
static Data getData();
|
||||
static float getRoll();
|
||||
static float getPitch();
|
||||
static float getYaw();
|
||||
static float getAx();
|
||||
static float getAy();
|
||||
static float getAz();
|
||||
|
||||
static uint8_t _buffer;
|
||||
static Data _data;
|
||||
};
|
||||
|
||||
#endif //IMU_H
|
||||
@ -1,38 +0,0 @@
|
||||
#ifndef KEY_H
|
||||
#define KEY_H
|
||||
|
||||
#include "ti_msp_dl_config.h"
|
||||
|
||||
#define KEY1 0
|
||||
#define KEY2 1
|
||||
#define KEY3 2
|
||||
#define KEY4 3
|
||||
|
||||
#define KEY_LEFT KEY1
|
||||
#define KEY_RIGHT KEY2
|
||||
#define KEY_ACCESS KEY3
|
||||
#define KEY_CANCEL KEY4
|
||||
|
||||
#define KEY1_PIN_ID 7
|
||||
#define KEY2_PIN_ID 10
|
||||
#define KEY3_PIN_ID 11
|
||||
#define KEY4_PIN_ID 14
|
||||
|
||||
class Key {
|
||||
public:
|
||||
struct KeyData {
|
||||
uint8_t id;
|
||||
GPIO_Regs *port;
|
||||
uint32_t pin;
|
||||
uint8_t state;
|
||||
};
|
||||
|
||||
static KeyData keys[];
|
||||
static void init();
|
||||
static uint8_t getState(uint8_t id);
|
||||
static void setState(uint8_t id, uint8_t state);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif //KEY_H
|
||||
@ -1,27 +0,0 @@
|
||||
#ifndef MOTOR_H
|
||||
#define MOTOR_H
|
||||
|
||||
#include "ti_msp_dl_config.h"
|
||||
|
||||
class Motor {
|
||||
public:
|
||||
static void init(); // 模块初始化
|
||||
static void inject(); // 数据注入(串口、I2C回调函数注入数据)
|
||||
static void setLeftSpeed(int left_speed);
|
||||
static void setRightSpeed(int right_speed);
|
||||
static void setSpeed(int left_speed, int right_speed);
|
||||
static void stopLeft();
|
||||
static void stopRight();
|
||||
static void stop();
|
||||
|
||||
private:
|
||||
static uint8_t _inited;
|
||||
static uint8_t _data[];
|
||||
static uint8_t motor_init; // 电机初始化标志
|
||||
static void setLeftDirection(uint8_t direction);
|
||||
static void setRightDirection(uint8_t direction);
|
||||
static void setDirection(uint8_t left_direction, uint8_t right_direction);
|
||||
static int Abs(int num); // 取绝对值函数
|
||||
};
|
||||
|
||||
#endif //MOTOR_H
|
||||
@ -1,37 +0,0 @@
|
||||
#ifndef OLED_OLED_H_
|
||||
#define OLED_OLED_H_
|
||||
|
||||
#include "../../include/user/OledFont.h"
|
||||
#include <cstdint>
|
||||
#include "ti_msp_dl_config.h"
|
||||
|
||||
class OLED {
|
||||
public:
|
||||
struct Data {
|
||||
// 用户获取到的数据集合
|
||||
};
|
||||
|
||||
static void Init(); // 初始化函数
|
||||
static void Clear(); // 清屏函数
|
||||
static void Display_On(); // 开启显示
|
||||
static void Display_Off(); // 关闭显示
|
||||
static void Set_Pos(uint8_t x, uint8_t y); // 设置显示位置
|
||||
static unsigned int oled_pow(uint8_t m, uint8_t n);
|
||||
static void ShowNum(uint8_t x, uint8_t y, unsigned int num, uint8_t len, uint8_t size2, uint8_t Color_Turn); // 显示数字
|
||||
static void ShowDecimal(uint8_t x, uint8_t y, float num, uint8_t z_len, uint8_t f_len, uint8_t size2, uint8_t Color_Turn); // 显示浮点数
|
||||
static void ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size, uint8_t Color_Turn); // 显示字符
|
||||
static void ShowString(uint8_t x, uint8_t y, char* chr, uint8_t Char_Size, uint8_t Color_Turn); // 显示字符串
|
||||
static void ShowChinese(uint8_t x, uint8_t y, uint8_t no, uint8_t Color_Turn); // 显示汉字
|
||||
static void DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t* BMP, uint8_t Color_Turn); // 显示BMP图片
|
||||
static void HorizontalShift(uint8_t direction); // 水平全屏滚动
|
||||
static void Some_HorizontalShift(uint8_t direction, uint8_t start, uint8_t end); // 部分水平滚动
|
||||
static void VerticalAndHorizontalShift(uint8_t direction); // 垂直水平全屏滚动
|
||||
static void DisplayMode(uint8_t mode); // 设置显示模式
|
||||
static void IntensityControl(uint8_t intensity); // 设置亮度
|
||||
|
||||
private:
|
||||
static void WR_CMD(uint8_t cmd); // 写命令
|
||||
static void WR_DATA(uint8_t data); // 写数据
|
||||
};
|
||||
|
||||
#endif /* OLED_OLED_H_ */
|
||||
@ -1,17 +0,0 @@
|
||||
#ifndef OLED_OLEDFONT_H_
|
||||
#define OLED_OLEDFONT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const unsigned char F6x8[][6];
|
||||
extern const unsigned char F8X16[];
|
||||
extern const unsigned char Hzk[][32];
|
||||
extern unsigned char BMP1[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OLED_OLEDFONT_H_ */
|
||||
@ -1,41 +0,0 @@
|
||||
#ifndef OLEDMENUCONFIG_H
|
||||
#define OLEDMENUCONFIG_H
|
||||
|
||||
#include "../../include/user/OledMenuPaint.h"
|
||||
|
||||
#define _ 0
|
||||
|
||||
// const MenuPaint::Menu menuInfo[] = {
|
||||
// { "Status:Normal", MenuPaint::MENU_TYPE_INFO, nullptr, 0, 0 },
|
||||
// { "Vol:3.3V", MenuPaint::MENU_TYPE_INFO, nullptr, 0, 0 },
|
||||
// { "Temp:25C", MenuPaint::MENU_TYPE_INFO, nullptr, 0, 0 },
|
||||
// { "Version:v1.0.2", MenuPaint::MENU_TYPE_INFO, nullptr, 0, 0 },
|
||||
// { "Name: Boen", MenuPaint::MENU_TYPE_INFO, nullptr, 0, 0 }
|
||||
// };
|
||||
|
||||
// const MenuPaint::Menu menuSystem[] = {
|
||||
// { "FuncA", MenuPaint::MENU_TYPE_SWITCH, nullptr, 0, 0 }, // switchId = 0
|
||||
// { "FuncB", MenuPaint::MENU_TYPE_SWITCH, nullptr, 0, 1 }, // switchId = 1
|
||||
// };
|
||||
//
|
||||
// const MenuPaint::Menu menuRoot[] = {
|
||||
// { "Settings", MenuPaint::MENU_TYPE_FOLDER, menuSystem, 2, 0 },
|
||||
// { "Infos", MenuPaint::MENU_TYPE_FOLDER, menuInfo, 5, 0 }
|
||||
// };
|
||||
|
||||
constexpr MenuPaint::Menu task1Menu[] = {
|
||||
{"N=1", MenuPaint::MENU_TYPE_SWITCH, nullptr, 0, 0},
|
||||
{"N=2", MenuPaint::MENU_TYPE_SWITCH, nullptr, 0, 1},
|
||||
{"N=3", MenuPaint::MENU_TYPE_SWITCH, nullptr, 0, 2},
|
||||
{"N=4", MenuPaint::MENU_TYPE_SWITCH, nullptr, 0, 3},
|
||||
{"N=5", MenuPaint::MENU_TYPE_SWITCH, nullptr, 0, 4},
|
||||
|
||||
};
|
||||
|
||||
constexpr MenuPaint::Menu menuRoot[] {
|
||||
{"Num", MenuPaint::MENU_TYPE_FOLDER, task1Menu, 5, 0},
|
||||
{"HighSpeed", MenuPaint::MENU_TYPE_SWITCH, nullptr, 0, 5},
|
||||
|
||||
};
|
||||
|
||||
#endif // OLEDMENUCONFIG_H
|
||||
@ -1,63 +0,0 @@
|
||||
#ifndef OLED_MENU_DRIVER_H_
|
||||
#define OLED_MENU_DRIVER_H_
|
||||
|
||||
#include "../../include/user/Print.h"
|
||||
#include <cmath>
|
||||
#include <u8g2.h>
|
||||
#include "ti_msp_dl_config.h"
|
||||
|
||||
|
||||
class MenuDriver {
|
||||
public:
|
||||
static u8g2_t u8g2; // 静态成员变量
|
||||
|
||||
inline static void init() {
|
||||
oled_init();
|
||||
}
|
||||
|
||||
static void screenOn();
|
||||
static void screenOff();
|
||||
|
||||
static void* getCanvasBuffer();
|
||||
|
||||
static uint8_t getBufferTileHeight();
|
||||
static uint8_t getBufferTileWidth();
|
||||
static void canvasUpdate();
|
||||
static void canvasClear();
|
||||
static void setFont(const uint8_t *_font);
|
||||
static void setFont(const uint8_t *_font, uint8_t font_mode, uint8_t font_direction);
|
||||
static uint8_t getFontWidth(const char *_text);
|
||||
static uint8_t getFontHeight();
|
||||
static void setDrawType(uint8_t type);
|
||||
static void drawPixel(float x, float y);
|
||||
static void draw(float _x, float _y, const char *_text, const uint8_t *_font, uint8_t _font_mode, uint8_t _font_direction);
|
||||
static void draw(float _x, float _y, const char *_text, uint8_t _font_mode, uint8_t _font_direction);
|
||||
static void draw(float _x, float _y, const char *_text);
|
||||
static void drawEnglish(float _x, float _y, const char *_text);
|
||||
static void drawChinese(float _x, float _y, const char *_text);
|
||||
static void drawVDottedLine(float x, float y, float h);
|
||||
static void drawHDottedLine(float x, float y, float l);
|
||||
static void drawVLine(float x, float y, float h);
|
||||
static void drawHLine(float x, float y, float l);
|
||||
static void drawBMP(float x, float y, float w, float h, const uint8_t* bitMap);
|
||||
static void drawBox(float x, float y, float w, float h);
|
||||
static void drawRBox(float x, float y, float w, float h, float r);
|
||||
static void drawFrame(float x, float y, float w, float h);
|
||||
static void drawRFrame(float x, float y, float w, float h, float r);
|
||||
|
||||
// static void delay(unsigned long mill);
|
||||
// unsigned long millis();
|
||||
// unsigned long getTick();
|
||||
// unsigned long getRandomSeed();
|
||||
|
||||
static void drawCheckMark(float x, float y, float w, float h);
|
||||
|
||||
private:
|
||||
static void oled_init();
|
||||
static void ssd1306_transmit_cmd(uint8_t cmd);
|
||||
static void ssd1306_transmit_data(uint8_t data, uint8_t mode);
|
||||
static void ssd1306_set_cursor(unsigned char x, unsigned char y);
|
||||
static void ssd1306_fill(unsigned char data);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,44 +0,0 @@
|
||||
#ifndef MENU_PAINT_H_
|
||||
#define MENU_PAINT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class MenuPaint {
|
||||
public:
|
||||
enum MenuType {
|
||||
MENU_TYPE_FOLDER,
|
||||
MENU_TYPE_SWITCH,
|
||||
MENU_TYPE_INFO
|
||||
};
|
||||
|
||||
struct Menu {
|
||||
const char *name;
|
||||
MenuType type;
|
||||
const Menu *subMenus;
|
||||
uint8_t subMenuCount;
|
||||
uint8_t switchId; // 新增字段:开关ID (仅在type为SWITCH时有效)
|
||||
};
|
||||
|
||||
static void Init(); // 初始化菜单
|
||||
static void Paint(); // 渲染菜单
|
||||
static void ScrollUp(); // 向上移动
|
||||
static void ScrollDown(); // 向下移动
|
||||
static void Enter(); // 进入子菜单/切换开关
|
||||
static void Exit(); // 返回上级菜单
|
||||
|
||||
static bool GetSwitchState(uint8_t switchId); // 新增接口:获取开关状态
|
||||
|
||||
private:
|
||||
static const Menu *currentMenu; // 当前菜单指针
|
||||
static uint8_t currentMenuSize; // 当前菜单项数量
|
||||
static int8_t selectIndex; // 当前选中项索引
|
||||
static int8_t scrollOffset; // 滚动偏移
|
||||
|
||||
static bool switchStates[20]; // 开关状态(按switchId匹配)
|
||||
static const Menu *menuStack[5]; // 菜单返回栈
|
||||
static uint8_t stackIndex;
|
||||
|
||||
static void RenderItem(int y, const char *text, bool selected, bool checked);
|
||||
};
|
||||
|
||||
#endif // MENU_PAINT_H_
|
||||
@ -1,4 +0,0 @@
|
||||
#ifndef POTENTIOMETER_H
|
||||
#define POTENTIOMETER_H
|
||||
|
||||
#endif //POTENTIOMETER_H
|
||||
@ -1,29 +0,0 @@
|
||||
#ifndef PRINTF_H
|
||||
#define PRINTF_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <ti_msp_dl_config.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void Print_init();
|
||||
|
||||
// 格式化输出函数
|
||||
void print(const char *format, ...);
|
||||
|
||||
// 简单字符串输出(可选)
|
||||
void print_str(const char *str);
|
||||
|
||||
// 单字符发送(可选)
|
||||
void print_char(char ch);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PRINTF_H
|
||||
@ -1,11 +0,0 @@
|
||||
#ifndef SERVO_H
|
||||
#define SERVO_H
|
||||
#include "ti_msp_dl_config.h"
|
||||
|
||||
class Servo
|
||||
{
|
||||
public:
|
||||
static void SetUpAngle(const float angle);
|
||||
static void SetDownAngle(const float angle);
|
||||
};
|
||||
#endif //SERVO_H
|
||||
@ -1,45 +0,0 @@
|
||||
#ifndef STEPMOTOR_H
|
||||
#define STEPMOTOR_H
|
||||
|
||||
#define FRAME_LENGTH 11
|
||||
|
||||
#include "ti_msp_dl_config.h"
|
||||
#include <../../example/2025_include_user/Print.h>
|
||||
|
||||
class StepMotor {
|
||||
public:
|
||||
typedef enum {
|
||||
SPEED_MODE = 1,
|
||||
POSITION_MODE,
|
||||
TORQUE_MODE,
|
||||
ABSOLUTE_ANGLE_MODE
|
||||
} ControlMode;
|
||||
|
||||
struct Data {
|
||||
uint8_t address;
|
||||
uint8_t flag;
|
||||
uint16_t speed;
|
||||
int32_t position;
|
||||
uint8_t bcc;
|
||||
};
|
||||
|
||||
static void init();
|
||||
static void inject();
|
||||
|
||||
static void setSpeed(uint8_t direction, uint8_t subdivide, float speed_rad_s);
|
||||
static void setPosition(uint8_t direction, uint8_t subdivide, float angle_deg, float speed_rad_s);
|
||||
static void setTorque(uint8_t direction, uint8_t subdivide, uint16_t torque_mA, float speed_rad_s);
|
||||
static void setAbsoluteAngle(uint8_t direction, uint8_t subdivide, float absolute_angle_deg, float speed_rad_s);
|
||||
|
||||
static uint16_t getSpeed();
|
||||
static uint32_t getPosition();
|
||||
|
||||
static uint8_t _buffer;
|
||||
static Data _data;
|
||||
|
||||
private:
|
||||
static void transmit_command(const uint8_t *cmd);
|
||||
static void encode_frame(ControlMode mode, uint8_t direction, uint8_t subdivide, float angle_deg, uint16_t torque_mA, float absolute_angle_deg, float speed_rad_s, uint8_t *frame_buffer);
|
||||
};
|
||||
|
||||
#endif //STEPMOTOR_H
|
||||
@ -1,21 +0,0 @@
|
||||
#ifndef TRACKER_GPIO_H
|
||||
#define TRACKER_GPIO_H
|
||||
|
||||
#include "ti_msp_dl_config.h"
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
class TrackerGpio {
|
||||
public:
|
||||
struct Data {
|
||||
char data[7];
|
||||
};
|
||||
|
||||
static void init(); // 模块初始化
|
||||
static void inject(); // 数据注入(串口、I2C回调函数注入数据)
|
||||
static Data getData();
|
||||
|
||||
static Data _data; // 声明静态成员变量
|
||||
|
||||
};
|
||||
#endif //TRACKER_GPIO_H
|
||||
@ -1,24 +0,0 @@
|
||||
#ifndef TRACKER_H
|
||||
#define TRACKER_H
|
||||
|
||||
#include "ti_msp_dl_config.h"
|
||||
#include <string.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
class TrackerMpu {
|
||||
public:
|
||||
struct Data {
|
||||
char data[8];
|
||||
};
|
||||
|
||||
static void init(); // 模块初始化
|
||||
static void inject(); // 数据注入(串口、I2C回调函数注入数据)
|
||||
static Data getData();
|
||||
|
||||
static uint8_t _buffer;
|
||||
static Data _data; // 声明静态成员变量
|
||||
|
||||
};
|
||||
|
||||
#endif //TRACKER_H
|
||||
@ -1,4 +0,0 @@
|
||||
#ifndef ULTRASONIC_H
|
||||
#define ULTRASONIC_H
|
||||
|
||||
#endif //ULTRASONIC_H
|
||||
@ -1,400 +0,0 @@
|
||||
#include <ti_msp_dl_config.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
#include <Print.h>
|
||||
#include <Encoder.h>
|
||||
#include <Imu.h>
|
||||
#include <Motor.h>
|
||||
#include <TrackerMpu.h>
|
||||
#include <TrackerGpio.h>
|
||||
#include <2025_include_user/Beep.h>
|
||||
#include <Host.h>
|
||||
#include <Key.h>
|
||||
#include <Led.h>
|
||||
#include <Servo.h>
|
||||
#include <Stepmotor.h>
|
||||
#include <Oled.hpp>
|
||||
#include <OledMenuDriver.h>
|
||||
#include <OledMenuPaint.h>
|
||||
#include <TrackerGpio.h>
|
||||
#include <TrackerGpio.h>
|
||||
|
||||
|
||||
/************ 外部中断测试部分 ************/
|
||||
|
||||
extern "C" void GROUP1_IRQHandler() {
|
||||
//读取Group1的中断寄存器并清除中断标志位
|
||||
switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
|
||||
//检查是否是KEY的GPIOB端口中断,注意是INT_IIDX,不是PIN_22_IIDX
|
||||
case Key_GPIOA_INT_IIDX:
|
||||
case GPIO_MULTIPLE_GPIOB_INT_IIDX: {
|
||||
const uint32_t statusA = DL_GPIO_getPendingInterrupt(GPIOA);
|
||||
const uint32_t statusB = DL_GPIO_getPendingInterrupt(GPIOB);
|
||||
// print("%d\n", statusA);
|
||||
// print("%d\n", statusB);
|
||||
if (statusA == KEY1_PIN_ID + 1) {
|
||||
Key::keys[KEY1].state = 1;
|
||||
} else if (statusB == KEY2_PIN_ID + 1) {
|
||||
Key::keys[KEY2].state = 1;
|
||||
} else if (statusB == KEY3_PIN_ID + 1) {
|
||||
Key::keys[KEY3].state = 1;
|
||||
} else if (statusB == KEY4_PIN_ID + 1) {
|
||||
Key::keys[KEY4].state = 1;
|
||||
}
|
||||
// TrackerGpio::inject(Tracker_Track1_PIN, DL_GPIO_readPins(Tracker_Track1_PORT, Tracker_Track1_PIN) > 0);
|
||||
// TrackerGpio::inject(Tracker_Track2_PIN, DL_GPIO_readPins(Tracker_Track2_PORT, Tracker_Track2_PIN) > 0);
|
||||
// TrackerGpio::inject(Tracker_Track3_PIN, DL_GPIO_readPins(Tracker_Track3_PORT, Tracker_Track3_PIN) > 0);
|
||||
// TrackerGpio::inject(Tracker_Track4_PIN, DL_GPIO_readPins(Tracker_Track4_PORT, Tracker_Track4_PIN) > 0);
|
||||
// TrackerGpio::inject(Tracker_Track5_PIN, DL_GPIO_readPins(Tracker_Track5_PORT, Tracker_Track5_PIN) > 0);
|
||||
// TrackerGpio::inject(Tracker_Track6_PIN, DL_GPIO_readPins(Tracker_Track6_PORT, Tracker_Track6_PIN) > 0);
|
||||
// TrackerGpio::inject(Tracker_Track7_PIN, DL_GPIO_readPins(Tracker_Track7_PORT, Tracker_Track7_PIN) > 0);
|
||||
DL_GPIO_clearInterruptStatus(GPIOA, statusA);
|
||||
DL_GPIO_clearInterruptStatus(GPIOB, statusB);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/************ FreeRtos 任务定义区 ************/
|
||||
|
||||
[[noreturn]] void vLedTask(void *pvParameters) {
|
||||
while (true) {
|
||||
Led::on(LED0);
|
||||
// DL_GPIO_setPins(Lights_PORT, Lights_Light_PIN);
|
||||
vTaskDelay(pdMS_TO_TICKS(500)); // 每500毫秒切换一次LED状态
|
||||
Led::off(LED0);
|
||||
// DL_GPIO_clearPins(Lights_PORT, Lights_Light_PIN);
|
||||
vTaskDelay(pdMS_TO_TICKS(500)); // 每500毫秒切换一次LE+D状态
|
||||
}
|
||||
}
|
||||
|
||||
[[noreturn]] void vOledTask(void *pvParameters) {
|
||||
MenuDriver::init();
|
||||
MenuPaint::Init();
|
||||
while (true) {
|
||||
const int direction = (int) Host::get("Direction", 0);
|
||||
if (Key::getState(KEY1 || direction == 2)) {
|
||||
MenuPaint::ScrollUp();
|
||||
}
|
||||
if (Key::getState(KEY2) || direction == 8) {
|
||||
MenuPaint::ScrollDown();
|
||||
}
|
||||
if (Key::getState(KEY3) || direction == 4) {
|
||||
MenuPaint::Enter();
|
||||
}
|
||||
if (Key::getState(KEY4) || direction == 6) {
|
||||
MenuPaint::Exit();
|
||||
}
|
||||
|
||||
MenuPaint::Paint();
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
[[noreturn]] void vTestTask(void *pvParameters) {
|
||||
while (true) {
|
||||
// print("Ctrl: %f\n", Host::get("Ctrl", 0.0));
|
||||
// print("x: %f\n", Host::get("x", 0.0));
|
||||
// print("y: %f\n", Host::get("y", 0.0));
|
||||
// Motor::setSpeed(3000, 3000);
|
||||
// TrackerGpio::Data data = TrackerGpio::getData(); // 每位数据:0 表示压线,1 表示空白
|
||||
// const char *d = data.data;
|
||||
//
|
||||
// print("Data:%d,%d,%d,%d,%d,%d,%d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6]);
|
||||
// vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t turn_limit = 0;
|
||||
[[noreturn]] void vTrackerTask(void *pvParameters) {
|
||||
// 计算偏移量(简单加权)
|
||||
// 左侧为正,右侧为负
|
||||
constexpr float weights[7] = {-2.1, -1.5, -0.8, 0, 0.8, 1.5, 2.1};
|
||||
constexpr int base_speed = 4000; // 基础速度
|
||||
constexpr int adjust_speed = 2000; // 差速调整速度
|
||||
|
||||
while (true) {
|
||||
if (turn_limit <= 0) {
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
if (MenuPaint::GetSwitchState(i) == 1) {
|
||||
turn_limit = 4 * (i + 1) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Motor::stop();
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 读取循迹传感器数据
|
||||
TrackerGpio::Data data = TrackerGpio::getData(); // 每位数据:0 表示压线,1 表示空白
|
||||
const char *d = data.data;
|
||||
|
||||
float error = 0;
|
||||
int sum = 0;
|
||||
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
if (d[i] == 0) {
|
||||
// 压到线
|
||||
error += weights[i];
|
||||
sum++;
|
||||
}
|
||||
}
|
||||
|
||||
if (sum == 0) {
|
||||
turn_limit--;
|
||||
if (turn_limit <= 0) {
|
||||
Motor::stop();
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t is_speed = (MenuPaint::GetSwitchState(5) == 1) ? 1 : 0;
|
||||
uint8_t speed = is_speed ? 210 : 160;
|
||||
Motor::setLeftSpeed(0);
|
||||
Motor::setRightSpeed(speed * 10);
|
||||
while (true) {
|
||||
data = TrackerGpio::getData(); // 每位数据:0 表示压线,1 表示空白
|
||||
const char *inner_d = data.data;
|
||||
if (inner_d[3] == 0 || inner_d[2] == 0 || inner_d[1] == 0 || inner_d[0] == 0)
|
||||
break;
|
||||
Motor::setLeftSpeed(0);
|
||||
Motor::setRightSpeed(speed * 10);
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
} else {
|
||||
int left_speed = base_speed;
|
||||
int right_speed = base_speed;
|
||||
|
||||
error = error / sum;
|
||||
// 差速控制,误差越大,左右轮速度差越大
|
||||
left_speed = (int) (base_speed - error * adjust_speed / 4);
|
||||
right_speed = (int) (base_speed + error * adjust_speed / 4);
|
||||
|
||||
// 限制最大最小速度
|
||||
if (left_speed > 10000) left_speed = 10000;
|
||||
if (left_speed < -10000) left_speed = -10000;
|
||||
if (right_speed > 10000) right_speed = 10000;
|
||||
if (right_speed < -10000) right_speed = -10000;
|
||||
|
||||
// 设置电机速度
|
||||
Motor::setLeftSpeed(left_speed);
|
||||
Motor::setRightSpeed(right_speed);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[noreturn]] void vStepMotorTask(void *pvParameters) {
|
||||
// // PID参数(根据实际调试再微调)
|
||||
//
|
||||
// const float integral_limit = 500.0f; // 积分限幅,避免积分快速累积
|
||||
// const float DEAD_ZONE = 10.0f; // 误差死区:误差在±5像素内不动作
|
||||
//
|
||||
// float integral = 0.0f;
|
||||
// float last_error = 0.0f;
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
|
||||
while (true) {
|
||||
// DL_TimerG_setCaptureCompareValue(Servo_INST, (uint32_t)800, GPIO_Servo_C0_IDX);
|
||||
Servo::SetUpAngle(Host::getWithoutClean("angle", 87.0));
|
||||
// Servo::SetDownAngle(120);
|
||||
// // if (MenuPaint::GetSwitchState(5) == 0 || MenuPaint::GetSwitchState(6) == 0) {
|
||||
// // vTaskDelay(pdMS_TO_TICKS(100));
|
||||
// // continue;
|
||||
// // }
|
||||
//
|
||||
// const double Kp = Host::getWithoutClean("kp", 0.2);
|
||||
// const double Ki = Host::getWithoutClean("ki", 0.0005);
|
||||
// const double Kd = Host::getWithoutClean("kd", 0.006);
|
||||
// const double t_ = Host::posX; // 获取像素误差,范围0~240
|
||||
// const uint8_t direction = (t_ > 0) ? 1 : 0;
|
||||
// const double error = t_ > 0 ? t_ : -t_;
|
||||
//
|
||||
//
|
||||
// print("Kp: %f, Ki: %f, Kd: %f\n", Kp, Ki, Kd);
|
||||
//
|
||||
// // 死区处理
|
||||
// if (fabs(error) < DEAD_ZONE) {
|
||||
// StepMotor::setPosition(0, 32, 0.0f, 0); // 停止动作
|
||||
// integral = 0; // 死区内积分归零,避免积累
|
||||
// // while (true) {
|
||||
// // // TODO 激光ON
|
||||
// // vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
// // // TODO 激光OFF
|
||||
// // }
|
||||
// } else {
|
||||
// // 积分项累加 & 限幅
|
||||
// integral += error;
|
||||
// if (integral > integral_limit) integral = integral_limit;
|
||||
// if (integral < -integral_limit) integral = -integral_limit;
|
||||
//
|
||||
// // 微分项
|
||||
// float derivative = error - last_error;
|
||||
//
|
||||
// // PID输出
|
||||
// float output = Kp * error + Ki * integral + Kd * derivative;
|
||||
//
|
||||
// // 限制输出范围(0.3° ~ 2.0°)
|
||||
// if (output < 0.3f) output = 0.3f;
|
||||
// if (output > 4.0f) output = 4.0f;
|
||||
//
|
||||
// // 控制步进电机
|
||||
// StepMotor::setPosition(direction, 32, output, -10);
|
||||
// // print("Motor: speed=%f, direction=%d\n", output, direction);
|
||||
//
|
||||
// last_error = error; // 保存上次误差
|
||||
// }
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
}
|
||||
}
|
||||
|
||||
/***************** 主函数 ******************/
|
||||
|
||||
int main() {
|
||||
/*** SysConfig 初始化 ***/
|
||||
SYSCFG_DL_init();
|
||||
|
||||
/*** 模块初始化 ***/
|
||||
Print_init();
|
||||
Encoder::init();
|
||||
// Imu::init();
|
||||
Motor::init();
|
||||
// TrackerMpu::init();
|
||||
// Beep::init();
|
||||
// Led::init();
|
||||
Host::init();
|
||||
Key::init();
|
||||
// StepMotor::init();
|
||||
|
||||
/*** FreeRtos 任务初始化 ***/
|
||||
xTaskCreate(vLedTask, "TestLedTask", 32, nullptr, 1, nullptr);
|
||||
xTaskCreate(vOledTask, "vOledTask", 128, nullptr, 1, nullptr);
|
||||
// xTaskCreate(vTestTask, "vTestTask", 512, nullptr, 1, nullptr);
|
||||
xTaskCreate(vTrackerTask, "vTrackerTask", 256, nullptr, 1, nullptr);
|
||||
xTaskCreate(vStepMotorTask, "vStepMotorTask", 32, nullptr, 1, nullptr);
|
||||
|
||||
|
||||
/*** 启动 FreeRtos ***/
|
||||
vTaskStartScheduler();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************ FreeRtos 错误处理部分 ************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
|
||||
/* 栈溢出时的处理代码 */
|
||||
/* 例如,打印错误信息并重置系统 */
|
||||
|
||||
/* 参数:
|
||||
* xTask - 发生栈溢出的任务句柄
|
||||
* pcTaskName - 发生栈溢出的任务名称
|
||||
*/
|
||||
|
||||
/* 通常在这里添加一些错误处理和系统恢复的代码 */
|
||||
while (1) {
|
||||
/* 可以在此处添加错误处理代码,如闪烁LED或输出调试信息 */
|
||||
}
|
||||
}
|
||||
|
||||
/* 在全局范围内定义存储空间 */
|
||||
static StaticTask_t xIdleTaskTCB;
|
||||
static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE];
|
||||
|
||||
/* 实现所需的函数 */
|
||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
||||
StackType_t **ppxIdleTaskStackBuffer,
|
||||
uint32_t *pulIdleTaskStackSize) {
|
||||
/* 传递静态分配的空闲任务数据结构的地址 */
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||
|
||||
/* 传递静态分配的空闲任务堆栈的地址 */
|
||||
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||
|
||||
/* 传递堆栈大小 */
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/* 为定时器任务定义静态内存 */
|
||||
static StaticTask_t xTimerTaskTCB;
|
||||
static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];
|
||||
|
||||
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
|
||||
StackType_t **ppxTimerTaskStackBuffer,
|
||||
uint32_t *pulTimerTaskStackSize) {
|
||||
/* 传递静态分配的定时器任务数据结构的地址 */
|
||||
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
||||
|
||||
/* 传递静态分配的定时器任务堆栈的地址 */
|
||||
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
||||
|
||||
/* 传递堆栈大小 */
|
||||
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// [[noreturn]] void vStepMotorTask(void *pvParameters) {
|
||||
// while (true) {
|
||||
// double speed = Host::posX;
|
||||
// uint8_t direction = 1;
|
||||
//
|
||||
// if (Host::x_count <= 0) {
|
||||
// speed = 0.0;
|
||||
// } else {
|
||||
// Host::x_count--;
|
||||
// if (Host::x_count == 0) {
|
||||
// Host::posX = 0.0; // 用完后置零
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// direction = speed >= 0 ? 1 : 0;
|
||||
// speed = speed >= 0 ? speed : -speed;
|
||||
// StepMotor::setSpeed(direction, 32, float(speed));
|
||||
// print("Motor: speed=%f, direction=%d\n", speed, direction);
|
||||
//
|
||||
// vTaskDelay(pdMS_TO_TICKS(70));
|
||||
// }
|
||||
// }
|
||||
|
||||
// [[noreturn]] void vStepMotorTask(void *pvParameters) {
|
||||
// while (true) {
|
||||
// int error = (int) Host::posX;
|
||||
// uint8_t direction = error > 0;
|
||||
// if (error > 5 || error < -5) {
|
||||
// StepMotor::setPosition(direction, 32, 0.5, 10);
|
||||
// }
|
||||
//
|
||||
// vTaskDelay(pdMS_TO_TICKS(93));
|
||||
// }
|
||||
// }
|
||||
// print("FunA: %d\n", MenuPaint::GetSwitchState(0));
|
||||
// print("FunB: %d\n", MenuPaint::GetSwitchState(1));
|
||||
// if (MenuPaint::GetSwitchState(0) == 1) {
|
||||
// Beep::start();
|
||||
// } else {
|
||||
// Beep::stop();
|
||||
// }
|
||||
|
||||
// [[noreturn]] void vTrackerTask(void *pvParameters) {
|
||||
// while (true) {
|
||||
// print("Tracker!\n");
|
||||
// const TrackerGpio::Data data = TrackerGpio::getData();
|
||||
// print("Tracker: %d, %d, %d, %d, %d, %d, %d\n", data.data[0], data.data[1], data.data[2], data.data[3], data.data[4], data.data[5], data.data[6]);
|
||||
// vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
// }
|
||||
// }
|
||||
@ -1,11 +0,0 @@
|
||||
#include "../2025_include_user/Beep.h"
|
||||
|
||||
void Beep::init() {}
|
||||
|
||||
void Beep::start() {
|
||||
DL_TimerG_startCounter(Beep_INST);
|
||||
}
|
||||
|
||||
void Beep::stop() {
|
||||
DL_TimerG_stopCounter(Beep_INST);
|
||||
}
|
||||
@ -1,91 +0,0 @@
|
||||
#include "../2025_include_user/Encoder.h"
|
||||
|
||||
#define RADIUS_OF_TYRE 30 // 轮胎半径,单位:mm
|
||||
#define LINE_SPEED_C (2.0f * 3.1415926f * RADIUS_OF_TYRE) // 一圈对应的线长,mm
|
||||
#define SPEED_RATIO 50
|
||||
|
||||
Encoder::Speed Encoder::ticks = {0, 0};
|
||||
Encoder::Speed Encoder::direction = {0, 0};
|
||||
Encoder::Speed Encoder::speed = {0, 0};
|
||||
Encoder::Speed Encoder::real_speed = {0, 0};
|
||||
|
||||
extern "C" {
|
||||
void Encoder1_TIM_INST_IRQHandler(void)
|
||||
{
|
||||
switch (DL_TimerG_getPendingInterrupt(Encoder1_TIM_INST))
|
||||
{
|
||||
case DL_TIMERG_IIDX_LOAD:
|
||||
Encoder::ticks.left++;
|
||||
Encoder::direction.left = DL_GPIO_readPins(Encoder1_GPIO_PORT, Encoder1_GPIO_Encoder1B_GPIO_PIN) ? -1 : 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Encoder2_TIM_INST_IRQHandler(void)
|
||||
{
|
||||
switch (DL_TimerA_getPendingInterrupt(Encoder2_TIM_INST))
|
||||
{
|
||||
case DL_TIMERG_IIDX_LOAD:
|
||||
Encoder::ticks.right++;
|
||||
Encoder::direction.right = DL_GPIO_readPins(Encoder2_GPIO_PORT, Encoder2_GPIO_Encoder2B_GPIO_PIN) ? -1 : 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Encoder_Count_INST_IRQHandler(void) {
|
||||
Encoder::inject();
|
||||
}
|
||||
}
|
||||
|
||||
void Encoder::init() {
|
||||
NVIC_EnableIRQ(Encoder1_TIM_INST_INT_IRQN);
|
||||
DL_TimerG_startCounter(Encoder1_TIM_INST);
|
||||
|
||||
NVIC_EnableIRQ(Encoder2_TIM_INST_INT_IRQN);
|
||||
DL_TimerA_startCounter(Encoder2_TIM_INST);
|
||||
|
||||
NVIC_EnableIRQ(Encoder_Count_INST_INT_IRQN);
|
||||
DL_TimerG_startCounter(Encoder_Count_INST);
|
||||
}
|
||||
|
||||
void Encoder::inject() {
|
||||
speed = {ticks.left * SPEED_RATIO, ticks.right * SPEED_RATIO};
|
||||
real_speed = {ticks.left * SPEED_RATIO * direction.left, ticks.right * SPEED_RATIO * direction.right};
|
||||
ticks = {0, 0};
|
||||
}
|
||||
|
||||
Encoder::Speed Encoder::getSpeeds() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
Encoder::Speed Encoder::getRealSpeeds() {
|
||||
return real_speed;
|
||||
}
|
||||
|
||||
int Encoder::getRealLeftSpeed() {
|
||||
return real_speed.left;
|
||||
}
|
||||
|
||||
int Encoder::getRealRightSpeed() {
|
||||
return real_speed.right;
|
||||
}
|
||||
|
||||
int Encoder::getLeftSpeed() {
|
||||
return speed.left;
|
||||
}
|
||||
|
||||
int Encoder::getRightSpeed() {
|
||||
return speed.right;
|
||||
}
|
||||
|
||||
int Encoder::getLeftDirection() {
|
||||
return direction.left;
|
||||
}
|
||||
|
||||
int Encoder::getRightDirection() {
|
||||
return direction.right;
|
||||
}
|
||||
@ -1,275 +0,0 @@
|
||||
#include "../2025_include_user/Host.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" void HOST_INST_IRQHandler(void) {
|
||||
const char _buffer = DL_UART_Main_receiveData(HOST_INST);
|
||||
switch (DL_UART_getPendingInterrupt(HOST_INST)) {
|
||||
case DL_UART_IIDX_RX:
|
||||
Host::inject(_buffer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NVIC_ClearPendingIRQ(HOST_INST_INT_IRQN);
|
||||
DL_UART_enableInterrupt(HOST_INST, DL_UART_INTERRUPT_RX); // 启用接收中断
|
||||
}
|
||||
|
||||
extern "C" void PRINTF_INST_IRQHandler(void) {
|
||||
const char _buffer = DL_UART_Main_receiveData(PRINTF_INST);
|
||||
switch (DL_UART_getPendingInterrupt(PRINTF_INST)) {
|
||||
case DL_UART_IIDX_RX:
|
||||
Host::inject(_buffer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NVIC_ClearPendingIRQ(PRINTF_INST_INT_IRQN);
|
||||
DL_UART_enableInterrupt(PRINTF_INST, DL_UART_INTERRUPT_RX); // 启用接收中断
|
||||
}
|
||||
|
||||
|
||||
KeyValuePair Host::data[MAX_KEYS] = {0}; // 初始化为0
|
||||
int Host::count = 0;
|
||||
|
||||
void Host::init() {
|
||||
NVIC_ClearPendingIRQ(HOST_INST_INT_IRQN);
|
||||
NVIC_EnableIRQ(HOST_INST_INT_IRQN);
|
||||
DL_UART_enable(HOST_INST); // 启用 UART 模块
|
||||
DL_UART_enableInterrupt(HOST_INST, DL_UART_INTERRUPT_RX); // 启用接收中断
|
||||
|
||||
NVIC_ClearPendingIRQ(PRINTF_INST_INT_IRQN);
|
||||
NVIC_EnableIRQ(PRINTF_INST_INT_IRQN);
|
||||
DL_UART_enable(PRINTF_INST); // 启用 UART 模块
|
||||
DL_UART_enableInterrupt(PRINTF_INST, DL_UART_INTERRUPT_RX); // 启用接收中断
|
||||
}
|
||||
|
||||
double Host::posX = 0.0;
|
||||
double Host::posY = 0.0;
|
||||
int Host::x_count = 0;
|
||||
int Host::y_count = 0;
|
||||
|
||||
void Host::inject(const char ch) {
|
||||
static char buffer[MAX_KEY_LENGTH];
|
||||
static int bufferIndex = 0;
|
||||
static bool isKey = false;
|
||||
static bool isValue = false;
|
||||
static char key[MAX_KEY_LENGTH];
|
||||
static char value[MAX_KEY_LENGTH];
|
||||
|
||||
if (ch == '$') {
|
||||
bufferIndex = 0;
|
||||
isKey = true;
|
||||
isValue = false;
|
||||
} else if (ch == '(') {
|
||||
bufferIndex = 0;
|
||||
} else if (ch == ')') {
|
||||
strncpy(key, buffer, bufferIndex);
|
||||
key[bufferIndex] = '\0';
|
||||
bufferIndex = 0;
|
||||
isKey = false;
|
||||
isValue = true;
|
||||
} else if (ch == '#') {
|
||||
strncpy(value, buffer, bufferIndex);
|
||||
value[bufferIndex] = '\0';
|
||||
bufferIndex = 0;
|
||||
isValue = false;
|
||||
|
||||
double num;
|
||||
if (sscanf(value, "%lf", &num) == 1) {
|
||||
if (strcmp(key, "x") == 0) {
|
||||
posX = num;
|
||||
return;
|
||||
} else if (strcmp(key, "y") == 0) {
|
||||
posY = num;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (strcmp(data[i].key, key) == 0) {
|
||||
data[i].value = num;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (count < MAX_KEYS) {
|
||||
strncpy(data[count].key, key, MAX_KEY_LENGTH);
|
||||
data[count].value = num;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else if (isKey || isValue) {
|
||||
if (bufferIndex < MAX_KEY_LENGTH - 1) {
|
||||
buffer[bufferIndex++] = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// void Host::inject(const char ch) {
|
||||
// static char buffer[MAX_KEY_LENGTH];
|
||||
// static int bufferIndex = 0;
|
||||
// static bool isKey = false;
|
||||
// static bool isValue = false;
|
||||
// static char key[MAX_KEY_LENGTH];
|
||||
// static char value[MAX_KEY_LENGTH];
|
||||
//
|
||||
// if (ch == '$') {
|
||||
// bufferIndex = 0;
|
||||
// isKey = true;
|
||||
// isValue = false;
|
||||
// } else if (ch == '(') {
|
||||
// bufferIndex = 0;
|
||||
// } else if (ch == ')') {
|
||||
// strncpy(key, buffer, bufferIndex);
|
||||
// key[bufferIndex] = '\0';
|
||||
// bufferIndex = 0;
|
||||
// isKey = false;
|
||||
// isValue = true;
|
||||
// } else if (ch == '#') {
|
||||
// strncpy(value, buffer, bufferIndex);
|
||||
// value[bufferIndex] = '\0';
|
||||
// bufferIndex = 0;
|
||||
// isValue = false;
|
||||
//
|
||||
// double num;
|
||||
// if (sscanf(value, "%lf", &num) == 1) {
|
||||
// if (strcmp(key, "x") == 0) {
|
||||
// posX = num;
|
||||
// x_count = 2;
|
||||
// // print("x: %d\n", num);
|
||||
// } else if (strcmp(key, "y") == 0) {
|
||||
// posY = num;
|
||||
// y_count = 2;
|
||||
// // print("y: %d\n", num);
|
||||
// }
|
||||
// // 其他key直接丢弃,不处理
|
||||
// }
|
||||
// } else if (isKey || isValue) {
|
||||
// if (bufferIndex < MAX_KEY_LENGTH - 1) {
|
||||
// buffer[bufferIndex++] = ch;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// void Host::inject(const char ch) {
|
||||
// static char buffer[MAX_KEY_LENGTH];
|
||||
// static int bufferIndex = 0;
|
||||
// static bool isKey = false;
|
||||
// static bool isValue = false;
|
||||
// static char key[MAX_KEY_LENGTH];
|
||||
// static char value[MAX_KEY_LENGTH];
|
||||
//
|
||||
// if (ch == '$') {
|
||||
// bufferIndex = 0;
|
||||
// isKey = true;
|
||||
// isValue = false;
|
||||
// } else if (ch == '(') {
|
||||
// bufferIndex = 0;
|
||||
// } else if (ch == ')') {
|
||||
// strncpy(key, buffer, bufferIndex);
|
||||
// key[bufferIndex] = '\0';
|
||||
// bufferIndex = 0;
|
||||
// isKey = false;
|
||||
// isValue = true;
|
||||
// } else if (ch == '#') {
|
||||
// strncpy(value, buffer, bufferIndex);
|
||||
// value[bufferIndex] = '\0';
|
||||
// bufferIndex = 0;
|
||||
// isValue = false;
|
||||
//
|
||||
// double num;
|
||||
// if (sscanf(value, "%lf", &num) == 1) {
|
||||
// for (int i = 0; i < count; ++i) {
|
||||
// if (strcmp(data[i].key, key) == 0) {
|
||||
// data[i].value = num;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// if (count < MAX_KEYS) {
|
||||
// strncpy(data[count].key, key, MAX_KEY_LENGTH);
|
||||
// data[count].value = num;
|
||||
// count++;
|
||||
// }
|
||||
// }
|
||||
// } else if (isKey || isValue) {
|
||||
// if (bufferIndex < MAX_KEY_LENGTH - 1) {
|
||||
// buffer[bufferIndex++] = ch;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
double Host::get(const char* key, double defaultValue) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (strcmp(data[i].key, key) == 0) {
|
||||
double value = data[i].value;
|
||||
data[i].value = defaultValue;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return defaultValue; // 默认值
|
||||
}
|
||||
|
||||
double Host::getWithoutClean(const char* key, double defaultValue) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (strcmp(data[i].key, key) == 0) {
|
||||
return data[i].value;
|
||||
}
|
||||
}
|
||||
return defaultValue; // 默认值
|
||||
}
|
||||
|
||||
void Host::log(const char* level, const char* format, ...) {
|
||||
char buffer[256];
|
||||
va_list args;
|
||||
|
||||
// 初始化可变参数列表
|
||||
va_start(args, format);
|
||||
|
||||
// 格式化字符串到缓冲区
|
||||
vsnprintf(buffer, sizeof(buffer), format, args);
|
||||
|
||||
// 结束可变参数列表
|
||||
va_end(args);
|
||||
|
||||
// 创建完整的INFO字符串
|
||||
char fullInfo[256];
|
||||
snprintf(fullInfo, sizeof(fullInfo), "%s%s%s", level, buffer, "#");
|
||||
|
||||
// 调用printf输出
|
||||
print("%s\n", fullInfo);
|
||||
}
|
||||
|
||||
void Host::info(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log("$0100", format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Host::warn(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log("$0200", format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Host::error(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log("$0300", format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Host::plot(const char* key, double value) {
|
||||
char buffer[256];
|
||||
char fullInfo[256];
|
||||
// 格式化键值对
|
||||
snprintf(buffer, sizeof(buffer), "(%s)%f", key, value);
|
||||
// 创建完整的PLOT字符串
|
||||
snprintf(fullInfo, sizeof(fullInfo), "$0400%s#", buffer);
|
||||
// 调用printf输出
|
||||
print("%s\n", fullInfo);
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
#include "../2025_include_user/Imu.h"
|
||||
|
||||
uint8_t Imu::_buffer = 0;
|
||||
Imu::Data Imu::_data = {};
|
||||
static uint8_t frame_index = 0;
|
||||
static uint8_t frame_buffer[11];
|
||||
|
||||
extern "C" void IMU_INST_IRQHandler(void) {
|
||||
switch (DL_UART_getPendingInterrupt(IMU_INST)) {
|
||||
case DL_UART_IIDX_RX:
|
||||
Imu::_buffer = DL_UART_Main_receiveData(IMU_INST);
|
||||
Imu::inject();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NVIC_ClearPendingIRQ(IMU_INST_INT_IRQN);
|
||||
DL_UART_enableInterrupt(IMU_INST, DL_UART_INTERRUPT_RX); // 启用接收中断
|
||||
}
|
||||
|
||||
void Imu::init() {
|
||||
NVIC_ClearPendingIRQ(IMU_INST_INT_IRQN);
|
||||
NVIC_EnableIRQ(IMU_INST_INT_IRQN);
|
||||
DL_UART_enable(IMU_INST); // 启用 UART 模块
|
||||
DL_UART_enableInterrupt(IMU_INST, DL_UART_INTERRUPT_RX); // 启用接收中断
|
||||
|
||||
}
|
||||
|
||||
void Imu::inject() {
|
||||
if (frame_index == 0 && _buffer == 0x55) {
|
||||
frame_buffer[frame_index++] = _buffer;
|
||||
} else if (frame_index == 1 && _buffer == 0x55) {
|
||||
frame_buffer[frame_index++] = _buffer;
|
||||
} else if (frame_index >= 2) {
|
||||
frame_buffer[frame_index++] = _buffer;
|
||||
if (frame_index >= 11) {
|
||||
uint8_t sum = 0;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
sum += frame_buffer[i];
|
||||
}
|
||||
|
||||
if (sum == frame_buffer[10] && frame_buffer[2] == 0x01 && frame_buffer[3] == 0x06) {
|
||||
int16_t roll = (frame_buffer[5] << 8) | frame_buffer[4];
|
||||
int16_t pitch = (frame_buffer[7] << 8) | frame_buffer[6];
|
||||
int16_t yaw = (frame_buffer[9] << 8) | frame_buffer[8];
|
||||
|
||||
_data.roll = (float) roll / 32768.0f * 180.0f;
|
||||
_data.pitch = (float) pitch / 32768.0f * 180.0f;
|
||||
_data.yaw = (float) yaw / 32768.0f * 180.0f;
|
||||
}
|
||||
frame_index = 0;
|
||||
}
|
||||
} else {
|
||||
frame_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Imu::Data Imu::getData() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
float Imu::getRoll() {
|
||||
return _data.roll;
|
||||
}
|
||||
|
||||
float Imu::getPitch() {
|
||||
return _data.pitch;
|
||||
}
|
||||
|
||||
float Imu::getYaw() {
|
||||
return _data.yaw;
|
||||
}
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
#include "Key.h"
|
||||
|
||||
#include <../2025_include_user/Host.h>
|
||||
|
||||
Key::KeyData Key::keys[] = {
|
||||
{KEY1, Key_Key1_PORT, Key_Key1_PIN, 0},
|
||||
{KEY2, Key_Key2_PORT, Key_Key2_PIN, 0},
|
||||
{KEY3, Key_Key3_PORT, Key_Key3_PIN, 0},
|
||||
{KEY4, Key_Key4_PORT, Key_Key4_PIN, 0},
|
||||
};
|
||||
|
||||
// extern "C" {
|
||||
// void vKeyTask(void *pvParameters) {
|
||||
// while (true) {
|
||||
// for (uint8_t i = 0; i < (sizeof(Key::keys) / sizeof(Key::keys[0])); i++) {
|
||||
// if (DL_GPIO_readPins(Key::keys[i].port, Key::keys[i].pin) == 0) {
|
||||
// // print("Key%d: %d\r\n", i, 1);
|
||||
// Key::keys[i].state = 1;
|
||||
// } else {
|
||||
// // print("Key%d: %d\r\n", i, 0);
|
||||
// Key::keys[i].state = 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// vTaskDelay(pdMS_TO_TICKS(1)); // 每10ms检测一次按键,释放CPU
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void Key::init() {
|
||||
// xTaskCreate(vKeyTask, "vKeyTask", 32, nullptr, 1, nullptr);
|
||||
NVIC_EnableIRQ(Key_GPIOA_INT_IRQN);
|
||||
NVIC_EnableIRQ(GPIO_MULTIPLE_GPIOB_INT_IRQN);
|
||||
}
|
||||
|
||||
uint8_t Key::getState(const uint8_t id) {
|
||||
const uint8_t state = keys[id].state;
|
||||
keys[id].state = 0;
|
||||
return state;
|
||||
}
|
||||
|
||||
void Key::setState(const uint8_t id, const uint8_t state) {
|
||||
keys[id].state = state;
|
||||
}
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
#include "../2025_include_user/Motor.h"
|
||||
|
||||
void Motor::init() {}
|
||||
|
||||
void Motor::setLeftSpeed(const int left_speed) {
|
||||
setLeftDirection(left_speed > 0);
|
||||
const int pwmA_abs = Abs(left_speed);
|
||||
DL_TimerA_setCaptureCompareValue(Motor_INST, pwmA_abs, GPIO_Motor_C0_IDX);
|
||||
}
|
||||
|
||||
void Motor::setRightSpeed(const int right_speed) {
|
||||
setRightDirection(right_speed > 0);
|
||||
const int pwmB_abs = Abs(right_speed);
|
||||
DL_TimerA_setCaptureCompareValue(Motor_INST, pwmB_abs, GPIO_Motor_C1_IDX);
|
||||
}
|
||||
|
||||
void Motor::setSpeed(const int left_speed, const int right_speed) {
|
||||
setLeftSpeed(left_speed);
|
||||
setRightSpeed(right_speed);
|
||||
}
|
||||
|
||||
void Motor::setLeftDirection(const uint8_t direction) {
|
||||
if (direction) {
|
||||
DL_GPIO_setPins(MotorDirection_PORT, MotorDirection_AIN1_PIN);
|
||||
DL_GPIO_clearPins(MotorDirection_PORT, MotorDirection_AIN2_PIN);
|
||||
} else {
|
||||
DL_GPIO_setPins(MotorDirection_PORT, MotorDirection_AIN2_PIN);
|
||||
DL_GPIO_clearPins(MotorDirection_PORT, MotorDirection_AIN1_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
void Motor::setRightDirection(const uint8_t direction) {
|
||||
if (direction) {
|
||||
DL_GPIO_setPins(MotorDirection_PORT, MotorDirection_BIN1_PIN);
|
||||
DL_GPIO_clearPins(MotorDirection_PORT, MotorDirection_BIN2_PIN);
|
||||
} else {
|
||||
DL_GPIO_setPins(MotorDirection_PORT, MotorDirection_BIN2_PIN);
|
||||
DL_GPIO_clearPins(MotorDirection_PORT, MotorDirection_BIN1_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
void Motor::setDirection(const uint8_t left_direction, const uint8_t right_direction) {
|
||||
setLeftDirection(left_direction);
|
||||
setRightDirection(right_direction);
|
||||
}
|
||||
|
||||
void Motor::stopLeft() {
|
||||
setLeftSpeed(0);
|
||||
DL_GPIO_setPins(MotorDirection_PORT, MotorDirection_AIN1_PIN);
|
||||
DL_GPIO_setPins(MotorDirection_PORT, MotorDirection_AIN2_PIN);
|
||||
}
|
||||
|
||||
void Motor::stopRight() {
|
||||
setRightSpeed(0);
|
||||
DL_GPIO_setPins(MotorDirection_PORT, MotorDirection_BIN1_PIN);
|
||||
DL_GPIO_setPins(MotorDirection_PORT, MotorDirection_BIN2_PIN);
|
||||
}
|
||||
|
||||
void Motor::stop() {
|
||||
stopLeft();
|
||||
stopRight();
|
||||
}
|
||||
|
||||
int Motor::Abs(const int num) {
|
||||
return num < 0 ? -num : num; // 取绝对值
|
||||
}
|
||||
|
||||
|
||||
@ -1,270 +0,0 @@
|
||||
#include "../2025_include_user/Oled.hpp"
|
||||
|
||||
#define OLED_ADDR 0x3C // 7位地址(0x78 >> 1)
|
||||
|
||||
void OLED::WR_CMD(uint8_t cmd) {
|
||||
uint8_t temp[2];
|
||||
temp[0] = 0x00; // Control byte for command
|
||||
temp[1] = cmd;
|
||||
|
||||
DL_I2C_fillControllerTXFIFO(I2C_0_INST, temp, 2);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_ADDR, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
|
||||
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
|
||||
}
|
||||
|
||||
void OLED::WR_DATA(uint8_t data) {
|
||||
uint8_t temp[2];
|
||||
temp[0] = 0x40; // Control byte for data
|
||||
temp[1] = data;
|
||||
|
||||
DL_I2C_fillControllerTXFIFO(I2C_0_INST, temp, 2);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_ADDR, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
|
||||
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
|
||||
}
|
||||
|
||||
|
||||
void OLED::Init() {
|
||||
uint8_t CMD_Data[] = {
|
||||
0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40, 0xA1, 0xC8, 0xDA,
|
||||
0x12, 0x81, 0xCF, 0xD9, 0xF1, 0xDB, 0x40, 0xA4, 0xA6, 0x8D, 0x14,
|
||||
0xAF
|
||||
};
|
||||
|
||||
for (uint8_t i = 0; i < 23; i++) {
|
||||
WR_CMD(CMD_Data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void OLED::Clear() {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
WR_CMD(0xb0 + i); // 设置页地址(0~7)
|
||||
WR_CMD(0x00); // 设置显示位置—列低地址
|
||||
WR_CMD(0x10); // 设置显示位置—列高地址
|
||||
for (uint8_t n = 0; n < 128; n++) {
|
||||
WR_DATA(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OLED::Display_On() {
|
||||
WR_CMD(0x8D); // SET DCDC命令
|
||||
WR_CMD(0x14); // DCDC ON
|
||||
WR_CMD(0xAF); // DISPLAY ON, 打开显示
|
||||
}
|
||||
|
||||
void OLED::Display_Off() {
|
||||
WR_CMD(0x8D); // SET DCDC命令
|
||||
WR_CMD(0x10); // DCDC OFF
|
||||
WR_CMD(0xAE); // DISPLAY OFF,关闭显示
|
||||
}
|
||||
|
||||
void OLED::Set_Pos(uint8_t x, uint8_t y) {
|
||||
WR_CMD(0xb0 + y); // 设置页地址(0~7)
|
||||
WR_CMD(((x & 0xf0) >> 4) | 0x10); // 设置显示位置—列高地址
|
||||
WR_CMD(x & 0x0f); // 设置显示位置—列低地址
|
||||
}
|
||||
|
||||
unsigned int OLED::oled_pow(uint8_t m, uint8_t n) {
|
||||
unsigned int result = 1;
|
||||
while (n--) result *= m;
|
||||
return result;
|
||||
}
|
||||
|
||||
void OLED::ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size, uint8_t Color_Turn) {
|
||||
uint8_t c = chr - ' '; // 得到偏移后的值
|
||||
if (x > 128 - 1) { x = 0; y = y + 2; }
|
||||
if (Char_Size == 16) {
|
||||
Set_Pos(x, y);
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (Color_Turn)
|
||||
WR_DATA(~F8X16[c * 16 + i]);
|
||||
else
|
||||
WR_DATA(F8X16[c * 16 + i]);
|
||||
}
|
||||
Set_Pos(x, y + 1);
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (Color_Turn)
|
||||
WR_DATA(~F8X16[c * 16 + i + 8]);
|
||||
else
|
||||
WR_DATA(F8X16[c * 16 + i + 8]);
|
||||
}
|
||||
} else {
|
||||
Set_Pos(x, y);
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
if (Color_Turn)
|
||||
WR_DATA(~F6x8[c][i]);
|
||||
else
|
||||
WR_DATA(F6x8[c][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OLED::ShowString(uint8_t x, uint8_t y, char* chr, uint8_t Char_Size, uint8_t Color_Turn) {
|
||||
uint8_t j = 0;
|
||||
while (chr[j] != '\0') {
|
||||
ShowChar(x, y, chr[j], Char_Size, Color_Turn);
|
||||
if (Char_Size == 12) // 6X8的字体列加6,显示下一个字符
|
||||
x += 6;
|
||||
else // 8X16的字体列加8,显示下一个字符
|
||||
x += 8;
|
||||
|
||||
if (x > 122 && Char_Size == 12) // TextSize6x8如果一行不够显示了,从下一行继续显示
|
||||
{
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
if (x > 120 && Char_Size == 16) // TextSize8x16如果一行不够显示了,从下一行继续显示
|
||||
{
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void OLED::ShowNum(uint8_t x, uint8_t y, unsigned int num, uint8_t len, uint8_t size2, uint8_t Color_Turn) {
|
||||
uint8_t t, temp;
|
||||
uint8_t enshow = 0;
|
||||
for (t = 0; t < len; t++) {
|
||||
temp = (num / oled_pow(10, len - t - 1)) % 10;
|
||||
if (enshow == 0 && t < (len - 1)) {
|
||||
if (temp == 0) {
|
||||
ShowChar(x + (size2 / 2) * t, y, ' ', size2, Color_Turn);
|
||||
continue;
|
||||
} else enshow = 1;
|
||||
}
|
||||
ShowChar(x + (size2 / 2) * t, y, temp + '0', size2, Color_Turn);
|
||||
}
|
||||
}
|
||||
|
||||
void OLED::ShowDecimal(uint8_t x, uint8_t y, float num, uint8_t z_len, uint8_t f_len, uint8_t size2, uint8_t Color_Turn) {
|
||||
uint8_t t, temp, i = 0; // i为负数标志位
|
||||
uint8_t enshow;
|
||||
int z_temp, f_temp;
|
||||
if (num < 0) {
|
||||
z_len += 1;
|
||||
i = 1;
|
||||
num = -num;
|
||||
}
|
||||
z_temp = (int)num;
|
||||
// 整数部分
|
||||
for (t = 0; t < z_len; t++) {
|
||||
temp = (z_temp / oled_pow(10, z_len - t - 1)) % 10;
|
||||
if (enshow == 0 && t < (z_len - 1)) {
|
||||
if (temp == 0) {
|
||||
ShowChar(x + (size2 / 2) * t, y, ' ', size2, Color_Turn);
|
||||
continue;
|
||||
} else
|
||||
enshow = 1;
|
||||
}
|
||||
ShowChar(x + (size2 / 2) * t, y, temp + '0', size2, Color_Turn);
|
||||
}
|
||||
// 小数点
|
||||
ShowChar(x + (size2 / 2) * (z_len), y, '.', size2, Color_Turn);
|
||||
|
||||
f_temp = (int)((num - z_temp) * (oled_pow(10, f_len)));
|
||||
// 小数部分
|
||||
for (t = 0; t < f_len; t++) {
|
||||
temp = (f_temp / oled_pow(10, f_len - t - 1)) % 10;
|
||||
ShowChar(x + (size2 / 2) * (t + z_len) + 5, y, temp + '0', size2, Color_Turn);
|
||||
}
|
||||
if (i == 1) // 如果为负,就将最前的一位赋值‘-’
|
||||
{
|
||||
ShowChar(x, y, '-', size2, Color_Turn);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void OLED::ShowChinese(uint8_t x, uint8_t y, uint8_t no, uint8_t Color_Turn) {
|
||||
uint8_t t = 0;
|
||||
Set_Pos(x, y);
|
||||
for (t = 0; t < 16; t++) {
|
||||
if (Color_Turn)
|
||||
WR_DATA(~Hzk[2 * no][t]); // 显示汉字的上半部分
|
||||
else
|
||||
WR_DATA(Hzk[2 * no][t]); // 显示汉字的上半部分
|
||||
}
|
||||
|
||||
Set_Pos(x, y + 1);
|
||||
for (t = 0; t < 16; t++) {
|
||||
if (Color_Turn)
|
||||
WR_DATA(~Hzk[2 * no + 1][t]); // 显示汉字的上半部分
|
||||
else
|
||||
WR_DATA(Hzk[2 * no + 1][t]); // 显示汉字的上半部分
|
||||
}
|
||||
}
|
||||
|
||||
void OLED::DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t* BMP, uint8_t Color_Turn) {
|
||||
uint32_t j = 0;
|
||||
uint8_t x = 0, y = 0;
|
||||
|
||||
if (y1 % 8 == 0)
|
||||
y = y1 / 8;
|
||||
else
|
||||
y = y1 / 8 + 1;
|
||||
for (y = y0; y < y1; y++) {
|
||||
Set_Pos(x0, y);
|
||||
for (x = x0; x < x1; x++) {
|
||||
if (Color_Turn)
|
||||
WR_DATA(~BMP[j++]); // 显示反相图片
|
||||
else
|
||||
WR_DATA(BMP[j++]); // 显示图片
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OLED::HorizontalShift(uint8_t direction) {
|
||||
WR_CMD(0x2e); // 停止滚动
|
||||
WR_CMD(direction); // 设置滚动方向
|
||||
WR_CMD(0x00); // 虚拟字节设置,默认为0x00
|
||||
WR_CMD(0x00); // 设置开始页地址
|
||||
WR_CMD(0x07); // 设置每个滚动步骤之间的时间间隔的帧频
|
||||
WR_CMD(0x07); // 设置结束页地址
|
||||
WR_CMD(0x00); // 虚拟字节设置,默认为0x00
|
||||
WR_CMD(0xff); // 虚拟字节设置,默认为0xff
|
||||
WR_CMD(0x2f); // 开启滚动-0x2f,禁用滚动-0x2e,禁用需要重写数据
|
||||
}
|
||||
|
||||
void OLED::Some_HorizontalShift(uint8_t direction, uint8_t start, uint8_t end) {
|
||||
WR_CMD(0x2e); // 停止滚动
|
||||
WR_CMD(direction); // 设置滚动方向
|
||||
WR_CMD(0x00); // 虚拟字节设置,默认为0x00
|
||||
WR_CMD(start); // 设置开始页地址
|
||||
WR_CMD(0x07); // 设置每个滚动步骤之间的时间间隔的帧频
|
||||
WR_CMD(end); // 设置结束页地址
|
||||
WR_CMD(0x00); // 虚拟字节设置,默认为0x00
|
||||
WR_CMD(0xff); // 虚拟字节设置,默认为0xff
|
||||
WR_CMD(0x2f); // 开启滚动-0x2f,禁用滚动-0x2e,禁用需要重写数据
|
||||
}
|
||||
|
||||
void OLED::VerticalAndHorizontalShift(uint8_t direction) {
|
||||
WR_CMD(0x2e); // 停止滚动
|
||||
WR_CMD(direction); // 设置滚动方向
|
||||
WR_CMD(0x01); // 虚拟字节设置
|
||||
WR_CMD(0x00); // 设置开始页地址
|
||||
WR_CMD(0x07); // 设置每个滚动步骤之间的时间间隔的帧频
|
||||
WR_CMD(0x07); // 设置结束页地址
|
||||
WR_CMD(0x01); // 垂直滚动偏移量
|
||||
WR_CMD(0x00); // 虚拟字节设置,默认为0x00
|
||||
WR_CMD(0xff); // 虚拟字节设置,默认为0xff
|
||||
WR_CMD(0x2f); // 开启滚动-0x2f,禁用滚动-0x2e,禁用需要重写数据
|
||||
}
|
||||
|
||||
void OLED::DisplayMode(uint8_t mode) {
|
||||
WR_CMD(mode);
|
||||
}
|
||||
|
||||
void OLED::IntensityControl(uint8_t intensity) {
|
||||
WR_CMD(0x81);
|
||||
WR_CMD(intensity);
|
||||
}
|
||||
@ -1,230 +0,0 @@
|
||||
/*
|
||||
* OledFont.c
|
||||
*
|
||||
* Created on: Jul 24, 2022
|
||||
* Author: Unicorn_Li
|
||||
*/
|
||||
#include "../2025_include_user/OledFont.h"
|
||||
|
||||
//8*6 ASCII字符集点阵
|
||||
const unsigned char F6x8[][6] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
|
||||
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
|
||||
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
|
||||
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
|
||||
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
|
||||
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
|
||||
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
|
||||
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
|
||||
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
|
||||
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
|
||||
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
|
||||
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
|
||||
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
|
||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
|
||||
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
|
||||
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
|
||||
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
|
||||
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
|
||||
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
|
||||
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
|
||||
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
|
||||
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
|
||||
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
|
||||
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
|
||||
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
|
||||
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
|
||||
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
|
||||
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;
|
||||
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
|
||||
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
|
||||
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
|
||||
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
|
||||
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
|
||||
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
|
||||
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
|
||||
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
|
||||
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
|
||||
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
|
||||
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
|
||||
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
|
||||
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
|
||||
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
|
||||
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
|
||||
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
|
||||
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
|
||||
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
|
||||
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
|
||||
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
|
||||
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
|
||||
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
|
||||
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
|
||||
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
|
||||
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
|
||||
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
|
||||
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
|
||||
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
|
||||
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
|
||||
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
|
||||
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
|
||||
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
|
||||
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
|
||||
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
|
||||
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
|
||||
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
|
||||
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
|
||||
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
|
||||
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
|
||||
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
|
||||
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
|
||||
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
|
||||
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
|
||||
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
|
||||
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
|
||||
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
|
||||
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
|
||||
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
|
||||
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
|
||||
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
|
||||
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
|
||||
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
|
||||
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
|
||||
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
|
||||
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
|
||||
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
|
||||
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
|
||||
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
|
||||
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
|
||||
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
|
||||
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
|
||||
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
|
||||
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
|
||||
};
|
||||
|
||||
//16*8 ASCII字符集点阵
|
||||
const unsigned char F8X16[]=
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//sp /0
|
||||
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! /1
|
||||
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" /2
|
||||
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# /3
|
||||
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ /4
|
||||
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% /5
|
||||
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& /6
|
||||
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' /7
|
||||
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( /8
|
||||
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) /9
|
||||
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* /10
|
||||
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ /11
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, /12
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- /13
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. /14
|
||||
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// /15
|
||||
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 /16
|
||||
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 /17
|
||||
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 /18
|
||||
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 /19
|
||||
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 /20
|
||||
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 /21
|
||||
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 /22
|
||||
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 /23
|
||||
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 /24
|
||||
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 /25
|
||||
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: /26
|
||||
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; /27
|
||||
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< /28
|
||||
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= /29
|
||||
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> /30
|
||||
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? /31
|
||||
0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ /32
|
||||
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A /33
|
||||
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B /34
|
||||
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C /35
|
||||
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D /36
|
||||
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E /37
|
||||
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F /38
|
||||
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G /39
|
||||
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H /40
|
||||
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I /41
|
||||
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J /42
|
||||
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K /43
|
||||
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L /44
|
||||
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M /45
|
||||
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N /46
|
||||
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O /47
|
||||
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P /48
|
||||
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q /49
|
||||
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R /50
|
||||
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S /51
|
||||
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T /52
|
||||
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U /53
|
||||
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V /54
|
||||
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W /55
|
||||
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X /56
|
||||
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y /57
|
||||
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z /58
|
||||
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ /59
|
||||
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ /60
|
||||
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] /61
|
||||
0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ /62
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ /63
|
||||
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` /64
|
||||
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a /65
|
||||
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b /66
|
||||
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c /67
|
||||
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d /68
|
||||
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e /69
|
||||
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f /70
|
||||
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g /71
|
||||
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h /72
|
||||
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i /73
|
||||
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j /74
|
||||
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k /75
|
||||
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l /76
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m /77
|
||||
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n /78
|
||||
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o /79
|
||||
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p /80
|
||||
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q /81
|
||||
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r /82
|
||||
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s /83
|
||||
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t /84
|
||||
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u /85
|
||||
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v /86
|
||||
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w /87
|
||||
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x /88
|
||||
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y /89
|
||||
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z /90
|
||||
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ /91
|
||||
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} /92
|
||||
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00};//| /93
|
||||
|
||||
//部分汉字 阴码,列行式,逆向
|
||||
const unsigned char Hzk[][32]=
|
||||
{
|
||||
{0x40,0x22,0x14,0x08,0xF4,0x02,0x00,0xF8,0x08,0x08,0xFF,0x08,0x08,0xF8,0x00,0x00},
|
||||
{0x08,0x44,0x82,0x41,0x3F,0x00,0x20,0x63,0x21,0x21,0x3F,0x21,0x29,0x33,0x60,0x00},/*"独",0*/
|
||||
{0x20,0x10,0xE8,0x24,0x27,0x24,0x24,0xE4,0x24,0x34,0x2C,0x20,0xE0,0x00,0x00,0x00},
|
||||
{0x80,0x60,0x1F,0x09,0x09,0x09,0x09,0x7F,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00},/*"角",1*/
|
||||
{0x00,0x00,0x7C,0x54,0x55,0x56,0x54,0x7C,0x54,0x56,0x55,0x54,0x7C,0x00,0x00,0x00},
|
||||
{0x01,0x01,0x01,0xFD,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0xFD,0x01,0x01,0x01,0x00},/*"兽",2*/
|
||||
|
||||
|
||||
|
||||
};
|
||||
//128*64图片
|
||||
unsigned char BMP1[]={
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x40,0xE0,0xE0,0x60,
|
||||
0x00,0x40,0x80,0x00,0x00,0x00,0x80,0x80,0x60,0x60,0x10,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x90,0xB2,0x66,0x6E,0xEC,0xC9,0x83,0x02,0x00,0x40,0x80,
|
||||
0x00,0x0C,0x0C,0x01,0x03,0x07,0x0F,0x11,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x08,0x18,0x3B,0x37,0x66,0xEE,0xEE,0xCC,0x88,0x80,0x00,0x00,
|
||||
0x01,0x02,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x0F,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x3E,0x40,0x40,0x40,0x3E,0x00,0x7E,0x04,0x08,0x10,0x7E,0x00,0x7E,0x00,0x3C,
|
||||
0x42,0x42,0x42,0x42,0x00,0x7E,0x42,0x42,0x42,0x7E,0x00,0x7E,0x04,0x08,0x10,0x7E,/*"C:\Users\HP\Desktop\UNICORN.BMP",0*/
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -1,299 +0,0 @@
|
||||
#include "../2025_include_user/OledMenuDriver.h"
|
||||
|
||||
#define OLED_I2C_ADDR (0x3C) // 7-bit地址,不需要 <<1
|
||||
#define SYSTEM_CORE_CLOCK_HZ 80000000U
|
||||
|
||||
u8g2_t MenuDriver::u8g2 = {};
|
||||
|
||||
uint8_t u8x8_gpio_and_delay_mspm0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8X8_MSG_GPIO_AND_DELAY_INIT:
|
||||
delay_cycles(32000); //1ms
|
||||
break;
|
||||
case U8X8_MSG_DELAY_MILLI:
|
||||
for (uint8_t i = 0; i < arg_int; i++) {
|
||||
delay_cycles(32000);
|
||||
}
|
||||
|
||||
break;
|
||||
case U8X8_MSG_GPIO_DC:
|
||||
break;
|
||||
case U8X8_MSG_GPIO_RESET: /**
|
||||
if (arg_int)
|
||||
{
|
||||
DL_GPIO_setPins(GPIO_OLED_PORT, GPIO_OLED_RST_OLED_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
DL_GPIO_clearPins(GPIO_OLED_PORT, GPIO_OLED_RST_OLED_PIN);
|
||||
}**/
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t u8x8_byte_mspm0_hw_i2c(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
|
||||
/* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
|
||||
/* add extra byte for the i2c address */
|
||||
static uint8_t buffer[34];
|
||||
static volatile uint8_t buf_idx, g_u8TxCount;
|
||||
uint8_t *data;
|
||||
switch (msg) {
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *) arg_ptr;
|
||||
while (arg_int > 0) {
|
||||
buffer[buf_idx++] = *data;
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
/* add your custom code to init i2c subsystem */
|
||||
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
/* ignored for i2c */
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
buf_idx = 0;
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
/*
|
||||
* Fill FIFO with data.
|
||||
*/
|
||||
g_u8TxCount = DL_I2C_fillControllerTXFIFO(I2C_0_INST, &buffer[0], buf_idx);
|
||||
|
||||
/* Wait for I2C to be Idle */
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
/* Send the packet to the controller.
|
||||
* This function will send Start + Stop automatically.
|
||||
*/
|
||||
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_I2C_ADDR,
|
||||
DL_I2C_CONTROLLER_DIRECTION_TX, buf_idx);
|
||||
|
||||
while (g_u8TxCount < buf_idx) {
|
||||
while (DL_I2C_isControllerTXFIFOFull(I2C_0_INST) == true);
|
||||
DL_I2C_transmitControllerData(I2C_0_INST, buffer[g_u8TxCount]);
|
||||
g_u8TxCount++;
|
||||
}
|
||||
|
||||
/* Poll until the Controller writes all bytes */
|
||||
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||||
|
||||
/* Trap if there was an error */
|
||||
if (DL_I2C_getControllerStatus(I2C_0_INST) &
|
||||
DL_I2C_CONTROLLER_STATUS_ERROR) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Wait for I2C to be Idle */
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MenuDriver::oled_init() {
|
||||
u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_mspm0_hw_i2c, u8x8_gpio_and_delay_mspm0);
|
||||
u8g2_InitDisplay(&u8g2);
|
||||
u8g2_SetPowerSave(&u8g2, 0);
|
||||
u8g2_ClearBuffer(&u8g2);
|
||||
}
|
||||
|
||||
void MenuDriver::ssd1306_transmit_cmd(uint8_t cmd) {
|
||||
uint8_t temp[2] = {0x00, cmd};
|
||||
|
||||
DL_I2C_fillControllerTXFIFO(I2C_0_INST, temp, 2);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
|
||||
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
|
||||
}
|
||||
|
||||
void MenuDriver::ssd1306_transmit_data(uint8_t data, const uint8_t mode) {
|
||||
if (!mode)
|
||||
data = ~data;
|
||||
uint8_t temp[2] = {0x40, data};
|
||||
|
||||
DL_I2C_fillControllerTXFIFO(I2C_0_INST, temp, 2);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
|
||||
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
|
||||
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
|
||||
}
|
||||
|
||||
void MenuDriver::ssd1306_set_cursor(unsigned char _x, unsigned char _y) {
|
||||
ssd1306_transmit_cmd(0xB0 | _y);
|
||||
ssd1306_transmit_cmd(0x10 | ((_x & 0xF0) >> 4));
|
||||
ssd1306_transmit_cmd(0x00 | (_x & 0x0F));
|
||||
}
|
||||
|
||||
void MenuDriver::ssd1306_fill(unsigned char _data) {
|
||||
for (uint8_t page = 0; page < 8; ++page) {
|
||||
ssd1306_set_cursor(0, page);
|
||||
for (uint8_t col = 0; col < 128; ++col) {
|
||||
ssd1306_transmit_data(_data, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MenuDriver::screenOn() {
|
||||
ssd1306_transmit_cmd(0X8D);
|
||||
ssd1306_transmit_cmd(0X14);
|
||||
ssd1306_transmit_cmd(0XAF);
|
||||
}
|
||||
|
||||
void MenuDriver::screenOff() {
|
||||
ssd1306_transmit_cmd(0X8D);
|
||||
ssd1306_transmit_cmd(0X10);
|
||||
ssd1306_transmit_cmd(0XAE);
|
||||
}
|
||||
|
||||
void *MenuDriver::getCanvasBuffer() {
|
||||
return u8g2_GetBufferPtr(&u8g2);
|
||||
}
|
||||
|
||||
uint8_t MenuDriver::getBufferTileHeight() {
|
||||
return u8g2_GetBufferTileHeight(&u8g2);
|
||||
}
|
||||
|
||||
uint8_t MenuDriver::getBufferTileWidth() {
|
||||
return u8g2_GetBufferTileWidth(&u8g2);
|
||||
}
|
||||
|
||||
void MenuDriver::canvasUpdate() {
|
||||
u8g2_SendBuffer(&u8g2);
|
||||
}
|
||||
|
||||
void MenuDriver::canvasClear() {
|
||||
u8g2_ClearBuffer(&u8g2);
|
||||
}
|
||||
|
||||
void MenuDriver::setFont(const uint8_t *_font) {
|
||||
u8g2_SetFontMode(&u8g2, 1);
|
||||
u8g2_SetFontDirection(&u8g2, 0);
|
||||
u8g2_SetFont(&u8g2, _font);
|
||||
}
|
||||
|
||||
void MenuDriver::setFont(const uint8_t *_font, uint8_t _font_mode, uint8_t _font_direction) {
|
||||
u8g2_SetFontMode(&u8g2, _font_mode);
|
||||
u8g2_SetFontDirection(&u8g2, _font_direction);
|
||||
u8g2_SetFont(&u8g2, _font);
|
||||
}
|
||||
|
||||
uint8_t MenuDriver::getFontWidth(const char *_text) {
|
||||
return u8g2_GetUTF8Width(&u8g2, _text);
|
||||
}
|
||||
|
||||
uint8_t MenuDriver::getFontHeight() {
|
||||
return u8g2_GetMaxCharHeight(&u8g2);
|
||||
}
|
||||
|
||||
void MenuDriver::setDrawType(uint8_t _type) {
|
||||
u8g2_SetDrawColor(&u8g2, _type);
|
||||
}
|
||||
|
||||
void MenuDriver::drawPixel(float _x, float _y) {
|
||||
u8g2_DrawPixel(&u8g2, (int16_t) round(_x), (int16_t) round(_y));
|
||||
}
|
||||
|
||||
void MenuDriver::draw(float _x, float _y, const char *_text) {
|
||||
setFont(u8g2_font_wqy14_t_chinese3);
|
||||
u8g2_DrawUTF8(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||||
}
|
||||
|
||||
void MenuDriver::draw(float _x, float _y, const char *_text, uint8_t _font_mode, uint8_t _font_direction) {
|
||||
setFont(u8g2_font_wqy14_t_chinese3, _font_mode, _font_direction);
|
||||
u8g2_DrawUTF8(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||||
}
|
||||
|
||||
void MenuDriver::draw(float _x, float _y, const char *_text, const uint8_t *_font, uint8_t _font_mode,
|
||||
uint8_t _font_direction) {
|
||||
setFont(_font, _font_mode, _font_direction);
|
||||
u8g2_DrawUTF8(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||||
}
|
||||
|
||||
void MenuDriver::drawEnglish(float _x, float _y, const char *_text) {
|
||||
setFont(u8g2_font_wqy14_t_chinese3);
|
||||
u8g2_DrawStr(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||||
}
|
||||
|
||||
void MenuDriver::drawChinese(float _x, float _y, const char *_text) {
|
||||
setFont(u8g2_font_wqy14_t_chinese3);
|
||||
u8g2_DrawUTF8(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||||
}
|
||||
|
||||
void MenuDriver::drawVDottedLine(float _x, float _y, float _h) {
|
||||
for (unsigned char i = 0; i < (unsigned char) round(_h); i++) {
|
||||
if (i % 8 == 0 || (i - 1) % 8 == 0 || (i - 2) % 8 == 0)
|
||||
continue;
|
||||
u8g2_DrawPixel(&u8g2, (int16_t) round(_x), (int16_t) round(_y) + i);
|
||||
}
|
||||
}
|
||||
|
||||
void MenuDriver::drawHDottedLine(float _x, float _y, float _l) {
|
||||
for (unsigned char i = 0; i < _l; i++) {
|
||||
if (i % 8 == 0 || (i - 1) % 8 == 0 || (i - 2) % 8 == 0)
|
||||
continue;
|
||||
u8g2_DrawPixel(&u8g2, (int16_t) round(_x) + i, (int16_t) round(_y));
|
||||
}
|
||||
}
|
||||
|
||||
void MenuDriver::drawVLine(float _x, float _y, float _h) {
|
||||
u8g2_DrawVLine(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_h));
|
||||
}
|
||||
|
||||
void MenuDriver::drawHLine(float _x, float _y, float _l) {
|
||||
u8g2_DrawHLine(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_l));
|
||||
}
|
||||
|
||||
void MenuDriver::drawBMP(float _x, float _y, float _w, float _h, const uint8_t *_bitMap) {
|
||||
u8g2_DrawXBMP(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h), _bitMap);
|
||||
}
|
||||
|
||||
void MenuDriver::drawBox(float _x, float _y, float _w, float _h) {
|
||||
u8g2_DrawBox(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h));
|
||||
}
|
||||
|
||||
void MenuDriver::drawRBox(float _x, float _y, float _w, float _h, float _r) {
|
||||
u8g2_DrawRBox(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h),
|
||||
(int16_t) round(_r));
|
||||
}
|
||||
|
||||
void MenuDriver::drawFrame(float _x, float _y, float _w, float _h) {
|
||||
u8g2_DrawFrame(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h));
|
||||
}
|
||||
|
||||
void MenuDriver::drawRFrame(float _x, float _y, float _w, float _h, float _r) {
|
||||
u8g2_DrawRFrame(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h),
|
||||
(int16_t) round(_r));
|
||||
}
|
||||
|
||||
void MenuDriver::drawCheckMark(float x, float y, float w, float h) {
|
||||
float x0 = x + w * 0.1f;
|
||||
float y0 = y + h * 0.5f;
|
||||
|
||||
float x1 = x + w * 0.4f;
|
||||
float y1 = y + h * 0.8f;
|
||||
|
||||
float x2 = x + w * 0.9f;
|
||||
float y2 = y + h * 0.2f;
|
||||
|
||||
u8g2_DrawLine(&u8g2, (int16_t) round(x0), (int16_t) round(y0), (int16_t) round(x1), (int16_t) round(y1));
|
||||
u8g2_DrawLine(&u8g2, (int16_t) round(x1), (int16_t) round(y1), (int16_t) round(x2), (int16_t) round(y2));
|
||||
}
|
||||
@ -1,102 +0,0 @@
|
||||
#include "OledMenuDriver.h"
|
||||
#include "OledMenuPaint.h"
|
||||
#include "../2025_include_user/OledMenuConfig.h"
|
||||
|
||||
const MenuPaint::Menu *MenuPaint::currentMenu = nullptr;
|
||||
uint8_t MenuPaint::currentMenuSize = 0;
|
||||
int8_t MenuPaint::selectIndex = 0;
|
||||
int8_t MenuPaint::scrollOffset = 0;
|
||||
bool MenuPaint::switchStates[20] = {0};
|
||||
const MenuPaint::Menu *MenuPaint::menuStack[5] = {nullptr};
|
||||
uint8_t MenuPaint::stackIndex = 0;
|
||||
|
||||
void MenuPaint::Init() {
|
||||
currentMenu = menuRoot;
|
||||
currentMenuSize = sizeof(menuRoot) / sizeof(Menu);
|
||||
selectIndex = 0;
|
||||
scrollOffset = 0;
|
||||
}
|
||||
|
||||
void MenuPaint::Paint() {
|
||||
MenuDriver::canvasClear();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int itemIndex = scrollOffset + i;
|
||||
if (itemIndex >= currentMenuSize) break;
|
||||
|
||||
const Menu &item = currentMenu[itemIndex];
|
||||
|
||||
bool selected = (itemIndex == selectIndex);
|
||||
bool checked = false;
|
||||
|
||||
if (item.type == MENU_TYPE_SWITCH) {
|
||||
checked = switchStates[item.switchId];
|
||||
}
|
||||
|
||||
RenderItem(16 * i, item.name, selected, checked);
|
||||
}
|
||||
|
||||
MenuDriver::canvasUpdate();
|
||||
}
|
||||
|
||||
void MenuPaint::RenderItem(int y, const char *text, bool selected, bool checked) {
|
||||
MenuDriver::drawChinese(0, y + 12, text);
|
||||
|
||||
if (selected) {
|
||||
MenuDriver::drawFrame(0, y, 128, 16);
|
||||
}
|
||||
|
||||
if (checked) {
|
||||
MenuDriver::drawCheckMark(128 - 12, y + 2, 10, 10);
|
||||
}
|
||||
}
|
||||
|
||||
void MenuPaint::ScrollUp() {
|
||||
if (selectIndex > 0) {
|
||||
selectIndex--;
|
||||
if (selectIndex < scrollOffset) scrollOffset--;
|
||||
Paint();
|
||||
}
|
||||
}
|
||||
|
||||
void MenuPaint::ScrollDown() {
|
||||
if (selectIndex < currentMenuSize - 1) {
|
||||
selectIndex++;
|
||||
if (selectIndex >= scrollOffset + 4) scrollOffset++;
|
||||
Paint();
|
||||
}
|
||||
}
|
||||
|
||||
void MenuPaint::Enter() {
|
||||
const Menu &item = currentMenu[selectIndex];
|
||||
if (item.type == MENU_TYPE_FOLDER && item.subMenus != nullptr) {
|
||||
if (stackIndex < 5) {
|
||||
menuStack[stackIndex++] = currentMenu;
|
||||
}
|
||||
currentMenu = item.subMenus;
|
||||
currentMenuSize = item.subMenuCount;
|
||||
selectIndex = 0;
|
||||
scrollOffset = 0;
|
||||
Paint();
|
||||
} else if (item.type == MENU_TYPE_SWITCH) {
|
||||
if (item.switchId < sizeof(switchStates)) {
|
||||
switchStates[item.switchId] = !switchStates[item.switchId];
|
||||
}
|
||||
Paint();
|
||||
}
|
||||
}
|
||||
|
||||
void MenuPaint::Exit() {
|
||||
if (stackIndex > 0) {
|
||||
currentMenu = menuStack[--stackIndex];
|
||||
currentMenuSize = sizeof(menuRoot) / sizeof(Menu); // 示例只返回一级
|
||||
selectIndex = 0;
|
||||
scrollOffset = 0;
|
||||
Paint();
|
||||
}
|
||||
}
|
||||
|
||||
bool MenuPaint::GetSwitchState(uint8_t switchId) {
|
||||
if (switchId >= sizeof(switchStates)) return false;
|
||||
return switchStates[switchId];
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
#include "../2025_include_user/Potentiometer.h"
|
||||
@ -1,28 +0,0 @@
|
||||
#include "../2025_include_user/Print.h"
|
||||
|
||||
void Print_init() {
|
||||
NVIC_ClearPendingIRQ(PRINTF_INST_INT_IRQN);
|
||||
NVIC_EnableIRQ(PRINTF_INST_INT_IRQN);
|
||||
}
|
||||
|
||||
// 串口发送单字节
|
||||
void print_char(char ch) {
|
||||
DL_UART_Main_transmitDataBlocking(PRINTF_INST, (uint8_t)ch);
|
||||
}
|
||||
|
||||
// 字符串输出
|
||||
void print_str(const char *str) {
|
||||
while (*str) {
|
||||
print_char(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义格式化输出
|
||||
void print(const char *format, ...) {
|
||||
char buffer[128]; // 注意大小,防止栈溢出
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(buffer, sizeof(buffer), format, args);
|
||||
va_end(args);
|
||||
print_str(buffer);
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
#include "../2025_include_user/Servo.h"
|
||||
|
||||
void Servo::SetUpAngle(const float angle) {
|
||||
float pulse = ( (float)angle / 180.0f ) * 1000.0f + 250.0f;
|
||||
DL_TimerG_setCaptureCompareValue(Servo_INST, (uint32_t)pulse, GPIO_Servo_C0_IDX);
|
||||
}
|
||||
|
||||
|
||||
void Servo::SetDownAngle(const float angle) {
|
||||
float pulse = ( (float)angle / 270.0f ) * 1000.0f + 250.0f;
|
||||
DL_TimerG_setCaptureCompareValue(Servo_INST, (uint32_t)pulse, GPIO_Servo_C1_IDX);
|
||||
}
|
||||
@ -1,136 +0,0 @@
|
||||
#include "../2025_include_user/Stepmotor.h"
|
||||
|
||||
uint8_t StepMotor::_buffer = 0;
|
||||
StepMotor::Data StepMotor::_data = {};
|
||||
static uint8_t frame_index = 0;
|
||||
static uint8_t frame_buffer[9];
|
||||
|
||||
extern "C" void Stepmotor_INST_IRQHandler(void) {
|
||||
switch (DL_UART_getPendingInterrupt(Stepmotor_INST)) {
|
||||
case DL_UART_IIDX_RX:
|
||||
StepMotor::_buffer = DL_UART_Main_receiveData(Stepmotor_INST);
|
||||
StepMotor::inject();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NVIC_ClearPendingIRQ(Stepmotor_INST_INT_IRQN);
|
||||
DL_UART_enableInterrupt(Stepmotor_INST, DL_UART_INTERRUPT_RX); // 启用接收中断
|
||||
}
|
||||
|
||||
void StepMotor::init() {
|
||||
NVIC_ClearPendingIRQ(Stepmotor_INST_INT_IRQN);
|
||||
NVIC_EnableIRQ(Stepmotor_INST_INT_IRQN);
|
||||
DL_UART_enable(Stepmotor_INST); // 启用 UART 模块
|
||||
DL_UART_enableInterrupt(Stepmotor_INST, DL_UART_INTERRUPT_RX); // 启用接收中断
|
||||
}
|
||||
|
||||
void StepMotor::inject() {
|
||||
frame_buffer[frame_index++] = _buffer;
|
||||
|
||||
if (frame_index >= 9) {
|
||||
// 校验BCC
|
||||
uint8_t bcc = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
bcc ^= frame_buffer[i];
|
||||
}
|
||||
|
||||
if (bcc == frame_buffer[8]) {
|
||||
// BCC校验通过,解析数据存储到ttl_data
|
||||
_data.address = frame_buffer[0];
|
||||
_data.flag = frame_buffer[1];
|
||||
_data.speed = (frame_buffer[2] << 8) | frame_buffer[3];
|
||||
uint32_t position_raw = (frame_buffer[4] << 24) | (frame_buffer[5] << 16) | (frame_buffer[6] << 8) | frame_buffer[7];
|
||||
|
||||
// 位置数据处理为有符号值(高位为符号位)
|
||||
if (position_raw & 0x80000000) {
|
||||
_data.position = (int32_t)(position_raw | 0xFFFFFFFF00000000);
|
||||
} else {
|
||||
_data.position = (int32_t)position_raw;
|
||||
}
|
||||
|
||||
_data.bcc = frame_buffer[8];
|
||||
}
|
||||
|
||||
// 无论校验是否通过,都重置frame_index,准备接收下一帧
|
||||
frame_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void StepMotor::transmit_command(const uint8_t *cmd) {
|
||||
for (uint8_t i = 0; i < FRAME_LENGTH; i++) {
|
||||
DL_UART_Main_transmitDataBlocking(Stepmotor_INST, cmd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 通用编码函数
|
||||
void StepMotor::encode_frame(const StepMotor::ControlMode mode, const uint8_t direction, const uint8_t subdivide,
|
||||
const float angle_deg, const uint16_t torque_mA, const float absolute_angle_deg,
|
||||
const float speed_rad_s, uint8_t *frame_buffer) {
|
||||
uint16_t angle_or_current = 0;
|
||||
uint16_t speed = (uint16_t) (speed_rad_s * 10); // 转速 *10 放大
|
||||
|
||||
frame_buffer[0] = 0x7B; // 帧头
|
||||
frame_buffer[1] = 0x01; // 控制ID
|
||||
frame_buffer[2] = mode; // 控制模式
|
||||
frame_buffer[3] = direction; // 方向
|
||||
frame_buffer[4] = subdivide; // 细分
|
||||
|
||||
if (mode == StepMotor::POSITION_MODE) {
|
||||
angle_or_current = (uint16_t) (angle_deg * 10); // 角度 *10 放大
|
||||
} else if (mode != StepMotor::TORQUE_MODE) {
|
||||
angle_or_current = torque_mA; // 电流mA
|
||||
} else if (mode == StepMotor::ABSOLUTE_ANGLE_MODE) {
|
||||
angle_or_current = (uint16_t) (absolute_angle_deg * 10); // 角度 *10 放大
|
||||
} else {
|
||||
angle_or_current = 0; // 速度模式时为0
|
||||
}
|
||||
|
||||
frame_buffer[5] = (angle_or_current >> 8) & 0xFF;
|
||||
frame_buffer[6] = angle_or_current & 0xFF;
|
||||
|
||||
frame_buffer[7] = (speed >> 8) & 0xFF;
|
||||
frame_buffer[8] = speed & 0xFF;
|
||||
|
||||
uint8_t bcc = 0;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
bcc ^= frame_buffer[i];
|
||||
}
|
||||
frame_buffer[9] = bcc;
|
||||
|
||||
frame_buffer[10] = 0x7D; // 帧尾
|
||||
}
|
||||
|
||||
void StepMotor::setSpeed(uint8_t direction, uint8_t subdivide, float speed_rad_s) {
|
||||
uint8_t frame[FRAME_LENGTH];
|
||||
encode_frame(SPEED_MODE, direction, subdivide, 0, 0, 0, speed_rad_s, frame);
|
||||
transmit_command(frame);
|
||||
}
|
||||
|
||||
void StepMotor::setPosition(uint8_t direction, uint8_t subdivide, float angle_deg, float speed_rad_s) {
|
||||
uint8_t frame[FRAME_LENGTH];
|
||||
encode_frame(POSITION_MODE, direction, subdivide, angle_deg, 0, 0, speed_rad_s, frame);
|
||||
transmit_command(frame);
|
||||
}
|
||||
|
||||
void StepMotor::setTorque(uint8_t direction, uint8_t subdivide, uint16_t torque_mA, float speed_rad_s) {
|
||||
uint8_t frame[FRAME_LENGTH];
|
||||
encode_frame(TORQUE_MODE, direction, subdivide, 0, torque_mA, 0, speed_rad_s, frame);
|
||||
transmit_command(frame);
|
||||
}
|
||||
|
||||
void StepMotor::setAbsoluteAngle(uint8_t direction, uint8_t subdivide, float absolute_angle_deg, float speed_rad_s) {
|
||||
uint8_t frame[FRAME_LENGTH];
|
||||
encode_frame(ABSOLUTE_ANGLE_MODE, direction, subdivide, 0, 0, absolute_angle_deg, speed_rad_s, frame);
|
||||
transmit_command(frame);
|
||||
}
|
||||
|
||||
uint16_t StepMotor::getSpeed() {
|
||||
return _data.speed;
|
||||
}
|
||||
|
||||
uint32_t StepMotor::getPosition() {
|
||||
return _data.position;
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
#include "../2025_include_user/TrackerGpio.h"
|
||||
|
||||
TrackerGpio::Data TrackerGpio::_data;
|
||||
|
||||
void TrackerGpio::init() {}
|
||||
|
||||
void TrackerGpio::inject() {}
|
||||
|
||||
TrackerGpio::Data TrackerGpio::getData() {
|
||||
TrackerGpio::Data data = {};
|
||||
data.data[0] = DL_GPIO_readPins(Tracker_PORT, Tracker_Track1_PIN) == 0;
|
||||
data.data[1] = DL_GPIO_readPins(Tracker_PORT, Tracker_Track2_PIN) == 0;
|
||||
data.data[2] = DL_GPIO_readPins(Tracker_PORT, Tracker_Track3_PIN) == 0;
|
||||
data.data[3] = DL_GPIO_readPins(Tracker_PORT, Tracker_Track4_PIN) == 0;
|
||||
data.data[4] = DL_GPIO_readPins(Tracker_PORT, Tracker_Track5_PIN) == 0;
|
||||
data.data[5] = DL_GPIO_readPins(Tracker_PORT, Tracker_Track6_PIN) == 0;
|
||||
data.data[6] = DL_GPIO_readPins(Tracker_PORT, Tracker_Track7_PIN) == 0;
|
||||
return data;
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
#include "TrackerMpu.h"
|
||||
|
||||
#include <../2025_include_user/Print.h>
|
||||
|
||||
#define TRACKER_ADDR 0x12
|
||||
#define TRACKER_DATA_ADDR 0x30
|
||||
|
||||
uint8_t TrackerMpu::_buffer = 0x00;
|
||||
TrackerMpu::Data TrackerMpu::_data;
|
||||
|
||||
void WriteByte(const uint8_t addr, const uint8_t dat) {
|
||||
uint8_t temp[2];
|
||||
temp[0] = addr;
|
||||
temp[1] = dat;
|
||||
|
||||
DL_I2C_fillControllerTXFIFO(I2C_1_INST, temp, 2);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
|
||||
|
||||
DL_I2C_startControllerTransfer(I2C_1_INST, 0x12, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
|
||||
while (DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
|
||||
while (!(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
|
||||
DL_I2C_flushControllerTXFIFO(I2C_1_INST);
|
||||
}
|
||||
|
||||
uint8_t ReadByte(const uint8_t addr) {
|
||||
uint8_t data;
|
||||
|
||||
DL_I2C_fillControllerTXFIFO(I2C_1_INST, &addr, 1);
|
||||
|
||||
DL_I2C_disableInterrupt(I2C_1_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
|
||||
|
||||
while (!(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
DL_I2C_startControllerTransfer(I2C_1_INST, 0x12, DL_I2C_CONTROLLER_DIRECTION_TX, 1);
|
||||
while (DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
// DL_I2C_flushControllerTXFIFO(I2C_1_INST);
|
||||
|
||||
DL_I2C_startControllerTransfer(I2C_1_INST, 0x12, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
|
||||
while (DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||||
while (!(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||||
data = DL_I2C_receiveControllerData(I2C_1_INST);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void TrackerMpu::init() {}
|
||||
|
||||
void TrackerMpu::inject() {
|
||||
WriteByte(0x01, 1);
|
||||
WriteByte(0x01, 0);
|
||||
TrackerMpu::_buffer = ReadByte(0x30);
|
||||
// print("Raw: %u (0x%02X)\n", _buffer, _buffer);
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
TrackerMpu::_data.data[i] = (TrackerMpu::_buffer >> (7 - i)) & 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
TrackerMpu::Data TrackerMpu::getData() {
|
||||
TrackerMpu::inject();
|
||||
return TrackerMpu::_data;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
#include "../2025_include_user/Ultrasonic.h"
|
||||
Loading…
x
Reference in New Issue
Block a user