4 files modified
7 files deleted
1 files renamed
31 files added
| | |
| | | "version": "2.0.0", |
| | | "tasks": [ |
| | | { |
| | | "label": "STM32: Flash via ST-Link(SWD)", |
| | | "label": "STM32: Flash via ST-Link (SWD)", |
| | | "type": "shell", |
| | | "command": "D:\\Program Files\\ST\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI.exe", |
| | | "command": "cube", |
| | | "args": [ |
| | | "-c port=SWD", |
| | | "-e all", |
| | | "-w", |
| | | "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "0x08000000", |
| | | "-v", |
| | | "programmer", |
| | | "-c", "port=SWD", "freq=4000", "reset=HWrst", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "-rst" |
| | | ], |
| | | "group": { |
| | | "kind": "build", |
| | | "isDefault": false |
| | | }, |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | |
| | | } |
| | | }, |
| | | { |
| | | "label": "STM32: Flash via stm32flash(UART)", |
| | | "label": "STM32: Flash via Serial (UART)", |
| | | "type": "shell", |
| | | "command": "${workspaceFolder}/.vscode/stm32flash.bat", |
| | | "command": "cube", |
| | | "args": [ |
| | | "${input:comPort}" |
| | | "programmer", |
| | | "--connect", "port=${input:comPort}", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf" |
| | | ], |
| | | "options": { |
| | | "env": { |
| | | "PATH": "${env:PATH}", |
| | | "SystemRoot": "${env:SystemRoot}", |
| | | "GCC_BIN": "${env:LOCALAPPDATA}\\stm32cube\\bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin", |
| | | "ELF": "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "BIN": "${workspaceFolder}\\build\\Release\\ISKBoard.bin", |
| | | "FLASH_EXE": "${workspaceFolder}\\.vscode\\stm32flash.exe" |
| | | } |
| | | }, |
| | | "group": { |
| | | "kind": "build", |
| | | "isDefault": false |
| | | }, |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | |
| | | "default": "COM22" |
| | | } |
| | | ] |
| | | } |
| | | } |
| | |
| | | "version": "2.0.0", |
| | | "tasks": [ |
| | | { |
| | | "label": "STM32: Flash via ST-Link(SWD)", |
| | | "label": "STM32: Flash via ST-Link (SWD)", |
| | | "type": "shell", |
| | | "command": "D:\\Program Files\\ST\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI.exe", |
| | | "command": "cube", |
| | | "args": [ |
| | | "-c port=SWD", |
| | | "-e all", |
| | | "-w", |
| | | "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "0x08000000", |
| | | "-v", |
| | | "programmer", |
| | | "-c", "port=SWD", "freq=4000", "reset=HWrst", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "-rst" |
| | | ], |
| | | "group": { |
| | | "kind": "build", |
| | | "isDefault": false |
| | | }, |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | |
| | | } |
| | | }, |
| | | { |
| | | "label": "STM32: Flash via stm32flash(UART)", |
| | | "label": "STM32: Flash via Serial (UART)", |
| | | "type": "shell", |
| | | "command": "${workspaceFolder}/.vscode/stm32flash.bat", |
| | | "command": "cube", |
| | | "args": [ |
| | | "${input:comPort}" |
| | | "programmer", |
| | | "--connect", "port=${input:comPort}", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf" |
| | | ], |
| | | "options": { |
| | | "env": { |
| | | "PATH": "${env:PATH}", |
| | | "SystemRoot": "${env:SystemRoot}", |
| | | "GCC_BIN": "${env:LOCALAPPDATA}\\stm32cube\\bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin", |
| | | "ELF": "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "BIN": "${workspaceFolder}\\build\\Release\\ISKBoard.bin", |
| | | "FLASH_EXE": "${workspaceFolder}\\.vscode\\stm32flash.exe" |
| | | } |
| | | }, |
| | | "group": { |
| | | "kind": "build", |
| | | "isDefault": false |
| | | }, |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | |
| | | "default": "COM22" |
| | | } |
| | | ] |
| | | } |
| | | } |
| | |
| | | "version": "2.0.0", |
| | | "tasks": [ |
| | | { |
| | | "label": "STM32: Flash via ST-Link(SWD)", |
| | | "label": "STM32: Flash via ST-Link (SWD)", |
| | | "type": "shell", |
| | | "command": "D:\\Program Files\\ST\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI.exe", |
| | | "command": "cube", |
| | | "args": [ |
| | | "-c port=SWD", |
| | | "-e all", |
| | | "-w", |
| | | "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "0x08000000", |
| | | "-v", |
| | | "programmer", |
| | | "-c", "port=SWD", "freq=4000", "reset=HWrst", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "-rst" |
| | | ], |
| | | "group": { |
| | | "kind": "build", |
| | | "isDefault": false |
| | | }, |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | |
| | | } |
| | | }, |
| | | { |
| | | "label": "STM32: Flash via stm32flash(UART)", |
| | | "label": "STM32: Flash via Serial (UART)", |
| | | "type": "shell", |
| | | "command": "${workspaceFolder}/.vscode/stm32flash.bat", |
| | | "command": "cube", |
| | | "args": [ |
| | | "${input:comPort}" |
| | | "programmer", |
| | | "--connect", "port=${input:comPort}", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf" |
| | | ], |
| | | "options": { |
| | | "env": { |
| | | "PATH": "${env:PATH}", |
| | | "SystemRoot": "${env:SystemRoot}", |
| | | "GCC_BIN": "${env:LOCALAPPDATA}\\stm32cube\\bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin", |
| | | "ELF": "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "BIN": "${workspaceFolder}\\build\\Release\\ISKBoard.bin", |
| | | "FLASH_EXE": "${workspaceFolder}\\.vscode\\stm32flash.exe" |
| | | } |
| | | }, |
| | | "group": { |
| | | "kind": "build", |
| | | "isDefault": false |
| | | }, |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | |
| | | "default": "COM22" |
| | | } |
| | | ] |
| | | } |
| | | } |
| | |
| | | "version": "2.0.0", |
| | | "tasks": [ |
| | | { |
| | | "label": "STM32: Flash via ST-Link(SWD)", |
| | | "label": "STM32: Flash via ST-Link (SWD)", |
| | | "type": "shell", |
| | | "command": "D:\\Program Files\\ST\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI.exe", |
| | | "command": "cube", |
| | | "args": [ |
| | | "-c port=SWD", |
| | | "-e all", |
| | | "-w", |
| | | "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "0x08000000", |
| | | "-v", |
| | | "programmer", |
| | | "-c", "port=SWD", "freq=4000", "reset=HWrst", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "-rst" |
| | | ], |
| | | "group": { |
| | | "kind": "build", |
| | | "isDefault": false |
| | | }, |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | |
| | | } |
| | | }, |
| | | { |
| | | "label": "STM32: Flash via stm32flash(UART)", |
| | | "label": "STM32: Flash via Serial (UART)", |
| | | "type": "shell", |
| | | "command": "${workspaceFolder}/.vscode/stm32flash.bat", |
| | | "command": "cube", |
| | | "args": [ |
| | | "${input:comPort}" |
| | | "programmer", |
| | | "--connect", "port=${input:comPort}", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf" |
| | | ], |
| | | "options": { |
| | | "env": { |
| | | "PATH": "${env:PATH}", |
| | | "SystemRoot": "${env:SystemRoot}", |
| | | "GCC_BIN": "${env:LOCALAPPDATA}\\stm32cube\\bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin", |
| | | "ELF": "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "BIN": "${workspaceFolder}\\build\\Release\\ISKBoard.bin", |
| | | "FLASH_EXE": "${workspaceFolder}\\.vscode\\stm32flash.exe" |
| | | } |
| | | }, |
| | | "group": { |
| | | "kind": "build", |
| | | "isDefault": false |
| | | }, |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | |
| | | "default": "COM22" |
| | | } |
| | | ] |
| | | } |
| | | } |
| New file |
| | |
| | | # ===== .vscode: 只保留下面三个文件 ===== |
| | | .vscode/* |
| | | !.vscode/stm32flash.bat |
| | | !.vscode/stm32flash.exe |
| | | !.vscode/tasks.json |
| | | |
| | | # ===== Keil MD: 只保留下面两个文件 ===== |
| | | MDK-ARM/* |
| | | !MDK-ARM/ISKBoard.uvoptx |
| | | !MDK-ARM/ISKBoard.uvprojx |
| | | |
| | | # ===== STM32CubeIDE: 忽略下面文件 ===== |
| | | .project |
| | | |
| | | # ===== 只保留这两个文件不忽略 ===== |
| | | # main.c |
| | | Core/* |
| | | !Core/Src/ |
| | | Core/Src/* |
| | | !Core/Src/main.c |
| | | |
| | | # ===== 忽略 CMake 相关生成文件 ===== |
| | | .clangd |
| | | .mxproject |
| | | CMakePresets.json |
| | | cmake/ |
| | | .settings/ |
| | | |
| | | # ===== 忽略启动文件、链接脚本 ===== |
| | | *.ld |
| | | startup_stm32*.s |
| | | |
| | | # ===== 忽略厂商 SDK(如果之后 Drivers/ 出现的话)===== |
| | | Drivers/ |
| | | Middlewares/ |
| | | |
| | | # ===== 忽略编译产物 ===== |
| | | build/ |
| | | Debug/ |
| | | Release/ |
| | | *.o |
| | | *.d |
| | | *.a |
| | | *.elf |
| | | *.bin |
| | | *.hex |
| | | *.map |
| New file |
| | |
| | | { |
| | | "version": "2.0.0", |
| | | "tasks": [ |
| | | { |
| | | "label": "STM32: Flash via ST-Link (SWD)", |
| | | "type": "shell", |
| | | "command": "cube", |
| | | "args": [ |
| | | "programmer", |
| | | "-c", "port=SWD", "freq=4000", "reset=HWrst", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf", |
| | | "-rst" |
| | | ], |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | | "panel": "shared", |
| | | "clear": true |
| | | } |
| | | }, |
| | | { |
| | | "label": "STM32: Flash via Serial (UART)", |
| | | "type": "shell", |
| | | "command": "cube", |
| | | "args": [ |
| | | "programmer", |
| | | "--connect", "port=${input:comPort}", |
| | | "-w", "${workspaceFolder}\\build\\Release\\ISKBoard.elf" |
| | | ], |
| | | "group": "build", |
| | | "problemMatcher": [], |
| | | "presentation": { |
| | | "reveal": "always", |
| | | "panel": "shared", |
| | | "clear": true |
| | | } |
| | | } |
| | | ], |
| | | "inputs": [ |
| | | { |
| | | "id": "comPort", |
| | | "type": "promptString", |
| | | "description": "!!!请确保开发板进入烧录模式,并输入串口号!!!", |
| | | "default": "COM22" |
| | | } |
| | | ] |
| | | } |
| New file |
| | |
| | | cmake_minimum_required(VERSION 3.16) |
| | | |
| | | # 取当前文件夹名,并转成小写作为库名 |
| | | get_filename_component(MODULE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) |
| | | string(TOLOWER ${MODULE_NAME} MODULE_NAME_LOWER) |
| | | |
| | | project(${MODULE_NAME_LOWER} C) |
| | | |
| | | # 收集当前目录源码 |
| | | file(GLOB MODULE_SRC |
| | | "${CMAKE_CURRENT_SOURCE_DIR}/*.c" |
| | | ) |
| | | |
| | | # 创建静态库 |
| | | add_library(${MODULE_NAME_LOWER} STATIC |
| | | ${MODULE_SRC} |
| | | ) |
| | | |
| | | # 头文件搜索路径 |
| | | target_include_directories(${MODULE_NAME_LOWER} |
| | | PUBLIC |
| | | ${CMAKE_CURRENT_SOURCE_DIR} |
| | | ) |
| | | |
| | | target_link_libraries(${MODULE_NAME_LOWER} |
| | | PUBLIC |
| | | stm32cubemx |
| | | ) |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * Description: ISKBoard buzzer/beeper driver and music play |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | ***********************************************************************/ |
| | | |
| | | #include "tim.h" |
| | | #include "buzzer.h" |
| | | |
| | | #define mdelay(ms) HAL_Delay(ms) |
| | | #define ARRAY_SIZE(song) (sizeof(song)/sizeof(song[0])) |
| | | |
| | | /* 音符频率定义(Hz) */ |
| | | #define NOTE_C4 524 |
| | | #define NOTE_D4 588 |
| | | #define NOTE_E4 660 |
| | | #define NOTE_F4 698 |
| | | #define NOTE_G4 784 |
| | | #define NOTE_A4 880 |
| | | #define NOTE_B4 988 |
| | | #define NOTE_C5 1046 |
| | | #define NOTE_D5 1174 |
| | | #define NOTE_E5 1318 |
| | | #define NOTE_F5 1396 |
| | | #define NOTE_G5 1568 |
| | | #define NOTE_A5 1760 |
| | | #define NOTE_B5 1976 |
| | | #define NOTE_C6 2093 |
| | | #define REST 0 |
| | | |
| | | #define BEAT 400 /* 一拍时长(ms),可自行调整节奏快慢 */ |
| | | |
| | | /* 《小星星》简谱: |
| | | * 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 |
| | | * 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 |
| | | * 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 |
| | | * (C=1, D=2, E=3, F=4, G=5, A=6, B=7) |
| | | */ |
| | | const Note_t twinkle[] = |
| | | { |
| | | /* Twinkle twinkle little star */ |
| | | {NOTE_C4, BEAT}, {NOTE_C4, BEAT}, {NOTE_G4, BEAT}, {NOTE_G4, BEAT}, |
| | | {NOTE_A4, BEAT}, {NOTE_A4, BEAT}, {NOTE_G4, BEAT * 2}, |
| | | |
| | | /* How I wonder what you are */ |
| | | {NOTE_F4, BEAT}, {NOTE_F4, BEAT}, {NOTE_E4, BEAT}, {NOTE_E4, BEAT}, |
| | | {NOTE_D4, BEAT}, {NOTE_D4, BEAT}, {NOTE_C4, BEAT * 2}, |
| | | |
| | | /* Up above the world so high */ |
| | | {NOTE_G4, BEAT}, {NOTE_G4, BEAT}, {NOTE_F4, BEAT}, {NOTE_F4, BEAT}, |
| | | {NOTE_E4, BEAT}, {NOTE_E4, BEAT}, {NOTE_D4, BEAT * 2}, |
| | | |
| | | /* Like a diamond in the sky */ |
| | | {NOTE_G4, BEAT}, {NOTE_G4, BEAT}, {NOTE_F4, BEAT}, {NOTE_F4, BEAT}, |
| | | {NOTE_E4, BEAT}, {NOTE_E4, BEAT}, {NOTE_D4, BEAT * 2}, |
| | | |
| | | /* Twinkle twinkle little star (repeat) */ |
| | | {NOTE_C4, BEAT}, {NOTE_C4, BEAT}, {NOTE_G4, BEAT}, {NOTE_G4, BEAT}, |
| | | {NOTE_A4, BEAT}, {NOTE_A4, BEAT}, {NOTE_G4, BEAT * 2}, |
| | | |
| | | /* How I wonder what you are (repeat) */ |
| | | {NOTE_F4, BEAT}, {NOTE_F4, BEAT}, {NOTE_E4, BEAT}, {NOTE_E4, BEAT}, |
| | | {NOTE_D4, BEAT}, {NOTE_D4, BEAT}, {NOTE_C4, BEAT * 2}, |
| | | }; |
| | | const uint32_t twinkle_count = ARRAY_SIZE(twinkle); |
| | | |
| | | /* 《祝你生日快乐》(Happy Birthday to You) |
| | | * 该曲旋律/歌词经美国法院2015-2016年裁定确认为公有领域作品,可放心使用。 |
| | | * 简谱: 5 5 6 5 1' 7 | 5 5 6 5 2' 1' | 5 5 5' 3' 1' 7 6 | 4' 4' 3' 1' 2' 1' |
| | | */ |
| | | const Note_t happy_birthday[] = |
| | | { |
| | | /* Happy Birthday to you */ |
| | | {NOTE_G4, BEAT / 2}, {NOTE_G4, BEAT / 2}, {NOTE_A4, BEAT}, {NOTE_G4, BEAT}, |
| | | {NOTE_C5, BEAT}, {NOTE_B4, BEAT * 2}, |
| | | |
| | | /* Happy Birthday to you */ |
| | | {NOTE_G4, BEAT / 2}, {NOTE_G4, BEAT / 2}, {NOTE_A4, BEAT}, {NOTE_G4, BEAT}, |
| | | {NOTE_D5, BEAT}, {NOTE_C5, BEAT * 2}, |
| | | |
| | | /* Happy Birthday dear friend */ |
| | | {NOTE_G4, BEAT / 2}, {NOTE_G4, BEAT / 2}, {NOTE_G5, BEAT}, {NOTE_E5, BEAT}, |
| | | {NOTE_C5, BEAT}, {NOTE_B4, BEAT}, {NOTE_A4, BEAT * 2}, |
| | | |
| | | /* Happy Birthday to you */ |
| | | {NOTE_F5, BEAT / 2}, {NOTE_F5, BEAT / 2}, {NOTE_E5, BEAT}, {NOTE_C5, BEAT}, |
| | | {NOTE_D5, BEAT}, {NOTE_C5, BEAT * 2}, |
| | | |
| | | /* 结尾留白 */ |
| | | {REST, BEAT * 2}, |
| | | }; |
| | | const uint32_t happy_birthday_count = ARRAY_SIZE(happy_birthday); |
| | | |
| | | /* 《Jingle Bells》(铃儿响叮当) |
| | | * 1857年James Lord Pierpont创作,早已进入公有领域。 |
| | | * (下面是常见的简化版本,节奏为大致还原,供播放测试使用) |
| | | */ |
| | | const Note_t jingle_bells[] = |
| | | { |
| | | /* Jingle bells, jingle bells, jingle all the way */ |
| | | {NOTE_E4, BEAT}, {NOTE_E4, BEAT}, {NOTE_E4, BEAT * 2}, |
| | | {NOTE_E4, BEAT}, {NOTE_E4, BEAT}, {NOTE_E4, BEAT * 2}, |
| | | {NOTE_E4, BEAT}, {NOTE_G4, BEAT}, {NOTE_C4, BEAT}, {NOTE_D4, BEAT}, |
| | | {NOTE_E4, BEAT * 4}, |
| | | |
| | | /* Oh what fun it is to ride in a one-horse open sleigh */ |
| | | {NOTE_F4, BEAT}, {NOTE_F4, BEAT}, {NOTE_F4, BEAT}, {NOTE_F4, BEAT}, |
| | | {NOTE_F4, BEAT}, {NOTE_E4, BEAT}, {NOTE_E4, BEAT}, {NOTE_E4, BEAT / 2}, {NOTE_E4, BEAT / 2}, |
| | | {NOTE_E4, BEAT}, {NOTE_D4, BEAT}, {NOTE_D4, BEAT}, {NOTE_E4, BEAT}, |
| | | {NOTE_D4, BEAT * 2}, {NOTE_G4, BEAT * 2}, |
| | | |
| | | /* 结尾留白 */ |
| | | {REST, BEAT * 2}, |
| | | }; |
| | | const uint32_t jingle_bells_count = ARRAY_SIZE(jingle_bells); |
| | | |
| | | /* |
| | | *+----------------------------+ |
| | | *| PWM buzzer API | |
| | | *+----------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief 设置蜂鸣器发声频率(占空比固定50%) |
| | | */ |
| | | static inline void Buzzer_SetFreq(uint32_t freq) |
| | | { |
| | | /* TIM1 初始化 PSC = 79,计数时钟 = 80MHz/80 = 1MHz */ |
| | | uint32_t arr = 1000000U / freq - 1U; |
| | | __HAL_TIM_SET_AUTORELOAD(&htim1, arr); |
| | | __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4, arr / 2U); |
| | | __HAL_TIM_SET_COUNTER(&htim1, 0); |
| | | } |
| | | |
| | | /** |
| | | * @brief 让蜂鸣器响 $times 次,每次间隔 $interval 毫秒 |
| | | */ |
| | | void beep_start(uint16_t times, uint16_t interval) |
| | | { |
| | | Buzzer_SetFreq(2700); |
| | | |
| | | while( times-- ) |
| | | { |
| | | /* Start buzzer */ |
| | | HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4); |
| | | |
| | | mdelay(interval); |
| | | |
| | | /* Stop buzzer */ |
| | | HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_4); |
| | | |
| | | mdelay(interval); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief 播放单个音符 |
| | | */ |
| | | static void Buzzer_PlayNote(uint32_t freq, uint32_t duration_ms) |
| | | { |
| | | if (freq == 0) |
| | | { |
| | | HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_4); |
| | | mdelay(duration_ms); |
| | | return; |
| | | } |
| | | |
| | | Buzzer_SetFreq(freq); |
| | | |
| | | HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4); |
| | | mdelay(duration_ms - 30); |
| | | |
| | | HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_4); |
| | | |
| | | mdelay(30); |
| | | } |
| | | |
| | | /** |
| | | * @brief 播放歌曲 |
| | | */ |
| | | void Play_Song(const Note_t *song, uint32_t note_count) |
| | | { |
| | | for (uint32_t i = 0; i < note_count; i++) |
| | | { |
| | | Buzzer_PlayNote(song[i].freq, song[i].duration); |
| | | } |
| | | } |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * Description: ISKBoard buzzer/beeper driver and music play |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | ***********************************************************************/ |
| | | |
| | | #ifndef __BUZZER_H |
| | | #define __BUZZER_H |
| | | |
| | | typedef struct |
| | | { |
| | | uint32_t freq; /* 音符频率,0表示休止 */ |
| | | uint32_t duration; /* 持续时间(ms) */ |
| | | } Note_t; |
| | | |
| | | /** |
| | | * @brief 让蜂鸣器响 $times 次,每次间隔 $interval 毫秒 |
| | | */ |
| | | extern void beep_start(uint16_t times, uint16_t interval); |
| | | |
| | | /** |
| | | * @brief 播放歌曲 |
| | | */ |
| | | extern void Play_Song(const Note_t *song, uint32_t note_count); |
| | | |
| | | extern const Note_t twinkle[]; |
| | | extern const uint32_t twinkle_count; |
| | | extern const Note_t happy_birthday[]; |
| | | extern const uint32_t happy_birthday_count; |
| | | extern const Note_t jingle_bells[]; |
| | | extern const uint32_t jingle_bells_count; |
| | | |
| | | #endif |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * |
| | | * Description: Temperature sensor DS18B20 driver on ISKBoard |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | * |
| | | ***********************************************************************/ |
| | | |
| | | #include "miscdev.h" |
| | | |
| | | /* DS18B20 上的数据通信口 DQ 连到了 CPU 的 PA12 引脚上 */ |
| | | static gpio_t W1Dat = |
| | | { |
| | | .name = "1-wire", |
| | | .group = GPIOA, |
| | | .pin = GPIO_PIN_12, |
| | | }; |
| | | |
| | | /* 下面定义了一些DS18B20通信DQ引脚的操作宏,这里之所以用宏而不是函数是 |
| | | * 减少函数调用的CPU开销。在下面宏中最后面出现的 \ 为断行符,如果不清楚 |
| | | * 的话,可以自行 Deepseek 搜索学习:宏定义 断行符 |
| | | */ |
| | | |
| | | /* 这里定义了一个宏,用来初始化DQ引脚:设置为输入模式,并使能内部上拉 */ |
| | | #define W1DQ_Input() \ |
| | | { \ |
| | | GPIO_InitTypeDef GPIO_InitStruct = {0}; \ |
| | | GPIO_InitStruct.Pin = W1Dat.pin; \ |
| | | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; \ |
| | | GPIO_InitStruct.Pull = GPIO_PULLUP; \ |
| | | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; \ |
| | | HAL_GPIO_Init(W1Dat.group, &GPIO_InitStruct); \ |
| | | } |
| | | |
| | | /* 这里定义了一个宏,用来把 DQ 引脚设置为推挽输出模式 */ |
| | | #define W1DQ_Output() \ |
| | | { \ |
| | | GPIO_InitTypeDef GPIO_InitStruct = {0}; \ |
| | | GPIO_InitStruct.Pin = W1Dat.pin; \ |
| | | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; \ |
| | | GPIO_InitStruct.Pull = GPIO_NOPULL; \ |
| | | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; \ |
| | | HAL_GPIO_Init(W1Dat.group, &GPIO_InitStruct); \ |
| | | } |
| | | |
| | | /* 这里定义了一个宏,用来写控制 DQ 引脚时输出高电平还是低电平 */ |
| | | #define W1DQ_Write(x) HAL_GPIO_WritePin(W1Dat.group, W1Dat.pin, \ |
| | | (x==1)?GPIO_PIN_SET:GPIO_PIN_RESET) |
| | | |
| | | /* 这里定义了一个宏,用来读 DQ 引脚,当前时高电平还是低电平 */ |
| | | #define W1DQ_Read() HAL_GPIO_ReadPin(W1Dat.group, W1Dat.pin) |
| | | |
| | | /* 这里定义了一个枚举,用来定义低电平和高电平 */ |
| | | enum { |
| | | LOW, /* 低电平:LOW=0 */ |
| | | HIGH, /* 高电平: LOW=1 */ |
| | | }; |
| | | |
| | | /* 单总线上的所有通信都是以初始化序列开始,Master发出初始化信号后等待从设备的应答信号,以确定从设备是否存在并能正常工作。 */ |
| | | static int ds18b20_reset(void) |
| | | { |
| | | int time = 0; |
| | | int present = 0; /* 设置默认值没有探测到 DS18B20 */ |
| | | static int firstin = 1; |
| | | |
| | | /* 使能所用 GPIO 口的时钟 */ |
| | | if(firstin) |
| | | { |
| | | gpio_clk_enable(W1Dat.group); |
| | | firstin = 0; |
| | | } |
| | | |
| | | /* 设置 DQ 引脚为输出模式 */ |
| | | W1DQ_Output(); |
| | | |
| | | /* 主机(CPU)输出低电平,并保持低电平时间至少 480us,以产生复位脉冲。 */ |
| | | W1DQ_Write(LOW); |
| | | udelay(480); |
| | | |
| | | /* 接着主机(CPU)释放总线, 4.7K 的上拉电阻将单总线拉高,延时 15~60 us,并进入接收模式(Rx) */ |
| | | W1DQ_Write(HIGH); // 这里先拉高是确保在模式切换瞬间,总线已经是高电平,避免模式切换瞬间可能出现的不确定状态。 |
| | | udelay(60); |
| | | W1DQ_Input(); |
| | | |
| | | /* DS18B20芯片在收到主机发送过来的这个复位脉冲后,将会拉低总线 60~240 us,以产生低电平应答脉冲 */ |
| | | while( W1DQ_Read() && time<240) { |
| | | time++; |
| | | udelay(1); |
| | | } |
| | | |
| | | /* 如果 time<240 则说明上面的while()循环是因为W1DQ_Read()读到了低电平(0) 跳出的,而不是超时 |
| | | * 跳出。这也就意味着CPU在这段期间读到了低电平,探测到DS18B20芯片了。 |
| | | */ |
| | | if( time < 240 ) |
| | | present = 1; |
| | | |
| | | /* 释放总线并维持至少480us */ |
| | | W1DQ_Output(); |
| | | W1DQ_Write(HIGH); |
| | | udelay(480-time); |
| | | |
| | | return present; |
| | | } |
| | | |
| | | /* |
| | | * 写 0 时序:主机输出低电平,延时 60us,然后释放总线,延时 2us; |
| | | * 写 1 时序:主机输出低电平,延时 2us,然后释放总线,延时 60us; |
| | | */ |
| | | void ds18b20_write_byte(uint8_t byte) |
| | | { |
| | | uint8_t i = 0; |
| | | |
| | | /* 设置 DS18B20的DQ引脚为输出模式 */ |
| | | W1DQ_Output(); |
| | | |
| | | /* 1个字节包含8个位,DS18B20数据发送是LSB(低位先发送) */ |
| | | for(i=0; i<8; i++) { |
| | | |
| | | /* DS18B20的写0逻辑是将 DQ 拉低>=60us 后拉高,写1逻辑是拉低<=15us后拉高 */ |
| | | |
| | | /* 这里先将 DS18B20 的 DQ 线线拉低 10us(<15us) */ |
| | | W1DQ_Write(LOW); |
| | | udelay(10); |
| | | |
| | | /* 判断当前位是1还是0 */ |
| | | if( byte & 0x1 ) |
| | | W1DQ_Write(HIGH); /* 如果当前位是1,则现在就拉成高电平,这样低电平维持时间 10us */ |
| | | else |
| | | W1DQ_Write(LOW); /* 如果当前位是0,则继续维持低电平,这样低电平维持时间位 10+下面的60us */ |
| | | |
| | | /* 无论是写0还是写1,DQ的写时序都要大于15+15+30=60us */ |
| | | udelay(60); |
| | | |
| | | /* 发送0/1数据位完成后,拉高总线并延时 2us */ |
| | | W1DQ_Write(HIGH); |
| | | udelay(2); |
| | | |
| | | /* 该字节数据右移1位,即再发下一位数据 */ |
| | | byte >>= 1; |
| | | } |
| | | } |
| | | |
| | | /* 当总线控制器把数据线从高电平拉到低电平时,读时序开始,数据线必须至少保持1us,然后总线被释放。 |
| | | * DS18B20 通过拉高或拉低总线上来传输”1”或”0”。 |
| | | */ |
| | | uint8_t ds18b20_read_byte(void) |
| | | { |
| | | uint8_t i = 0; |
| | | uint8_t byte = 0; |
| | | |
| | | /* 1个字节包含8个位,DS18B20数据发送是LSB(低位先发送),所以读也是LSB */ |
| | | for(i=0; i<8; i++) { |
| | | /* 当CPU把数据线DQ拉低至少1us后,读时序开始。*/ |
| | | W1DQ_Output(); |
| | | W1DQ_Write(LOW); |
| | | udelay(2); |
| | | |
| | | /* CPU拉高DQ释放总线 */ |
| | | W1DQ_Write(HIGH); |
| | | udelay(2); |
| | | |
| | | /* CPU设置DQ为输入模式,等待DS18B20发数据过来,注意此时需要靠上拉电阻将总线拉成高电平 */ |
| | | W1DQ_Input(); |
| | | |
| | | /* DS18B20开始以 LSB (lower bit first) 模式发送数据 */ |
| | | if( W1DQ_Read() ) { |
| | | byte |= 1<<i; /* 如果接收到该位是高电平,则将相应位设置为1,否则为0 */ |
| | | } |
| | | |
| | | /* 读时序至少维持15+45=60us */ |
| | | udelay(60); |
| | | |
| | | /* CPU拉高DQ并释放总线 */ |
| | | W1DQ_Output(); |
| | | W1DQ_Write(HIGH); |
| | | udelay(2); |
| | | } |
| | | |
| | | return byte; |
| | | } |
| | | |
| | | /* 该函数用来给 DS18B20 传感器发送开始采样温度命令 */ |
| | | static inline int ds18b20_convert(void) |
| | | { |
| | | /* 发送复位信号,看DS18B20模块是否在位,如果模块不在或坏了就返回错误值(-1)。 */ |
| | | if( !ds18b20_reset() ) |
| | | return -1; |
| | | |
| | | /* 这里我们不关心ROM中的16位产品序列号,就发送 Skip ROM 命令跳过SN的读取 */ |
| | | ds18b20_write_byte(0xCC); |
| | | |
| | | /* 发送 Convert T 命令,通知DS18B20开始温度采样 */ |
| | | ds18b20_write_byte(0x44); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /* 根据DS18B20的 CRC 校验公式(CRC = X^8 + X^5 + X^4 + 1) 来检测收到的数据是否出错 */ |
| | | static int ds18b20_checkcrc(uint8_t *data, uint8_t length, uint8_t checksum) |
| | | { |
| | | uint8_t i, j, byte; |
| | | uint8_t mix = 0; |
| | | uint8_t crc = 0; |
| | | |
| | | for ( i=0; i<length; i++ ) { |
| | | byte = data[i]; |
| | | |
| | | for( j=0; j<8; j++ ) { |
| | | mix = ( crc ^ byte ) & 0x01; |
| | | crc >>= 1; |
| | | if ( mix ) |
| | | crc ^= 0x8C; //POLYNOMIAL; |
| | | byte >>= 1; |
| | | } |
| | | } |
| | | |
| | | return crc==checksum ? 1 : 0; |
| | | } |
| | | |
| | | /* 读取 DS18B20 的采样温度值 */ |
| | | static inline int ds18b20_read(uint8_t *out, int bytes) |
| | | { |
| | | uint8_t buf[9]; |
| | | uint8_t i = 0; |
| | | |
| | | /* CPU给DS18B02发送复位信号并探测芯片是否存在 */ |
| | | if( !ds18b20_reset() ) |
| | | return -1; |
| | | |
| | | /* 这里我们不关心ROM中的16位产品序列号,就发送 Skip ROM 命令跳过SN的读取 */ |
| | | ds18b20_write_byte(0xCC); |
| | | |
| | | /* 发送 Read Scratchpad 命令开始读取DS18B20的采样温度值 */ |
| | | ds18b20_write_byte(0xBE); |
| | | |
| | | buf[i++] = ds18b20_read_byte(); /* 第1个字节是温度值的低字节(LSB) */ |
| | | buf[i++] = ds18b20_read_byte(); /* 第2个字节是温度值的高字节(MSB) */ |
| | | buf[i++] = ds18b20_read_byte(); /* 第3个字节不关心 */ |
| | | buf[i++] = ds18b20_read_byte(); /* 第4个字节不关心 */ |
| | | buf[i++] = ds18b20_read_byte(); /* 第5个字节是用户配置寄存器,也不关系 */ |
| | | buf[i++] = ds18b20_read_byte(); /* 第6个字节保留(0xFF) */ |
| | | buf[i++] = ds18b20_read_byte(); /* 第7个字节保留 */ |
| | | buf[i++] = ds18b20_read_byte(); /* 第8个字节保留(0x10) */ |
| | | buf[i++] = ds18b20_read_byte(); /* 第9个字节是CRC校验和 */ |
| | | |
| | | /* 将读取到的前8个字节数据按照CRC公司计算校验和,与第9个字节做对比看是否匹配 */ |
| | | if( !ds18b20_checkcrc(buf, 8, buf[8]) ) { |
| | | return -2; /* CRC校验失败就返回错误值 */ |
| | | } |
| | | |
| | | /* CRC校验通过就输出读到的2字节温度采样原始数据 */ |
| | | out[0]=buf[0]; |
| | | out[1]=buf[1]; |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int ds18b20_sample(float *temperature) |
| | | { |
| | | uint8_t byte[2]; |
| | | uint8_t sign; |
| | | uint16_t temp; |
| | | static uint8_t firstin = 1; |
| | | |
| | | if( !temperature ) |
| | | return -1; |
| | | |
| | | /* 发送开始采样的命令 */ |
| | | if( ds18b20_convert()<0 ) |
| | | return -2; |
| | | |
| | | /* 芯片datasheet说明第一次启动采样最大需要750ms完成,否则将会在100ms内完成采样 */ |
| | | if( firstin ) { |
| | | mdelay(750); |
| | | firstin = 0; |
| | | } |
| | | else { |
| | | mdelay(100); |
| | | } |
| | | |
| | | /* 开始从DS18B20传感器读取2字节的原始数据 */ |
| | | if( ds18b20_read(byte, 2)<0 ) |
| | | return -3; |
| | | |
| | | /* 采样温度值两个字节,共16位。其中byte[0]为低字节、byte[1]为高字节: |
| | | * LSB: Bits[0:3]为小数位 2^(-4) ~ 2^(-1) Bits[4:7]为整数位:2^0~2^3 |
| | | * MSB: Bits[0:2]为为整数位:2^4~2^6 Bits[3:7]为符号位: 全1表示温度为负值 |
| | | */ |
| | | |
| | | /* 高字节的低3位为温度整数值,高8位为符号位。*/ |
| | | if( byte[1]> 0x7 ) { /* 如果>7(低三位最大为111=7),说明为负值 */ |
| | | temp = ~(byte[1]<<8|byte[0]) + 1; |
| | | sign=0; |
| | | } |
| | | else { |
| | | temp = byte[1]<<8 | byte[0]; |
| | | sign=1; |
| | | } |
| | | |
| | | /* DS18b20默认工作精度为12位,高8位是整数部分,低4位为小数部分。小数部分刻度为0.0625(1/16) */ |
| | | *temperature = (temp>>4) + (temp&0xF)*0.0625 ; |
| | | if( !sign ) { |
| | | *temperature = -*temperature; |
| | | } |
| | | |
| | | return 0; |
| | | } |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * |
| | | * Description: Temperature sensor DS18B20 driver on ISKBoard |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | * |
| | | ***********************************************************************/ |
| | | |
| | | #ifndef __DS18B20_H_ |
| | | #define __DS18B20_H_ |
| | | |
| | | extern int ds18b20_sample(float *temperature); |
| | | |
| | | #endif /* __DS18B20_H_ */ |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * Description: I2C EEPROM device driver for ISKBoard (Internal Lock Version) |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.5.0 2026.07.08 GuoWenxue Use goto cleanup for unified lock releasing |
| | | ***********************************************************************/ |
| | | |
| | | #include "eeprom.h" |
| | | #include "miscdev.h" /* 提供 mdelay() / udelay() */ |
| | | #include <stdio.h> |
| | | #include <string.h> |
| | | |
| | | |
| | | /* EEPROM 型号表:未来若有新芯片,只需在此处追加一行,其余代码不用更改 */ |
| | | static const eeprom_info_t eeprom_ids[] = { |
| | | { EEPROM_INFO("AT24C02", 256, 8, 1) }, |
| | | { EEPROM_INFO("AT24C04", 512, 16, 1) }, |
| | | { EEPROM_INFO("AT24C08", 1024, 16, 1) }, |
| | | { EEPROM_INFO("AT24C16", 2048, 16, 1) }, |
| | | { EEPROM_INFO("AT24C32", 4096, 32, 2) }, |
| | | { EEPROM_INFO("AT24C64", 8192, 32, 2) }, |
| | | { EEPROM_INFO("AT24C128", 16384, 64, 2) }, |
| | | { EEPROM_INFO("AT24C256", 32768, 64, 2) }, |
| | | }; |
| | | #define EEPROM_IDS_NUM (sizeof(eeprom_ids) / sizeof(eeprom_ids[0])) |
| | | |
| | | /** |
| | | * @brief 根据芯片型号名称内部查找匹配的型号 |
| | | */ |
| | | static const eeprom_info_t *eeprom_find_info_by_name(const char *name) |
| | | { |
| | | uint32_t i; |
| | | for (i = 0; i < EEPROM_IDS_NUM; i++) |
| | | { |
| | | if (strcmp(eeprom_ids[i].name, name) == 0) |
| | | { |
| | | return &eeprom_ids[i]; |
| | | } |
| | | } |
| | | return NULL; |
| | | } |
| | | |
| | | /** |
| | | * @brief 初始化 EEPROM 设备参数(通过型号名称自动查表匹配) |
| | | */ |
| | | int eeprom_init(eeprom_dev_t *eeprom, i2c_bus_t *bus, uint8_t dev_addr, const char *chip_name) |
| | | { |
| | | const eeprom_info_t *info = eeprom_find_info_by_name(chip_name); |
| | | |
| | | if (!info || !eeprom || !bus) |
| | | { |
| | | printf("EEPROM: Named device [%s] not supported!\r\n", chip_name ? chip_name : "NULL"); |
| | | return -1; |
| | | } |
| | | |
| | | eeprom->bus = bus; |
| | | eeprom->dev_addr = dev_addr; |
| | | eeprom->info = info; |
| | | |
| | | printf("Initialized EEPROM(%s), Capacity: %ld Bytes, Page Size: %ld\r\n", |
| | | info->name, info->capacity, info->page_size); |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief EEPROM 测试函数 |
| | | */ |
| | | int eeprom_test(i2c_bus_t *bus) |
| | | { |
| | | eeprom_dev_t my_at24c256; |
| | | uint8_t tx_buf[100]; |
| | | uint8_t rx_buf[100]; |
| | | int i; |
| | | int rv = -1; |
| | | |
| | | /* 1. 初始化 EEPROM 参数 */ |
| | | if (eeprom_init(&my_at24c256, bus, 0x50, "AT24C256") != 0) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 2. 填充测试数据 */ |
| | | for (i = 0; i < sizeof(tx_buf); i++) |
| | | { |
| | | tx_buf[i] = i; |
| | | } |
| | | |
| | | /* 3. 测试跨页连续写 */ |
| | | if (eeprom_write(&my_at24c256, 0x00A0, tx_buf, sizeof(tx_buf)) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 4. 测试任意地址连续读 */ |
| | | if (eeprom_read(&my_at24c256, 0x00A0, rx_buf, sizeof(rx_buf)) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 5. 数据一致性校验 */ |
| | | if (memcmp(tx_buf, rx_buf, sizeof(tx_buf)) == 0) |
| | | { |
| | | rv = 0; |
| | | } |
| | | |
| | | cleanup: |
| | | printf("AT24C256 Read/Write Test %s!\r\n", rv == 0 ? "Passed" : "Failed"); |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief 24C16仅支持单字节地址(可寻址256字节),需借用I2C设备地址的低3位充当片内地址的高3位。 |
| | | */ |
| | | static inline uint8_t eeprom_get_actual_addr(eeprom_dev_t *eeprom, uint16_t reg_addr) |
| | | { |
| | | uint8_t actual_dev_addr = eeprom->dev_addr; |
| | | if (eeprom->info->addr_bytes == 1 && eeprom->info->capacity > 256) |
| | | { |
| | | actual_dev_addr |= (uint8_t)((reg_addr >> 8) & 0x07); |
| | | } |
| | | return actual_dev_addr; |
| | | } |
| | | |
| | | /** |
| | | * @brief 从 EEPROM 任意地址读取指定长度数据 |
| | | */ |
| | | i2c_status_t eeprom_read(eeprom_dev_t *eeprom, uint16_t reg_addr, uint8_t *buf, uint16_t len) |
| | | { |
| | | uint8_t addr_buf[2]; |
| | | uint8_t addr_len = 0; |
| | | i2c_msg_t msgs[2]; |
| | | i2c_status_t status; |
| | | |
| | | if ( len == 0 || !buf || !eeprom || !eeprom->bus || !eeprom->info ) |
| | | { |
| | | return I2C_OK; |
| | | } |
| | | |
| | | /* 1. 准备发送数据 */ |
| | | if (eeprom->info->addr_bytes == 2) |
| | | { |
| | | addr_buf[addr_len++] = (uint8_t)(reg_addr >> 8); |
| | | } |
| | | addr_buf[addr_len++] = (uint8_t)(reg_addr & 0xFF); |
| | | |
| | | /* 2. 封装 I2C 消息 */ |
| | | msgs[0].addr = eeprom_get_actual_addr(eeprom, reg_addr); |
| | | msgs[0].flags = I2C_M_WR; |
| | | msgs[0].len = addr_len; |
| | | msgs[0].buf = addr_buf; |
| | | |
| | | msgs[1].addr = msgs[0].addr; |
| | | msgs[1].flags = I2C_M_RD; |
| | | msgs[1].len = len; |
| | | msgs[1].buf = buf; |
| | | |
| | | /* 3. 锁住 I2C 总线 */ |
| | | if (i2c_lock(eeprom->bus) != I2C_OK) |
| | | { |
| | | return I2C_BUSY; |
| | | } |
| | | |
| | | /* 4. 调用 i2c_transfer 发送消息 */ |
| | | status = i2c_transfer(eeprom->bus, msgs, 2); |
| | | |
| | | /* 5. 释放 I2C 总线 */ |
| | | i2c_unlock(eeprom->bus); |
| | | |
| | | return status; |
| | | } |
| | | |
| | | /** |
| | | * @brief 轮询 EEPROM 硬件内部擦写就绪状态 |
| | | */ |
| | | static void eeprom_wait_standby(eeprom_dev_t *eeprom, uint16_t reg_addr) |
| | | { |
| | | i2c_msg_t msg; |
| | | uint32_t timeout = 2000; |
| | | |
| | | msg.addr = eeprom_get_actual_addr(eeprom, reg_addr); |
| | | msg.flags = I2C_M_WR; |
| | | msg.len = 0; |
| | | msg.buf = NULL; |
| | | |
| | | while (timeout--) |
| | | { |
| | | if (i2c_transfer(eeprom->bus, &msg, 1) == I2C_OK) |
| | | { |
| | | break; /* 芯片返回 ACK,擦写完成,退出轮询 */ |
| | | } |
| | | udelay(50); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief 向 EEPROM 写入单页数据 |
| | | */ |
| | | static i2c_status_t eeprom_write_page(eeprom_dev_t *eeprom, uint16_t reg_addr, uint8_t *buf, uint16_t len) |
| | | { |
| | | uint8_t tx_payload[128]; |
| | | uint8_t addr_len = 0; |
| | | i2c_msg_t msg; |
| | | i2c_status_t status = I2C_OK; |
| | | |
| | | /* 1. 准备发送数据 */ |
| | | if (eeprom->info->addr_bytes == 2) |
| | | { |
| | | tx_payload[addr_len++] = (uint8_t)(reg_addr >> 8); |
| | | } |
| | | tx_payload[addr_len++] = (uint8_t)(reg_addr & 0xFF); |
| | | memcpy(&tx_payload[addr_len], buf, len); |
| | | |
| | | msg.addr = eeprom_get_actual_addr(eeprom, reg_addr); |
| | | msg.flags = I2C_M_WR; |
| | | msg.len = addr_len + len; |
| | | msg.buf = tx_payload; |
| | | |
| | | /* 2. 锁住 I2C 总线 */ |
| | | if (i2c_lock(eeprom->bus) != I2C_OK) |
| | | { |
| | | return I2C_BUSY; |
| | | } |
| | | |
| | | /* 3. 调用 i2c_transfer 发送消息 */ |
| | | status = i2c_transfer(eeprom->bus, &msg, 1); |
| | | if (status != I2C_OK) |
| | | { |
| | | status = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 4. 轮询等待 EEPROM 内部擦写完成 */ |
| | | eeprom_wait_standby(eeprom, reg_addr); |
| | | |
| | | cleanup: |
| | | /* 5. 释放 I2C 总线 */ |
| | | i2c_unlock(eeprom->bus); |
| | | |
| | | return status; |
| | | } |
| | | |
| | | /** |
| | | * @brief 大批量数据动态跨页分包连续写入 |
| | | */ |
| | | i2c_status_t eeprom_write(eeprom_dev_t *eeprom, uint16_t reg_addr, uint8_t *buf, uint16_t len) |
| | | { |
| | | i2c_status_t status = I2C_OK; |
| | | uint16_t count = 0; |
| | | uint16_t page_offset; |
| | | uint16_t bytes_to_write; |
| | | |
| | | if ( len == 0 || !buf || !eeprom || !eeprom->bus || !eeprom->info ) |
| | | { |
| | | return I2C_OK; |
| | | } |
| | | |
| | | while (len > 0) |
| | | { |
| | | page_offset = reg_addr % eeprom->info->page_size; |
| | | |
| | | bytes_to_write = eeprom->info->page_size - page_offset; |
| | | if (bytes_to_write > len) |
| | | { |
| | | bytes_to_write = len; |
| | | } |
| | | |
| | | /* 内部单页级连写带等就绪的一体化锁定 */ |
| | | status = eeprom_write_page(eeprom, reg_addr, &buf[count], bytes_to_write); |
| | | if (status != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | reg_addr += bytes_to_write; |
| | | count += bytes_to_write; |
| | | len -= bytes_to_write; |
| | | } |
| | | |
| | | cleanup: |
| | | return status; |
| | | } |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * Description: I2C EEPROM device driver for ISKBoard |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | ***********************************************************************/ |
| | | #ifndef __EEPROM_H__ |
| | | #define __EEPROM_H__ |
| | | |
| | | #include "i2c_bitbang.h" |
| | | |
| | | #define EEPROM_INFO(_name, _cap, _page, _addr_bytes) \ |
| | | .name = _name, \ |
| | | .capacity = _cap, \ |
| | | .page_size = _page, \ |
| | | .addr_bytes = _addr_bytes, \ |
| | | .n_pages = (_cap)/(_page) |
| | | |
| | | typedef struct eeprom_info |
| | | { |
| | | const char *name; /* 芯片型号名称,如 "AT24C256" */ |
| | | uint32_t capacity; /* 总容量 (Bytes) */ |
| | | uint32_t page_size; /* 单页大小 (Bytes) */ |
| | | uint8_t addr_bytes; /* 片内寻址字节数:1 或 2 */ |
| | | uint32_t n_pages; /* 总页数 */ |
| | | } eeprom_info_t; |
| | | |
| | | /* 设备运行时上下文结构体 */ |
| | | typedef struct eeprom_dev |
| | | { |
| | | i2c_bus_t *bus; /* 绑定的 I2C 总线 */ |
| | | uint8_t dev_addr; /* 基础 I2C 从机地址 (通常为 0x50) */ |
| | | const eeprom_info_t *info; /* 指向匹配成功的规格信息,直接替代原 switch-case */ |
| | | } eeprom_dev_t; |
| | | |
| | | /* 导出 API */ |
| | | |
| | | /** |
| | | * @brief 初始化 EEPROM 设备结构体对象 |
| | | * @note 该函数仅做内部参数映射与规格配置(如页大小、芯片容量)。 |
| | | * @param eeprom: 指向 EEPROM 设备句柄的指针 |
| | | * @param bus: 绑定的物理 I2C 总线对象指针 |
| | | * @param dev_addr: EEPROM 的 7 位 I2C 从机基地址 (例如 AT24C256 常规为 0x50) |
| | | * @param chip_name: EEPROM 的芯片型号名称 (例如 "AT24C256") |
| | | * @retval None |
| | | */ |
| | | int eeprom_init(eeprom_dev_t *eeprom, i2c_bus_t *bus, uint8_t dev_addr, const char *chip_name); |
| | | |
| | | /** |
| | | * @brief 从 EEPROM 的指定内部地址连续读取数据 |
| | | * @param eeprom: 指向已初始化的 EEPROM 设备句柄的指针 |
| | | * @param reg_addr: 芯片内部物理存储的 16 位起始地址 (0x0000 ~ 0x7FFF) |
| | | * @param buf: 存放接收数据的用户缓冲区指针 |
| | | * @param len: 期望读取的数据字节数 |
| | | * @retval I2C_OK: 读取成功; I2C_ERROR: 总线或从机无应答; I2C_BUSY: 总线被占用 |
| | | */ |
| | | i2c_status_t eeprom_read(eeprom_dev_t *eeprom, uint16_t reg_addr, uint8_t *buf, uint16_t len); |
| | | |
| | | /** |
| | | * @brief 向 EEPROM 的指定内部地址连续写入数据(含跨页切片处理) |
| | | * @param eeprom: 指向已初始化的 EEPROM 设备句柄的指针 |
| | | * @param reg_addr: 芯片内部物理存储的 16 位起始地址 (0x0000 ~ 0x7FFF) |
| | | * @param buf: 存放待发送数据的源缓冲区指针 |
| | | * @param len: 期望写入的数据字节数 |
| | | * @retval I2C_OK: 全部数据写入成功; I2C_ERROR: 期间发生物理通信故障 |
| | | */ |
| | | i2c_status_t eeprom_write(eeprom_dev_t *eeprom, uint16_t reg_addr, uint8_t *buf, uint16_t len); |
| | | |
| | | /** |
| | | * @brief EEPROM 测试函数 |
| | | * @param bus: 绑定的物理 I2C 总线对象指针 |
| | | * @retval None |
| | | */ |
| | | int eeprom_test(i2c_bus_t *bus); |
| | | |
| | | #endif /* __EEPROM_H__ */ |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * |
| | | * Description: The purpose of this code is to provide a simple C library, |
| | | * which providing software bit-bang of the I2C protocol on |
| | | * any GPIO pins for ISKBoard. |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | * |
| | | ***********************************************************************/ |
| | | |
| | | #include <stdbool.h> |
| | | #include <stdio.h> |
| | | #include "miscdev.h" /* udelay() */ |
| | | #include "i2c_bitbang.h" |
| | | |
| | | /* I2C1 bus instance for SHT20, RTC, OLED on board */ |
| | | i2c_bus_t i2c1_bus = |
| | | { |
| | | .lock = ATOMIC_VAR_INIT(false), |
| | | .addr = 0x00, |
| | | .scl = {GPIOB, GPIO_PIN_6}, |
| | | .sda = {GPIOB, GPIO_PIN_7}, |
| | | }; |
| | | |
| | | /* I2C2 bus instance on MikroBUS */ |
| | | i2c_bus_t i2c2_bus = |
| | | { |
| | | .lock = ATOMIC_VAR_INIT(false), |
| | | .addr = 0x00, |
| | | .scl = {GPIOB, GPIO_PIN_10}, |
| | | .sda = {GPIOB, GPIO_PIN_11}, |
| | | }; |
| | | |
| | | /* |
| | | *+---------------------------------+ |
| | | *| I2C GPIO port Level functions | |
| | | *+---------------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief Initialize I2C GPIO pins |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | void i2c_gpio_init(i2c_bus_t *bus) |
| | | { |
| | | GPIO_InitTypeDef GPIO_InitStruct = {0}; |
| | | |
| | | /* Enable GPIO clocks */ |
| | | gpio_clk_enable(bus->scl.group); |
| | | gpio_clk_enable(bus->sda.group); |
| | | |
| | | /* Configure SCL pin */ |
| | | GPIO_InitStruct.Pin = bus->scl.pin; |
| | | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; /* Open-drain output */ |
| | | GPIO_InitStruct.Pull = GPIO_PULLUP; |
| | | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; |
| | | HAL_GPIO_Init(bus->scl.group, &GPIO_InitStruct); |
| | | |
| | | /* Configure SDA pin */ |
| | | GPIO_InitStruct.Pin = bus->sda.pin; |
| | | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; /* Open-drain output */ |
| | | GPIO_InitStruct.Pull = GPIO_PULLUP; |
| | | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; |
| | | HAL_GPIO_Init(bus->sda.group, &GPIO_InitStruct); |
| | | |
| | | /* Set both pins to HIGH (idle state) */ |
| | | HAL_GPIO_WritePin(bus->scl.group, bus->scl.pin, GPIO_PIN_SET); |
| | | HAL_GPIO_WritePin(bus->sda.group, bus->sda.pin, GPIO_PIN_SET); |
| | | } |
| | | |
| | | /** |
| | | * @brief Set SCL pin level |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param level: LOW or HIGH |
| | | * @retval None |
| | | */ |
| | | static inline void i2c_scl_set(i2c_bus_t *bus, uint8_t level) |
| | | { |
| | | HAL_GPIO_WritePin(bus->scl.group, bus->scl.pin, level?GPIO_PIN_SET:GPIO_PIN_RESET); |
| | | } |
| | | |
| | | /** |
| | | * @brief Set SDA pin level |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param level: LOW or HIGH |
| | | * @retval None |
| | | */ |
| | | static inline void i2c_sda_set(i2c_bus_t *bus, uint8_t level) |
| | | { |
| | | HAL_GPIO_WritePin(bus->sda.group, bus->sda.pin, level?GPIO_PIN_SET:GPIO_PIN_RESET); |
| | | } |
| | | |
| | | /** |
| | | * @brief Read SDA pin level |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval pin level (0 or 1) |
| | | */ |
| | | static uint8_t i2c_sda_read(i2c_bus_t *bus) |
| | | { |
| | | return (HAL_GPIO_ReadPin(bus->sda.group, bus->sda.pin) == GPIO_PIN_SET) ? 1 : 0; |
| | | } |
| | | |
| | | |
| | | /* |
| | | *+---------------------------------+ |
| | | *| I2C bus control function | |
| | | *+---------------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief 工业级模拟 I2C 总线初始化 (带硬件死锁九脉冲自愈) |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | void i2c_init(i2c_bus_t *bus) |
| | | { |
| | | if (!bus) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | /* 1. 初始化 I2C GPIO 口 */ |
| | | i2c_gpio_init(bus); |
| | | |
| | | /* 2. 连续发送 9 个 SCL 时钟脉冲 */ |
| | | i2c_sda_set(bus, HIGH); |
| | | for (int i = 0; i < 9; i++) |
| | | { |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | i2c_scl_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | } |
| | | |
| | | /* 3. 补发一个结束信号,强迫所有从机回到空闲态 */ |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | i2c_sda_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | i2c_scl_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | i2c_sda_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | } |
| | | |
| | | /** |
| | | * @brief Deinitialize I2C GPIO pins |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | void i2c_deinit(i2c_bus_t *bus) |
| | | { |
| | | HAL_GPIO_DeInit(bus->scl.group, bus->scl.pin); |
| | | HAL_GPIO_DeInit(bus->sda.group, bus->sda.pin); |
| | | atomic_store(&bus->lock, false); |
| | | } |
| | | |
| | | /** |
| | | * @brief 绑定设备及地址到 I2C 总线上 |
| | | */ |
| | | int i2c_bind_dev(i2c_dev_t *dev, i2c_bus_t *bus, uint8_t dev_addr) |
| | | { |
| | | if (!dev || !bus) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | dev->bus = bus; |
| | | dev->dev_addr = dev_addr; |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief 将I2C总线加锁让设备独占总线 |
| | | */ |
| | | int i2c_lock_dev(i2c_dev_t *dev) |
| | | { |
| | | if( !dev || !dev->bus ) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 安全上锁,若总线被占用则在此阻塞等待 */ |
| | | if( I2C_OK != i2c_lock(dev->bus) ) |
| | | { |
| | | return -2; |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief 释放设备的 I2C 总线锁 |
| | | */ |
| | | void i2c_free_dev(i2c_dev_t *dev) |
| | | { |
| | | if (!dev || !dev->bus) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | /* 1. 释放总线锁,让其他外设可以竞争总线 */ |
| | | i2c_unlock(dev->bus); |
| | | } |
| | | |
| | | /** |
| | | * @brief Lock I2C bus for exclusive access (bare metal mutex) |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval I2C_OK if success, I2C_BUSY if bus is locked |
| | | */ |
| | | i2c_status_t i2c_lock(i2c_bus_t *bus) |
| | | { |
| | | uint32_t timeout = 10000; |
| | | |
| | | /* atomic_compare_exchange_weak 会原子性地检查 bus->lock 是否为 false。 |
| | | * 如果是 false,就把它设置为 true,并返回 true; |
| | | * 如果已经是 true,则返回 false,进入循环等待。 |
| | | */ |
| | | while (timeout > 0) |
| | | { |
| | | _Bool expected = false; |
| | | if (atomic_compare_exchange_weak(&bus->lock, &expected, true)) |
| | | { |
| | | return I2C_OK; |
| | | } |
| | | udelay(10); |
| | | timeout--; |
| | | } |
| | | |
| | | return I2C_BUSY; |
| | | } |
| | | |
| | | /** |
| | | * @brief Unlock I2C bus |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | void i2c_unlock(i2c_bus_t *bus) |
| | | { |
| | | atomic_store(&bus->lock, false); |
| | | } |
| | | |
| | | /** |
| | | * @brief Scan I2C bus for connected devices |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval none |
| | | */ |
| | | void i2c_scan(i2c_bus_t *bus) |
| | | { |
| | | uint8_t addr; |
| | | int found = 0; |
| | | |
| | | if (i2c_lock(bus) != I2C_OK) { |
| | | printf("I2C bus lock failed!\r\n"); |
| | | return; |
| | | } |
| | | |
| | | printf("Scanning I2C bus...\r\n"); |
| | | |
| | | /*10-bit 地址前缀保留区(0x70 ~ 0x77)*/ |
| | | for (addr = 0x03; addr < 0x70; addr++) { |
| | | i2c_start(bus); |
| | | i2c_write_byte(bus, (addr << 1) | 0x01); // read mode |
| | | |
| | | if (i2c_wait_ack(bus) == I2C_ACK) { |
| | | printf("Found device at 0x%02X\r\n", addr); |
| | | found = 1; |
| | | } |
| | | |
| | | i2c_stop(bus); |
| | | udelay(100); |
| | | } |
| | | |
| | | i2c_unlock(bus); |
| | | |
| | | if (!found) { |
| | | printf("No I2C devices found.\r\n"); |
| | | } |
| | | } |
| | | |
| | | |
| | | /* |
| | | *+---------------------------------+ |
| | | *| I2C timing sequence function | |
| | | *+---------------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief Generate I2C start condition |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | void i2c_start(i2c_bus_t *bus) |
| | | { |
| | | /* Start Condition Timing Sequence: |
| | | ______ |
| | | SCL: |___ |
| | | _____ |
| | | SDA: |_____ |
| | | */ |
| | | |
| | | /* 无论前序是空闲还是刚结束 ACK,先确保 SCL 为低时 SDA 释放为高 */ |
| | | i2c_sda_set(bus, HIGH); |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | /* 此时拉高 SCL,SDA 必然处于稳定的高电平 */ |
| | | i2c_scl_set(bus, HIGH); |
| | | i2c_sda_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | /* 在 SCL 为高期间拉低 SDA,制造标准的 START / RESTART 沿 */ |
| | | i2c_sda_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | } |
| | | |
| | | /** |
| | | * @brief Generate I2C stop condition |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | void i2c_stop(i2c_bus_t *bus) |
| | | { |
| | | /* SCL Stop Condition Timing Sequence: |
| | | _______ |
| | | SCL: ___| |
| | | _____ |
| | | SDA: _____| |
| | | */ |
| | | |
| | | i2c_scl_set(bus, LOW); |
| | | i2c_sda_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | i2c_scl_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | i2c_sda_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | } |
| | | |
| | | /** |
| | | * @brief Wait for ACK from slave |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval I2C_ACK or I2C_NACK |
| | | */ |
| | | i2c_ack_t i2c_wait_ack(i2c_bus_t *bus) |
| | | { |
| | | uint16_t timeout = 0; |
| | | |
| | | i2c_sda_set(bus, HIGH); /* 释放SDA线允许从机控制 */ |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | i2c_scl_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); /* 确保SCL高电平波形稳定 */ |
| | | |
| | | while (i2c_sda_read(bus)) |
| | | { |
| | | timeout++; |
| | | if (timeout > I2C_TIMEOUT_COUNT) |
| | | { |
| | | break; /* 超时退出,返回NACK */ |
| | | } |
| | | } |
| | | |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | return (timeout > I2C_TIMEOUT_COUNT) ? I2C_NACK : I2C_ACK; |
| | | } |
| | | |
| | | /** |
| | | * @brief Send ACK to slave |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | void i2c_send_ack(i2c_bus_t *bus) |
| | | { |
| | | i2c_scl_set(bus, LOW); |
| | | i2c_sda_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | i2c_scl_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | } |
| | | |
| | | /** |
| | | * @brief Send NACK to slave |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | void i2c_send_nack(i2c_bus_t *bus) |
| | | { |
| | | i2c_scl_set(bus, LOW); |
| | | i2c_sda_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | i2c_scl_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); |
| | | } |
| | | |
| | | /** |
| | | * @brief Write one byte to I2C bus |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param byte: byte to write |
| | | * @retval None |
| | | */ |
| | | void i2c_write_byte(i2c_bus_t *bus, uint8_t byte) |
| | | { |
| | | uint8_t i; |
| | | |
| | | i2c_scl_set(bus, LOW); |
| | | |
| | | for (i = 0; i < 8; i++) |
| | | { |
| | | i2c_sda_set(bus, (byte & 0x80) ? HIGH : LOW); |
| | | udelay(I2C_DELAY_US); /* 数据建立时间 Setup Time */ |
| | | |
| | | i2c_scl_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); /* 保持高电平采样 */ |
| | | |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); /* 确保时钟低电平持续时间 */ |
| | | |
| | | byte <<= 1; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief Read one byte from I2C bus |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval received byte |
| | | */ |
| | | uint8_t i2c_read_byte(i2c_bus_t *bus) |
| | | { |
| | | uint8_t i; |
| | | uint8_t byte = 0; |
| | | |
| | | i2c_sda_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); |
| | | |
| | | for (i = 0; i < 8; i++) |
| | | { |
| | | byte <<= 1; |
| | | |
| | | i2c_scl_set(bus, HIGH); |
| | | udelay(I2C_DELAY_US); /* 延时确保 SCL 电平平稳后采样 */ |
| | | |
| | | if (i2c_sda_read(bus)) |
| | | { |
| | | byte |= 0x01; |
| | | } |
| | | |
| | | i2c_scl_set(bus, LOW); |
| | | udelay(I2C_DELAY_US); /* 确保时钟低电平持续时间 */ |
| | | } |
| | | |
| | | return byte; |
| | | } |
| | | |
| | | |
| | | /* |
| | | *+-----------------------------------+ |
| | | *| I2C read/write function | |
| | | *+-----------------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief Write data to I2C slave device |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param addr: 7-bit slave address |
| | | * @param reg: register address |
| | | * @param data: pointer to data buffer |
| | | * @param len: data length |
| | | * @retval I2C status |
| | | */ |
| | | i2c_status_t i2c_write(i2c_bus_t *bus, uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len) |
| | | { |
| | | uint16_t i; |
| | | int rv = I2C_OK; |
| | | |
| | | i2c_start(bus); |
| | | |
| | | /* Send slave address + write bit */ |
| | | i2c_write_byte(bus, (addr << 1) | 0x00); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* Send register address */ |
| | | i2c_write_byte(bus, reg); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* Send data */ |
| | | for (i = 0; i < len; i++) |
| | | { |
| | | i2c_write_byte(bus, data[i]); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | } |
| | | |
| | | cleanup: |
| | | i2c_stop(bus); |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief Read data from I2C slave device |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param addr: 7-bit slave address |
| | | * @param reg: register address |
| | | * @param data: pointer to data buffer |
| | | * @param len: data length |
| | | * @retval I2C status |
| | | */ |
| | | i2c_status_t i2c_read(i2c_bus_t *bus, uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len) |
| | | { |
| | | uint16_t i; |
| | | int rv = I2C_OK; |
| | | |
| | | /* Write register address */ |
| | | i2c_start(bus); |
| | | i2c_write_byte(bus, (addr << 1) | 0x00); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | i2c_write_byte(bus, reg); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* Restart and read data */ |
| | | i2c_start(bus); |
| | | i2c_write_byte(bus, (addr << 1) | 0x01); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | for (i = 0; i < len; i++) |
| | | { |
| | | data[i] = i2c_read_byte(bus); |
| | | |
| | | if (i < len - 1) |
| | | { |
| | | i2c_send_ack(bus); |
| | | } |
| | | else |
| | | { |
| | | i2c_send_nack(bus); |
| | | } |
| | | } |
| | | |
| | | cleanup: |
| | | i2c_stop(bus); |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief Write data to I2C slave device without register address |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param addr: 7-bit slave address |
| | | * @param data: pointer to data buffer |
| | | * @param len: data length |
| | | * @retval I2C status |
| | | */ |
| | | i2c_status_t i2c_write_no_reg(i2c_bus_t *bus, uint8_t addr, uint8_t *data, uint16_t len) |
| | | { |
| | | uint16_t i; |
| | | int rv = I2C_OK; |
| | | |
| | | i2c_start(bus); |
| | | |
| | | /* Send slave address + write bit */ |
| | | i2c_write_byte(bus, (addr << 1) | 0x00); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* Send data */ |
| | | for (i = 0; i < len; i++) |
| | | { |
| | | i2c_write_byte(bus, data[i]); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | } |
| | | |
| | | cleanup: |
| | | i2c_stop(bus); |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief Read data from I2C slave device without register address |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param addr: 7-bit slave address |
| | | * @param data: pointer to data buffer |
| | | * @param len: data length |
| | | * @retval I2C status |
| | | */ |
| | | i2c_status_t i2c_read_no_reg(i2c_bus_t *bus, uint8_t addr, uint8_t *data, uint16_t len) |
| | | { |
| | | uint16_t i; |
| | | int rv = I2C_OK; |
| | | |
| | | i2c_start(bus); |
| | | |
| | | /* Send slave address + read bit */ |
| | | i2c_write_byte(bus, (addr << 1) | 0x01); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | rv = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* Read data */ |
| | | for (i = 0; i < len; i++) |
| | | { |
| | | data[i] = i2c_read_byte(bus); |
| | | |
| | | if (i < len - 1) |
| | | { |
| | | i2c_send_ack(bus); |
| | | } |
| | | else |
| | | { |
| | | i2c_send_nack(bus); |
| | | } |
| | | } |
| | | |
| | | cleanup: |
| | | i2c_stop(bus); |
| | | return rv; |
| | | } |
| | | |
| | | |
| | | /* |
| | | *+-----------------------------------+ |
| | | *| Linux I2C API–compatible function | |
| | | *+-----------------------------------+ |
| | | */ |
| | | |
| | | /* Functions compatible with the Linux I2C adapter API */ |
| | | i2c_status_t i2c_transfer(i2c_bus_t *bus, i2c_msg_t *msgs, int num) |
| | | { |
| | | i2c_status_t status = I2C_OK; |
| | | int i, j; |
| | | |
| | | for (i = 0; i < num; i++) |
| | | { |
| | | i2c_msg_t *msg = &msgs[i]; |
| | | |
| | | /* 1. 每条消息都以 Start (或 Repeated Start) 开始 */ |
| | | i2c_start(bus); |
| | | |
| | | /* 2. 发送从机地址 + 读写位 */ |
| | | uint8_t dir = (msg->flags & I2C_M_RD) ? 0x01 : 0x00; |
| | | i2c_write_byte(bus, (msg->addr << 1) | dir); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | status = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 3. 根据读写标志传输主体数据 */ |
| | | if (msg->flags & I2C_M_RD) |
| | | { |
| | | /* 读模式 */ |
| | | for (j = 0; j < msg->len; j++) |
| | | { |
| | | msg->buf[j] = i2c_read_byte(bus); |
| | | /* 只要不是当前消息的最后一个字节,就回复 ACK */ |
| | | if (j < msg->len - 1) |
| | | i2c_send_ack(bus); |
| | | else |
| | | i2c_send_nack(bus); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | /* 写模式 */ |
| | | for (j = 0; j < msg->len; j++) |
| | | { |
| | | i2c_write_byte(bus, msg->buf[j]); |
| | | if (i2c_wait_ack(bus) != I2C_ACK) |
| | | { |
| | | status = I2C_ERROR; |
| | | goto cleanup; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | cleanup: |
| | | /* 4. 只有当所有消息都传输完毕,或者中途出错时,才发送 Stop 释放总线 */ |
| | | i2c_stop(bus); |
| | | |
| | | return status; |
| | | } |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * |
| | | * Description: The purpose of this code is to provide a simple C library, |
| | | * which providing software bit-bang of the I2C protocol on |
| | | * any GPIO pins for ISKBoard. |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | * |
| | | ***********************************************************************/ |
| | | |
| | | #ifndef __I2C_BITBANG_H |
| | | #define __I2C_BITBANG_H |
| | | |
| | | #include "stm32l4xx_hal.h" |
| | | #include <stdint.h> |
| | | #include <stdatomic.h> |
| | | |
| | | #define I2C_DELAY_US 5 /* I2C timing delay in microseconds */ |
| | | #define I2C_TIMEOUT_COUNT 100 /* Timeout counter for waiting ACK */ |
| | | |
| | | /* GPIO port for I2C typedef */ |
| | | typedef struct i2c_gpio_s |
| | | { |
| | | GPIO_TypeDef *group; /* GPIO group */ |
| | | uint16_t pin; /* GPIO pin */ |
| | | } i2c_gpio_t; |
| | | |
| | | /* I2C bus typedef */ |
| | | typedef struct i2c_bus_s |
| | | { |
| | | volatile atomic_bool lock; /* Bus lock flag */ |
| | | uint8_t addr; /* 7-bits slave address */ |
| | | i2c_gpio_t scl; /* SCL GPIO pin */ |
| | | i2c_gpio_t sda; /* SDA GPIO pin */ |
| | | } i2c_bus_t; |
| | | |
| | | /* GPIO level enum */ |
| | | enum |
| | | { |
| | | LOW = 0, |
| | | HIGH = 1, |
| | | }; |
| | | |
| | | /* I2C ACK/NACK enum */ |
| | | typedef enum |
| | | { |
| | | I2C_ACK = 0, |
| | | I2C_NACK = 1 |
| | | } i2c_ack_t; |
| | | |
| | | /* I2C status enum */ |
| | | typedef enum |
| | | { |
| | | I2C_OK = 0, |
| | | I2C_ERROR = 1, |
| | | I2C_TIMEOUT = 2, |
| | | I2C_BUSY = 3 |
| | | } i2c_status_t; |
| | | |
| | | /* |
| | | *+---------------------------------+ |
| | | *| I2C bus control function | |
| | | *+---------------------------------+ |
| | | */ |
| | | |
| | | /* I2C1 bus instance for SHT20, RTC, OLED on board */ |
| | | extern i2c_bus_t i2c1_bus; |
| | | |
| | | /* I2C2 bus instance on MikroBUS */ |
| | | extern i2c_bus_t i2c2_bus; |
| | | |
| | | /** |
| | | * @brief Initialize I2C GPIO pins |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | extern void i2c_init(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief Deinitialize I2C GPIO pins |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | extern void i2c_deinit(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief 通用 I2C 设备属性结构体 |
| | | */ |
| | | typedef struct { |
| | | i2c_bus_t *bus; /* 绑定的 I2C 物理总线实例 */ |
| | | uint8_t dev_addr; /* 7位设备物理从机地址 */ |
| | | } i2c_dev_t; |
| | | |
| | | /** |
| | | * @brief 绑定设备及地址到 I2C 总线上 |
| | | * @param dev: I2C 设备结构体指针 |
| | | * @param bus: 物理总线指针 |
| | | * @param dev_addr: 7位从机地址 |
| | | * @retval 0: 成功; -1: 失败 |
| | | */ |
| | | extern int i2c_bind_dev(i2c_dev_t *dev, i2c_bus_t *bus, uint8_t dev_addr); |
| | | |
| | | |
| | | /** |
| | | * @brief 将I2C总线加锁让设备独占总线 |
| | | * @param dev: I2C 设备结构体指针 |
| | | * @retval 0: 成功; -1: 失败 |
| | | */ |
| | | extern int i2c_lock_dev(i2c_dev_t *dev); |
| | | |
| | | /** |
| | | * @brief 释放设备的 I2C 总线锁 |
| | | * @param dev: I2C 设备结构体指针 |
| | | * @retval 无 |
| | | */ |
| | | extern void i2c_free_dev(i2c_dev_t *dev); |
| | | |
| | | /** |
| | | * @brief Lock I2C bus for exclusive access (bare metal mutex) |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval I2C_OK if success, I2C_BUSY if bus is locked |
| | | */ |
| | | extern i2c_status_t i2c_lock(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief Unlock I2C bus |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | extern void i2c_unlock(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief Scan I2C bus for connected devices |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval none |
| | | */ |
| | | extern void i2c_scan(i2c_bus_t *bus); |
| | | |
| | | |
| | | /* |
| | | *+---------------------------------+ |
| | | *| I2C timing sequence function | |
| | | *+---------------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief Generate I2C start condition |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | extern void i2c_start(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief Generate I2C stop condition |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | extern void i2c_stop(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief Wait for ACK from slave |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval I2C_ACK or I2C_NACK |
| | | */ |
| | | extern i2c_ack_t i2c_wait_ack(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief Send ACK to slave |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | extern void i2c_send_ack(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief Send NACK to slave |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval None |
| | | */ |
| | | extern void i2c_send_nack(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief Write one byte to I2C bus |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param byte: byte to write |
| | | * @retval None |
| | | */ |
| | | extern void i2c_write_byte(i2c_bus_t *bus, uint8_t byte); |
| | | |
| | | /** |
| | | * @brief Read one byte from I2C bus |
| | | * @param bus: pointer to I2C bus structure |
| | | * @retval received byte |
| | | */ |
| | | extern uint8_t i2c_read_byte(i2c_bus_t *bus); |
| | | |
| | | |
| | | /* |
| | | *+-----------------------------------+ |
| | | *| I2C read/write function | |
| | | *+-----------------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief Write data to I2C slave device |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param addr: 7-bit slave address |
| | | * @param reg: register address |
| | | * @param data: pointer to data buffer |
| | | * @param len: data length |
| | | * @retval I2C status |
| | | */ |
| | | extern i2c_status_t i2c_write(i2c_bus_t *bus, uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len); |
| | | |
| | | /** |
| | | * @brief Read data from I2C slave device |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param addr: 7-bit slave address |
| | | * @param reg: register address |
| | | * @param data: pointer to data buffer |
| | | * @param len: data length |
| | | * @retval I2C status |
| | | */ |
| | | extern i2c_status_t i2c_read(i2c_bus_t *bus, uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len); |
| | | |
| | | /** |
| | | * @brief Write data to I2C slave device without register address |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param addr: 7-bit slave address |
| | | * @param data: pointer to data buffer |
| | | * @param len: data length |
| | | * @retval I2C status |
| | | */ |
| | | extern i2c_status_t i2c_write_no_reg(i2c_bus_t *bus, uint8_t addr, uint8_t *data, uint16_t len); |
| | | |
| | | /** |
| | | * @brief Read data from I2C slave device without register address |
| | | * @param bus: pointer to I2C bus structure |
| | | * @param addr: 7-bit slave address |
| | | * @param data: pointer to data buffer |
| | | * @param len: data length |
| | | * @retval I2C status |
| | | */ |
| | | extern i2c_status_t i2c_read_no_reg(i2c_bus_t *bus, uint8_t addr, uint8_t *data, uint16_t len); |
| | | |
| | | |
| | | /* |
| | | *+-----------------------------------+ |
| | | *| Linux I2C API–compatible function | |
| | | *+-----------------------------------+ |
| | | */ |
| | | |
| | | #define I2C_M_WR 0x0000 /* 写控制标志 */ |
| | | #define I2C_M_RD 0x0001 /* 读控制标志 */ |
| | | |
| | | typedef struct { |
| | | uint8_t addr; /* 7位从机地址 */ |
| | | uint16_t flags; /* I2C_M_WR 或 I2C_M_RD */ |
| | | uint16_t len; /* 数据长度 */ |
| | | uint8_t *buf; /* 数据指针 */ |
| | | } i2c_msg_t; |
| | | |
| | | /* Functions compatible with the Linux I2C adapter API */ |
| | | extern i2c_status_t i2c_transfer(i2c_bus_t *bus, i2c_msg_t *msgs, int num); |
| | | |
| | | #endif /* __I2C_BITBANG_H */ |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2026 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * |
| | | * Description: ISL1208 RTC driver on ISKBoard (Unlocked Core Pattern) |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.1.0 2026.07.08 GuoWenxue Refactor with unlocked core functions |
| | | * |
| | | ***********************************************************************/ |
| | | |
| | | #include <stdio.h> |
| | | #include "isl1208.h" |
| | | |
| | | /* 隐藏在私有源文件内部的 ISL1208 寄存器映射与参数 */ |
| | | #define ISL1208_I2C_ADDR 0x6F |
| | | |
| | | #define ISL1208_REG_SC 0x00 /* 秒 (00-59) */ |
| | | #define ISL1208_REG_MN 0x01 /* 分 (00-59) */ |
| | | #define ISL1208_REG_HR 0x02 /* 时 (24小时模式) */ |
| | | #define ISL1208_REG_DT 0x03 /* 日 (01-31) */ |
| | | #define ISL1208_REG_MO 0x04 /* 月 (01-12) */ |
| | | #define ISL1208_REG_YR 0x05 /* 年 (00-99) */ |
| | | #define ISL1208_REG_DW 0x06 /* 星期 (00-06) */ |
| | | |
| | | #define ISL1208_REG_SR 0x07 /* 状态寄存器 */ |
| | | #define ISL1208_SR_RTCF 0x80 /* 掉电/晶振失效标志位 */ |
| | | #define ISL1208_SR_WRTC 0x10 /* 写使能位 */ |
| | | |
| | | /* 前置私有静态辅助函数声明 (无锁底层业务函数) */ |
| | | static int __isl1208_set_time_unlocked(const rtc_time_t *time); |
| | | static int __isl1208_get_time_unlocked(rtc_time_t *time); |
| | | |
| | | /* |
| | | *+---------------------------------+ |
| | | *| RTC 公共接口函数(带锁) | |
| | | *+---------------------------------+ |
| | | */ |
| | | |
| | | /* I2C 设备 RTC */ |
| | | static i2c_dev_t rtc; |
| | | |
| | | /** |
| | | * @brief ISL1208 硬件初始化与掉电自愈函数 |
| | | * @note 只有检测到掉电(RTCF=1)或停振(ST=1)时,才强制清理控制位并激活时钟,平时不干扰原有走时 |
| | | * @param bus: 绑定的 I2C 物理总线指针 (如 &i2c1_bus) |
| | | * @retval 0: 初始化成功; -1: 总线通信失败或芯片未响应 |
| | | */ |
| | | int isl1208_init(i2c_bus_t *bus) |
| | | { |
| | | uint8_t sr_val; |
| | | uint8_t sc_val; |
| | | int rv = -1; |
| | | |
| | | if (!bus) |
| | | return -1; |
| | | |
| | | /* 绑定设备及其设备号到 I2C 总线上 */ |
| | | i2c_bind_dev(&rtc, bus, ISL1208_I2C_ADDR); |
| | | |
| | | /* 将I2C总线加锁让设备独占总线 */ |
| | | i2c_lock_dev(&rtc); |
| | | |
| | | /* 读取当前状态寄存器 (检查 RTCF) */ |
| | | if (i2c_read(rtc.bus, rtc.dev_addr, ISL1208_REG_SR, &sr_val, 1) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 读取当前秒寄存器 (检查 ST) */ |
| | | if (i2c_read(rtc.bus, rtc.dev_addr, ISL1208_REG_SC, &sc_val, 1) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 条件触发:只要 SBIB 位为 1 证明是断电冷启动,必须强制清除解冻 */ |
| | | if (sr_val & 0x01) |
| | | { |
| | | printf("ISL1208 Power-Loss or Stop detected! Activating oscillator...\r\n"); |
| | | |
| | | /* 强开写保护 (WRTC=1),并抹除 SBIB 冻结位 */ |
| | | sr_val = ISL1208_SR_WRTC; |
| | | if (i2c_write(rtc.bus, rtc.dev_addr, ISL1208_REG_SR, &sr_val, 1) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 写入完整的 2026-01-01 00:00:00 (星期四) 基准时间 */ |
| | | uint8_t init_buf[7]; |
| | | init_buf[0] = 0x00; /* 00秒,同时最高位 ST=0 激活晶振起振 */ |
| | | init_buf[1] = 0x00; /* 00分 */ |
| | | init_buf[2] = 0x80; /* 00时,Bit7=1 代表开启 24 小时制 */ |
| | | init_buf[3] = 0x01; /* 01日 (BCD: 0x01) */ |
| | | init_buf[4] = 0x01; /* 01月 (BCD: 0x01) */ |
| | | init_buf[5] = 0x26; /* 26年 (BCD: 0x26 代表 2026年) */ |
| | | init_buf[6] = 0x04; /* 星期四 (BCD: 0x04) */ |
| | | |
| | | /* 写入 7 个时间寄存器 */ |
| | | if (i2c_write(rtc.bus, rtc.dev_addr, ISL1208_REG_SC, init_buf, 7) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 强制将秒寄存器的最高位 ST (Stop) 清零以激活晶振 */ |
| | | sc_val &= 0x7F; |
| | | if (i2c_write(rtc.bus, rtc.dev_addr, ISL1208_REG_SC, &sc_val, 1) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 关闭写保护,并将状态寄存器洗干净 (SBIB 清零) */ |
| | | sr_val = 0x00; |
| | | if (i2c_write(rtc.bus, rtc.dev_addr, ISL1208_REG_SR, &sr_val, 1) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | } |
| | | |
| | | rv = 0; |
| | | |
| | | cleanup: |
| | | i2c_free_dev(&rtc); |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief 应用层设置 RTC 时间接口函数(rtc_time_t格式) |
| | | * @param time 指向待写入时间数据的 rtc_time_t 结构体常指针 |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | int isl1208_set_time(const rtc_time_t *time) |
| | | { |
| | | int rv = -1; |
| | | |
| | | if (!rtc.bus || !time) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | i2c_lock_dev(&rtc); |
| | | |
| | | /* 调用无锁底层核心实现写操作 */ |
| | | rv = __isl1208_set_time_unlocked(time); |
| | | |
| | | i2c_free_dev(&rtc); |
| | | |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief 应用层设置 RTC 时间接口函数(字符串格式) |
| | | * @param time_str 输入的时间字符串指针,格式如 "2026-01-01 10:00:00" |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | int isl1208_set_time_str(const char *time_str) |
| | | { |
| | | rtc_time_t tm; |
| | | int year, month, day, hour, minute, second; |
| | | |
| | | if (!time_str) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 1. 解析时间字符串 */ |
| | | if (sscanf(time_str, "%d-%d-%d %d:%d:%d", |
| | | &year, &month, &day, &hour, &minute, &second) != 6) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 2. 填充结构体(年份仅保留低两位) */ |
| | | tm.year = year % 100; |
| | | tm.month = month; |
| | | tm.day = day; |
| | | tm.hour = hour; |
| | | tm.minute = minute; |
| | | tm.second = second; |
| | | tm.weekday = 0; |
| | | |
| | | /* 3. 直接调用带锁的原本接口 */ |
| | | return isl1208_set_time(&tm); |
| | | } |
| | | |
| | | /** |
| | | * @brief 应用层获取 RTC 时间接口函数 |
| | | * @param time 指向用于接收时间数据的 rtc_time_t 结构体指针 |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | int isl1208_get_time(rtc_time_t *time) |
| | | { |
| | | int rv = -1; |
| | | |
| | | if (!rtc.bus || !time) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | i2c_lock_dev(&rtc); |
| | | |
| | | /* 调用无锁底层核心实现读操作 */ |
| | | rv = __isl1208_get_time_unlocked(time); |
| | | |
| | | i2c_free_dev(&rtc); |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief 应用层获取 RTC 时间接口函数(字符串格式) |
| | | * @param buf 用于存储格式化时间字符串的缓冲区指针 |
| | | * @param buf_len 接收缓冲区长度(建议至少20字节) |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | int isl1208_get_time_str(char *buf, size_t buf_len) |
| | | { |
| | | rtc_time_t tm; |
| | | int rv = -1; |
| | | |
| | | if (!buf || buf_len < 20) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 直接调用带锁的原本接口获取时间结构体 */ |
| | | rv = isl1208_get_time(&tm); |
| | | if (rv != 0) |
| | | { |
| | | return rv; |
| | | } |
| | | |
| | | /* 格式化为字符串输出 */ |
| | | snprintf(buf, buf_len, "20%02d-%02d-%02d %02d:%02d:%02d", |
| | | tm.year, tm.month, tm.day, |
| | | tm.hour, tm.minute, tm.second); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief 获取并格式化打印当前 RTC 时间接口函数 |
| | | * @param bus 指向已初始化的 I2C 总线结构体指针 |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | int isl1208_print_time(void) |
| | | { |
| | | char time_str[32]; |
| | | |
| | | /* 直接调用刚刚封装好的获取字符串接口 */ |
| | | if (isl1208_get_time_str(time_str, sizeof(time_str)) != 0) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 格式化输出 */ |
| | | printf("ISL1208 Time: %s\r\n", time_str); |
| | | return 0; |
| | | } |
| | | |
| | | /* |
| | | *+---------------------------------+ |
| | | *| RTC 私有底层函数(无锁) | |
| | | *+---------------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief 十进制转 BCD 码 |
| | | */ |
| | | static inline uint8_t rtc_dec_to_bcd(uint8_t dec) |
| | | { |
| | | uint8_t high; |
| | | uint8_t low; |
| | | |
| | | high = dec / 10; |
| | | low = dec % 10; |
| | | |
| | | return (uint8_t)((high << 4) | low); |
| | | } |
| | | |
| | | /** |
| | | * @brief BCD 码转十进制 |
| | | */ |
| | | static inline uint8_t rtc_bcd_to_dec(uint8_t bcd) |
| | | { |
| | | uint8_t high; |
| | | uint8_t low; |
| | | |
| | | high = bcd >> 4; |
| | | low = bcd & 0x0F; |
| | | |
| | | return (uint8_t)((high * 10) + low); |
| | | } |
| | | |
| | | /** |
| | | * @brief 向 RTC 芯片写入时间 |
| | | */ |
| | | static int __isl1208_set_time_unlocked(const rtc_time_t *time) |
| | | { |
| | | uint8_t time_buf[7]; |
| | | uint8_t sr_val; |
| | | |
| | | if( !rtc.bus ) |
| | | return -1; |
| | | |
| | | /* 读取当前状态寄存器 */ |
| | | if (i2c_read(rtc.bus, ISL1208_I2C_ADDR, ISL1208_REG_SR, &sr_val, 1) != I2C_OK) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 解除 RTC 写保护 (WRTC 置 1) */ |
| | | sr_val |= ISL1208_SR_WRTC; |
| | | if (i2c_write(rtc.bus, ISL1208_I2C_ADDR, ISL1208_REG_SR, &sr_val, 1) != I2C_OK) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 将标准十进制转换为 BCD 码并打包 */ |
| | | time_buf[0] = rtc_dec_to_bcd(time->second); |
| | | time_buf[1] = rtc_dec_to_bcd(time->minute); |
| | | time_buf[2] = (rtc_dec_to_bcd(time->hour) & 0x3F) | 0x80; |
| | | time_buf[3] = rtc_dec_to_bcd(time->day); |
| | | time_buf[4] = rtc_dec_to_bcd(time->month); |
| | | time_buf[5] = rtc_dec_to_bcd(time->year); |
| | | time_buf[6] = rtc_dec_to_bcd(time->weekday); |
| | | |
| | | /* 写入 7 个时间寄存器 */ |
| | | if (i2c_write(rtc.bus, ISL1208_I2C_ADDR, ISL1208_REG_SC, time_buf, 7) != I2C_OK) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 恢复写保护并同时清除掉电失效位 (WRTC = 0, RTCF = 0) */ |
| | | sr_val &= ~ISL1208_SR_WRTC; |
| | | sr_val &= ~ISL1208_SR_RTCF; |
| | | if (i2c_write(rtc.bus, ISL1208_I2C_ADDR, ISL1208_REG_SR, &sr_val, 1) != I2C_OK) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief 从 RTC 芯片读取时间 |
| | | */ |
| | | static int __isl1208_get_time_unlocked(rtc_time_t *time) |
| | | { |
| | | uint8_t time_buf[7]; |
| | | |
| | | /* 连续读取 7 个寄存器的原始 BCD 数据 */ |
| | | if (i2c_read(rtc.bus, ISL1208_I2C_ADDR, ISL1208_REG_SC, time_buf, 7) != I2C_OK) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 解析 BCD 码并做去噪掩码隔离 */ |
| | | time->second = rtc_bcd_to_dec(time_buf[0] & 0x7F); |
| | | time->minute = rtc_bcd_to_dec(time_buf[1] & 0x7F); |
| | | time->hour = rtc_bcd_to_dec(time_buf[2] & 0x3F); |
| | | time->day = rtc_bcd_to_dec(time_buf[3] & 0x3F); |
| | | time->month = rtc_bcd_to_dec(time_buf[4] & 0x1F); |
| | | time->year = rtc_bcd_to_dec(time_buf[5]); |
| | | time->weekday = rtc_bcd_to_dec(time_buf[6] & 0x07); |
| | | |
| | | return 0; |
| | | } |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2026 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * |
| | | * Description: ISL1208 RTC driver on ISKBoard |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2026.07.08 GuoWenxue Release initial version |
| | | * |
| | | ************************************************************************/ |
| | | |
| | | #ifndef __ISL1208_H |
| | | #define __ISL1208_H |
| | | |
| | | #include "i2c_bitbang.h" |
| | | |
| | | /** |
| | | * @brief RTC 时间结构体 (标准十进制格式,应用层直接读写) |
| | | */ |
| | | typedef struct { |
| | | uint8_t second; /* 秒: 00 - 59 */ |
| | | uint8_t minute; /* 分: 00 - 59 */ |
| | | uint8_t hour; /* 时: 00 - 23 (固定为24小时制) */ |
| | | uint8_t day; /* 日: 01 - 31 */ |
| | | uint8_t month; /* 月: 01 - 12 */ |
| | | uint8_t year; /* 年: 00 - 99 (代表 2000 - 2099 年) */ |
| | | uint8_t weekday; /* 星期: 00 - 06 (00代表星期天) */ |
| | | } rtc_time_t; |
| | | |
| | | /** |
| | | * @brief ISL1208 硬件初始化与掉电自愈函数 |
| | | * @param bus: 绑定的 I2C 物理总线指针 (如 &i2c1_bus) |
| | | * @retval 0: 初始化成功; -1: 总线通信失败或芯片未响应 |
| | | */ |
| | | extern int isl1208_init(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief 应用层设置 RTC 时间接口函数(rtc_time_t格式) |
| | | * @param time 指向待写入时间数据的 rtc_time_t 结构体常指针 |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | extern int isl1208_set_time(const rtc_time_t *time); |
| | | |
| | | /** |
| | | * @brief 应用层设置 RTC 时间接口函数(字符串格式) |
| | | * @param time_str 输入的时间字符串指针,格式如 "2026-01-01 10:00:00" |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | extern int isl1208_set_time_str(const char *time_str); |
| | | |
| | | /** |
| | | * @brief 应用层获取 RTC 时间接口函数 |
| | | * @param time 指向用于接收时间数据的 rtc_time_t 结构体指针 |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | extern int isl1208_get_time(rtc_time_t *time); |
| | | |
| | | /** |
| | | * @brief 应用层获取 RTC 时间接口函数(字符串格式) |
| | | * @param buf 用于存储格式化时间字符串的缓冲区指针 |
| | | * @param buf_len 接收缓冲区长度(建议至少20字节) |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | extern int isl1208_get_time_str(char *buf, size_t buf_len); |
| | | |
| | | /** |
| | | * @brief 获取并格式化打印当前 RTC 时间接口函数 |
| | | * @retval 0:成功, -1:失败 |
| | | */ |
| | | extern int isl1208_print_time(void); |
| | | |
| | | #endif /* __ISL1208_H */ |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * Description: ISKBoard Hardware Abstract Layer driver |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | ***********************************************************************/ |
| | | |
| | | #include "miscdev.h" |
| | | |
| | | /* |
| | | *+----------------------+ |
| | | *| STM32 GPIO API | |
| | | *+----------------------+ |
| | | */ |
| | | |
| | | void gpio_clk_enable(GPIO_TypeDef *port) |
| | | { |
| | | if (port == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE(); |
| | | else if (port == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE(); |
| | | else if (port == GPIOC) __HAL_RCC_GPIOC_CLK_ENABLE(); |
| | | else if (port == GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE(); |
| | | #ifdef GPIOE |
| | | else if (port == GPIOE) __HAL_RCC_GPIOE_CLK_ENABLE(); |
| | | #endif |
| | | #ifdef GPIOF |
| | | else if (port == GPIOF) __HAL_RCC_GPIOF_CLK_ENABLE(); |
| | | #endif |
| | | #ifdef GPIOG |
| | | else if (port == GPIOG) __HAL_RCC_GPIOG_CLK_ENABLE(); |
| | | #endif |
| | | #ifdef GPIOH |
| | | else if (port == GPIOH) __HAL_RCC_GPIOH_CLK_ENABLE(); |
| | | #endif |
| | | } |
| | | |
| | | |
| | | /* |
| | | *+----------------------+ |
| | | *| GPIO Led/Relay API | |
| | | *+----------------------+ |
| | | */ |
| | | |
| | | /* ISKBoard 有一个继电器 */ |
| | | gpio_t relay = { "Relay", GPIOD, GPIO_PIN_2, 1 }; |
| | | |
| | | /* ISKBoard 有三个Led灯 */ |
| | | gpio_t leds[LedMax] = |
| | | { |
| | | { "RedLed", GPIOC, GPIO_PIN_9, 0 }, |
| | | { "GreenLed", GPIOC, GPIO_PIN_6, 0 }, |
| | | { "BlueLed", GPIOB, GPIO_PIN_2, 0 }, |
| | | }; |
| | | |
| | | /** |
| | | * @brief 继电器初始化:配置继电器控制引脚对应的GPIO |
| | | */ |
| | | void init_relay(void) |
| | | { |
| | | /* set default output level to inactive */ |
| | | HAL_GPIO_WritePin(relay.group, relay.pin, !relay.active); |
| | | |
| | | return; |
| | | } |
| | | |
| | | /** |
| | | * @brief 控制继电器的开关状态 |
| | | * @param status: ON 或 OFF |
| | | */ |
| | | void turn_relay(int status) |
| | | { |
| | | GPIO_PinState level; |
| | | |
| | | level = status==OFF ? !relay.active : relay.active; |
| | | HAL_GPIO_WritePin(relay.group, relay.pin, level); |
| | | } |
| | | |
| | | /** |
| | | * @brief LED初始化:配置各LED对应的GPIO状态。 |
| | | */ |
| | | void init_led(void) |
| | | { |
| | | int which; |
| | | |
| | | /* Initial all leds GPIO */ |
| | | for(which=0; which<LedMax; which++) |
| | | { |
| | | /* set default output level to inactive */ |
| | | HAL_GPIO_WritePin(leds[which].group, leds[which].pin, !leds[which].active); |
| | | } |
| | | |
| | | return; |
| | | } |
| | | |
| | | /** |
| | | * @brief 控制指定LED的开关状态 |
| | | * @param which: LED编号(参考 lednum_t,如 Led_R/Led_G/Led_B) |
| | | * @param status: ON 或 OFF |
| | | */ |
| | | void turn_led(int which, int status) |
| | | { |
| | | GPIO_PinState level; |
| | | |
| | | if( which >= LedMax ) |
| | | return ; |
| | | |
| | | level = status==ON ? leds[which].active : !leds[which].active; |
| | | HAL_GPIO_WritePin(leds[which].group, leds[which].pin, level); |
| | | } |
| | | |
| | | /** |
| | | * @brief 翻转指定LED当前状态(亮变灭,灭变亮) |
| | | * @param which: LED编号(参考 lednum_t) |
| | | */ |
| | | void toggle_led(int which) |
| | | { |
| | | if( which >= LedMax ) |
| | | return ; |
| | | |
| | | HAL_GPIO_TogglePin(leds[which].group, leds[which].pin); |
| | | } |
| | | |
| | | /** |
| | | * @brief 阻塞式闪烁指定LED一次(亮interval毫秒,灭interval毫秒) |
| | | * @param which: LED编号(参考 lednum_t) |
| | | * @param interval: 亮灭各自持续时间(ms) |
| | | */ |
| | | void blink_led(int which, uint32_t interval) |
| | | { |
| | | turn_led(which, ON); |
| | | mdelay(interval); |
| | | |
| | | turn_led(which, OFF); |
| | | mdelay(interval); |
| | | } |
| | | |
| | | /** |
| | | * @brief 绿灯"滴-答"双闪心跳灯:每隔 interval 秒心跳一次。 |
| | | * @param interval: 心跳总周期,单位:秒 (参数 > 1)。 |
| | | */ |
| | | void heartbeat_led(uint32_t interval) |
| | | { |
| | | /* 总周期 - (亮 + 灭 + 亮) = 停顿时长 */ |
| | | uint32_t pause_time = (interval * 1000) - 300; |
| | | uint32_t hb_duration[4] = {60, 60, 180, pause_time}; |
| | | |
| | | static const uint8_t hb_status[4] = {ON, OFF, ON, OFF}; |
| | | |
| | | static uint8_t state = 0; |
| | | static uint32_t last_tick = 0; |
| | | static uint8_t first_run = 1; |
| | | |
| | | uint32_t now = HAL_GetTick(); |
| | | |
| | | if (first_run) |
| | | { |
| | | turn_led(Led_G, hb_status[state]); |
| | | last_tick = now; |
| | | first_run = 0; |
| | | } |
| | | |
| | | if (now - last_tick >= hb_duration[state]) |
| | | { |
| | | state = (state + 1) % 4; |
| | | turn_led(Led_G, hb_status[state]); |
| | | last_tick = now; |
| | | } |
| | | } |
| | | |
| | | /* |
| | | *+----------------------+ |
| | | *| GPIO Key API | |
| | | *+----------------------+ |
| | | */ |
| | | /* 全局按键状态位图定义,初始为0(所有按键都未按下) */ |
| | | int g_keys_status = 0; |
| | | |
| | | /** |
| | | * @brief GPIO外部中断统一回调函数(HAL库弱函数重写), |
| | | * 按键触发的EXTI中断都会进入这里,根据引脚号区分是哪个按键按下 |
| | | * @param GPIO_Pin: 触发中断的引脚号(如 GPIO_PIN_12/13/14) |
| | | */ |
| | | void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) |
| | | { |
| | | if( GPIO_PIN_12 == GPIO_Pin ) /* Key1 */ |
| | | { |
| | | g_keys_status |= KEY1_PRESSED; |
| | | } |
| | | else if( GPIO_PIN_13 == GPIO_Pin ) /* Key2 */ |
| | | { |
| | | g_keys_status |= KEY2_PRESSED; |
| | | } |
| | | else if( GPIO_PIN_14 == GPIO_Pin ) /* Key3 */ |
| | | { |
| | | g_keys_status |= KEY3_PRESSED; |
| | | } |
| | | } |
| | | |
| | | /* |
| | | *+----------------------+ |
| | | *| printf API | |
| | | *+----------------------+ |
| | | */ |
| | | |
| | | /* gcc 编译器的 printf 将会调用 __io_putchar() 函数,实现最终的字符打印 |
| | | * keil编译器的 printf 将会调用 fputc() 函数,实现最终的字符打印 |
| | | * 这里我们定义一个宏 PUTCHAR_PROTOTYPE 来兼容两个编译器所需要的函数原型 |
| | | * |
| | | * 注意: |
| | | * 1. Keil5 工程需要勾选:Options for Target -> Target -> Use MicroLIB |
| | | * 2. Keil5 的编译器 armclang(AC6) 会定义 __GNUC__ 宏,而旧版 armcc(AC5) 则不会 |
| | | */ |
| | | #if defined(__ARMCC_VERSION) /* */ |
| | | #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) |
| | | #elif defined(__GNUC__) /* GCC */ |
| | | #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) |
| | | #endif |
| | | |
| | | PUTCHAR_PROTOTYPE |
| | | { |
| | | /* 调用STM32 HAL库的串口发送函数,将printf要打印的这个字符通过串口发送出去 */ |
| | | HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); |
| | | return ch; |
| | | } |
| | | |
| | | /* |
| | | *+----------------------------+ |
| | | *| ADC noisy & lux sensor API | |
| | | *+----------------------------+ |
| | | */ |
| | | |
| | | #include "adc.h" |
| | | |
| | | /** |
| | | * @brief 读取指定通道的ADC值 |
| | | * @param channel: 通道号,例如 ADC_CHANNEL_15 / ADC_CHANNEL_16 |
| | | * @param value: 读取结果输出指针 |
| | | * @retval 0 成功, -1 失败 |
| | | */ |
| | | int adc_read_channel(uint32_t channel, uint32_t *value) |
| | | { |
| | | ADC_ChannelConfTypeDef sConfig = {0}; |
| | | uint32_t timeout = 0xffffff; |
| | | |
| | | /* 咪头(麦克风)输出的是交流信号,叠加在某个直流偏置上。 当声音信号处于波形过零点附近时, |
| | | * 2.5 个采样周期极短,ADC 输入阻抗在如此短的时间内无法对麦克风输出的高阻信号完成充电, |
| | | * 信号还没稳定就完成了采样,所以这里修改采样时间为 247.5 Cycles。 */ |
| | | sConfig.Channel = channel; |
| | | sConfig.Rank = ADC_REGULAR_RANK_1; |
| | | sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; |
| | | sConfig.SingleDiff = ADC_SINGLE_ENDED; |
| | | sConfig.OffsetNumber = ADC_OFFSET_NONE; |
| | | sConfig.Offset = 0; |
| | | |
| | | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | HAL_ADC_Start(&hadc1); |
| | | |
| | | if (HAL_ADC_PollForConversion(&hadc1, timeout) != HAL_OK) |
| | | { |
| | | HAL_ADC_Stop(&hadc1); |
| | | return -1; |
| | | } |
| | | |
| | | *value = HAL_ADC_GetValue(&hadc1); |
| | | HAL_ADC_Stop(&hadc1); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief 在指定时间窗口内对麦克风多次采样,返回峰峰值作为响度 |
| | | * @param noisy: 响度输出(峰峰值,范围 0~4095) |
| | | * @param window_ms: 采样时间窗口,建议 50~100ms(覆盖完整音节) |
| | | * @retval 0表示成功,-1 表示失败 |
| | | */ |
| | | int adc_read_noisy_peak(uint32_t *noisy, uint32_t window_ms) |
| | | { |
| | | uint32_t val; |
| | | uint32_t max_val = 0; |
| | | uint32_t min_val = 0xFFFFFFFF; |
| | | uint32_t deadline = HAL_GetTick() + window_ms; |
| | | |
| | | while (HAL_GetTick() < deadline) |
| | | { |
| | | if (adc_read_channel(ADC_CHANNEL_16, &val) != 0) |
| | | return -1; |
| | | |
| | | if (val > max_val) max_val = val; |
| | | if (val < min_val) min_val = val; |
| | | } |
| | | |
| | | /* 峰峰值消除直流偏置影响,更真实反映响度 */ |
| | | *noisy = (max_val > min_val) ? (max_val - min_val) : 0; |
| | | return 0; |
| | | } |
| | | |
| | | /* ------------------- Lux 滤波相关参数 ------------------- */ |
| | | #define LUX_SAMPLE_COUNT 10 /* 每次采集的原始样本数 */ |
| | | #define LUX_TRIM_COUNT 2 /* 排序后,头尾各丢弃的样本数 */ |
| | | |
| | | /** |
| | | * @brief 简单冒泡排序(数据量很小,不追求性能) |
| | | */ |
| | | static void sort_u32(uint32_t *arr, int n) |
| | | { |
| | | for (int i = 0; i < n - 1; i++) |
| | | { |
| | | for (int j = 0; j < n - 1 - i; j++) |
| | | { |
| | | if (arr[j] > arr[j + 1]) |
| | | { |
| | | uint32_t tmp = arr[j]; |
| | | arr[j] = arr[j + 1]; |
| | | arr[j + 1] = tmp; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief 多次采样光照度ADC值,排序后去掉两端的离群样本,再取平均 |
| | | * @param lux: 输出参数,滤波后的光照度值 |
| | | * @retval 0 成功, -1 失败 |
| | | */ |
| | | static int adc_read_lux_filtered(uint32_t *lux) |
| | | { |
| | | uint32_t samples[LUX_SAMPLE_COUNT]; |
| | | uint32_t sum = 0; |
| | | int valid_count; |
| | | |
| | | /* 多次采样光照度ADC值 */ |
| | | for (int i = 0; i < LUX_SAMPLE_COUNT; i++) |
| | | { |
| | | if (adc_read_channel(ADC_CHANNEL_15, &samples[i]) != 0) |
| | | return -1; |
| | | } |
| | | |
| | | /* 将多次采样的数据排序 */ |
| | | sort_u32(samples, LUX_SAMPLE_COUNT); |
| | | |
| | | /* 丢弃排序后头尾各 LUX_TRIM_COUNT 个可能的离群值 */ |
| | | valid_count = LUX_SAMPLE_COUNT - 2 * LUX_TRIM_COUNT; |
| | | if (valid_count <= 0) |
| | | { |
| | | /* 参数配置不合理时兜底,避免除0 */ |
| | | valid_count = LUX_SAMPLE_COUNT; |
| | | for (int i = 0; i < LUX_SAMPLE_COUNT; i++) |
| | | sum += samples[i]; |
| | | } |
| | | else |
| | | { |
| | | for (int i = LUX_TRIM_COUNT; i < LUX_SAMPLE_COUNT - LUX_TRIM_COUNT; i++) |
| | | sum += samples[i]; |
| | | } |
| | | |
| | | *lux = sum / valid_count; |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief 采集光照度与噪声值 |
| | | * @param lux: 输出参数,采集到的光照度值 |
| | | * @param noisy: 输出参数,采集到的噪声值 |
| | | * @return 0表示成功,-1 表示失败 |
| | | */ |
| | | int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy) |
| | | { |
| | | if (adc_read_lux_filtered(lux) != 0) |
| | | return -1; |
| | | |
| | | if (adc_read_noisy_peak(noisy, 50) != 0) |
| | | return -2; |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /* |
| | | *+----------------------------+ |
| | | *| Timer delay API | |
| | | *+----------------------------+ |
| | | */ |
| | | #include "tim.h" |
| | | |
| | | /** |
| | | * @brief 微秒级延时,最大支持 60000us,更长延时可以使用 HAL_Delay() |
| | | * @param us: 延时时长(微秒) |
| | | */ |
| | | void udelay(uint16_t us) |
| | | { |
| | | uint16_t differ = 60000-us; |
| | | |
| | | HAL_TIM_Base_Start(&htim6); |
| | | |
| | | __HAL_TIM_SET_COUNTER(&htim6, differ); |
| | | |
| | | while( differ < 60000 ) |
| | | { |
| | | differ=__HAL_TIM_GET_COUNTER(&htim6); |
| | | } |
| | | |
| | | HAL_TIM_Base_Stop(&htim6); |
| | | } |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * Description: ISKBoard Hardware Abstract Layer driver |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | ***********************************************************************/ |
| | | |
| | | #ifndef __MISCDEV_H |
| | | #define __MISCDEV_H |
| | | |
| | | #include <stdio.h> |
| | | |
| | | #include "stm32l4xx_hal.h" |
| | | #include "usart.h" |
| | | #include "buzzer.h" |
| | | |
| | | /* 定义ON/OFF两个宏,这样在代码中使用比 1/0 更具有可读性 */ |
| | | #define OFF 0 |
| | | #define ON 1 |
| | | |
| | | /* |
| | | *+----------------------+ |
| | | *| STM32 GPIO API | |
| | | *+----------------------+ |
| | | */ |
| | | |
| | | |
| | | /* 定义一个gpio的结构体,用来描述这个引脚的相关信息 */ |
| | | typedef struct gpio_s |
| | | { |
| | | const char *name; |
| | | GPIO_TypeDef *group; |
| | | uint16_t pin; |
| | | int active; /* 1 for active high, 0 for active low */ |
| | | } gpio_t; |
| | | |
| | | extern void gpio_clk_enable(GPIO_TypeDef *port); |
| | | |
| | | /* |
| | | *+----------------------+ |
| | | *| GPIO Relay API | |
| | | *+----------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief 继电器初始化:配置继电器控制引脚对应的GPIO |
| | | */ |
| | | extern void init_relay(void); |
| | | |
| | | /** |
| | | * @brief 控制继电器的开关状态 |
| | | * @param status: ON 或 OFF |
| | | */ |
| | | extern void turn_relay(int status); |
| | | |
| | | /* |
| | | *+----------------------+ |
| | | *| GPIO Led API | |
| | | *+----------------------+ |
| | | */ |
| | | |
| | | /* 定义了一个枚举,分别表示RGB三个灯的索引: |
| | | * 枚举的第1个成员,如果没赋值则其值为0,后面的成员值永远是前面成员的值加1. |
| | | */ |
| | | typedef enum |
| | | { |
| | | Led_R, /* 其值为0 */ |
| | | Led_G, /* 其值为1 */ |
| | | Led_B, /* 其值为2 */ |
| | | LedMax,/* 其值为3,刚好是Led的总数 */ |
| | | } lednum_t; |
| | | |
| | | /** |
| | | * @brief LED初始化:配置各LED对应的GPIO状态。 |
| | | */ |
| | | extern void init_led(void); |
| | | |
| | | /** |
| | | * @brief 控制指定LED的开关状态 |
| | | * @param which: LED编号(参考 lednum_t,如 Led_R/Led_G/Led_B) |
| | | * @param status: ON 或 OFF |
| | | */ |
| | | extern void turn_led(int which, int status); |
| | | |
| | | /** |
| | | * @brief 翻转指定LED当前状态(亮变灭,灭变亮) |
| | | * @param which: LED编号(参考 lednum_t) |
| | | */ |
| | | extern void toggle_led(int which); |
| | | |
| | | /** |
| | | * @brief 阻塞式闪烁指定LED一次(亮interval毫秒,灭interval毫秒) |
| | | * @param which: LED编号(参考 lednum_t) |
| | | * @param interval: 亮灭各自持续时间(ms) |
| | | */ |
| | | extern void blink_led(int which, uint32_t interval); |
| | | |
| | | /** |
| | | * @brief 绿灯"滴-答"双闪心跳灯:每隔 interval 秒心跳一次。 |
| | | * @param interval: 心跳总周期,单位:秒 (参数 > 1)。 |
| | | */ |
| | | extern void heartbeat_led(uint32_t interval); |
| | | |
| | | /* |
| | | *+----------------------+ |
| | | *| GPIO Led API | |
| | | *+----------------------+ |
| | | */ |
| | | |
| | | /* 定义了一个枚举,分别表示RGB三个灯的索引: |
| | | * 枚举的第1个成员,如果没赋值则其值为0,后面的成员值永远是前面成员的值加1. |
| | | */ |
| | | typedef enum |
| | | { |
| | | Key1, /* 其值为0 */ |
| | | Key2, /* 其值为1 */ |
| | | Key3, /* 其值为2 */ |
| | | KeyMax,/* 其值为3,刚好是Key的总数 */ |
| | | } keynum_t; |
| | | |
| | | /* 按键状态位掩码:对应 g_keys_status 中的第 Key1/Key2/Key3 位被按下 */ |
| | | #define KEY1_PRESSED (1<<Key1) |
| | | #define KEY2_PRESSED (1<<Key2) |
| | | #define KEY3_PRESSED (1<<Key3) |
| | | |
| | | /* 全局按键状态位图,每一位代表当前按键是否处于"已按下"状态,由中断逻辑置位 */ |
| | | extern int g_keys_status; |
| | | |
| | | /* 判断指定按键当前是否处于按下状态 */ |
| | | #define key_pressed(key) (g_keys_status & (1<<key) ) |
| | | |
| | | /* 清除指定按键的按下标志 */ |
| | | #define key_clear(key) (g_keys_status &= ~(1<<key) ) |
| | | |
| | | /* |
| | | *+----------------------------+ |
| | | *| ADC noisy & lux sensor API | |
| | | *+----------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief 采集光照度与噪声值 |
| | | * @param lux: 输出参数,采集到的光照度值 |
| | | * @param noisy: 输出参数,采集到的噪声值 |
| | | * @return 0表示成功,-1 表示失败 |
| | | */ |
| | | extern int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy); |
| | | |
| | | /* |
| | | *+----------------------------+ |
| | | *| Timer delay API | |
| | | *+----------------------------+ |
| | | */ |
| | | |
| | | /** |
| | | * @brief 微秒级延时,最大支持 60000us,更长延时可以使用 HAL_Delay() |
| | | * @param us: 延时时长(微秒) |
| | | */ |
| | | extern void udelay(uint16_t us); |
| | | |
| | | /** |
| | | * @brief 毫秒秒级延时,直接使用 HAL_Delay(),方便代码可读性 |
| | | * @param ms: 延时时长(毫秒) |
| | | */ |
| | | #define mdelay(ms) HAL_Delay(ms) |
| | | |
| | | #endif /* __MISCDEV_H */ |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2021 LingYun IoT System Studio <www.weike-iot.com> |
| | | * Author: GuoWenxue<guowenxue@gmail.com> QQ: 281143292 |
| | | * Description: ISKBoard OLED(N091-2832TSWFG02-H14, 128x32) SSD1306 driver |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2021.08.10 GuoWenxue Release initial version |
| | | * V2.0.0 2026.04.29 Optimized GRAM buffered rendering |
| | | ***********************************************************************/ |
| | | |
| | | #include <string.h> |
| | | #include "oled_drv.h" |
| | | #include "oled_font.h" |
| | | #include "miscdev.h" |
| | | |
| | | /* I2C 设备 OLED */ |
| | | static i2c_dev_t oled; |
| | | |
| | | /* ----------------------------------------------------------------------- |
| | | * 屏幕本地显存镜像缓冲区(Shadow GRAM): 128列 x 4页 |
| | | * 所有绘制操作先写入此缓冲区,调用 OLED_Refresh() 后才真正发送到屏幕, |
| | | * ----------------------------------------------------------------------- */ |
| | | static uint8_t s_gram[OLED_PAGES][X_WIDTH]; |
| | | |
| | | /* ----------------------------------------------------------------------- |
| | | * I2C 突发传输数据打包缓冲区,大小为 128列 + 1字节控制头 = 129 字节。 |
| | | * 用于在冲刷(Refresh)每一页显存时,将控制字节 (OLED_DATA) 与一页的 |
| | | * 128 字节 GRAM 数据在连续的内存中拼接,从而实现单次 I2C 事务的流式高效写入。 |
| | | * ----------------------------------------------------------------------- */ |
| | | static uint8_t s_tx_packet[X_WIDTH + 1]; |
| | | |
| | | /* |
| | | * ==================================== |
| | | * 1. OLED 底层内部私有通信函数 |
| | | * ==================================== |
| | | */ |
| | | |
| | | static int oled_write_cmd(uint8_t cmd) |
| | | { |
| | | i2c_msg_t msg; |
| | | int ret = -2; |
| | | uint8_t buf[2]; |
| | | |
| | | /* 准备数据包:控制字节(OLED_CMD) + 命令字节 */ |
| | | buf[0] = OLED_CMD; |
| | | buf[1] = cmd; |
| | | |
| | | /* 配置 I2C 消息结构体 */ |
| | | msg.addr = oled.dev_addr; /* 7位从机地址 */ |
| | | msg.flags = I2C_M_WR; /* 写标志 */ |
| | | msg.len = 2; /* 数据长度 = 控制字节 + 命令字节 */ |
| | | msg.buf = buf; /* 数据指针 */ |
| | | |
| | | /* 将I2C总线加锁让设备独占总线 */ |
| | | i2c_lock_dev(&oled); |
| | | |
| | | /* 执行 I2C 传输 */ |
| | | if (i2c_transfer(oled.bus, &msg, 1) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | ret = 0; |
| | | |
| | | cleanup: |
| | | /* 释放设备的 I2C 总线锁 */ |
| | | i2c_free_dev(&oled); |
| | | return ret; |
| | | } |
| | | |
| | | int OLED_Init(i2c_bus_t *bus) |
| | | { |
| | | if (!bus) |
| | | return -1; |
| | | |
| | | if( i2c_bind_dev(&oled, bus, OLED_I2C_ADDR) < 0) |
| | | return -2; |
| | | |
| | | mdelay(100); |
| | | |
| | | oled_write_cmd(0xAE); /* Display OFF */ |
| | | oled_write_cmd(0x40); /* Display Start Line = 0 */ |
| | | oled_write_cmd(0xB0); /* Page Start Address = 0 */ |
| | | oled_write_cmd(0xC8); /* COM Scan: remapped (垂直翻转修正) */ |
| | | |
| | | oled_write_cmd(0x81); /* Contrast Control */ |
| | | oled_write_cmd(0xFF); /* 最大对比度 */ |
| | | oled_write_cmd(0xA1); /* Segment Remap: SEG127→SEG0 */ |
| | | oled_write_cmd(0xA6); /* Normal Display (非反色) */ |
| | | |
| | | oled_write_cmd(0xA8); /* Multiplex Ratio */ |
| | | oled_write_cmd(0x1F); /* MUX=31 → 32行 (128×32屏) */ |
| | | oled_write_cmd(0xD3); /* Display Offset */ |
| | | oled_write_cmd(0x00); /* 垂直偏移=0 */ |
| | | |
| | | oled_write_cmd(0xD5); /* Display Clock Divide Ratio / OSC */ |
| | | oled_write_cmd(0xF0); /* 高频率 + 默认分频,提高刷新率 */ |
| | | oled_write_cmd(0xD9); /* Pre-charge Period */ |
| | | oled_write_cmd(0x22); /* Phase1=2, Phase2=2 DCLK */ |
| | | |
| | | oled_write_cmd(0xDA); /* COM Pins Hardware Config */ |
| | | oled_write_cmd(0x02); /* 适用于 128×32(128×64 用 0x12) */ |
| | | |
| | | oled_write_cmd(0xDB); /* VCOMH */ |
| | | oled_write_cmd(0x49); /* ≈ 0.83×Vcc */ |
| | | |
| | | /* 开启 OLED 显示面板 */ |
| | | OLED_Display_On(); |
| | | |
| | | /* 将显示屏黑屏 */ |
| | | OLED_Clear(); |
| | | OLED_Refresh(); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief 开启 OLED 显示面板 |
| | | */ |
| | | void OLED_Display_On(void) |
| | | { |
| | | oled_write_cmd(0x8D); /* Charge Pump Setting */ |
| | | oled_write_cmd(0x14); /* 电荷泵使能 */ |
| | | oled_write_cmd(0xAF); /* Display ON */ |
| | | } |
| | | |
| | | /** |
| | | * @brief 关闭 OLED 显示面板 |
| | | */ |
| | | void OLED_Display_Off(void) |
| | | { |
| | | oled_write_cmd(0x8D); /* Charge Pump Setting */ |
| | | oled_write_cmd(0x10); /* 电荷泵停用 */ |
| | | oled_write_cmd(0xAE); /* Display OFF */ |
| | | } |
| | | |
| | | /* 设置页地址(Page Address), SSD1306 显示屏按页寻址,每页 8 行像素 |
| | | * page 表示页号(0~3,对应 32px 高度的 4 页) |
| | | */ |
| | | void oled_set_pos(uint8_t x, uint8_t page) |
| | | { |
| | | oled_write_cmd( 0xB0 | (page & 0x07) ); /* 页地址 */ |
| | | oled_write_cmd( 0x10 | ((x & 0xF0) >> 4) ); /* 列高4位 */ |
| | | oled_write_cmd( x & 0x0F ); /* 列低4位 */ |
| | | } |
| | | |
| | | /** |
| | | * @brief 将本地 GRAM 缓冲区突发(Burst)全量更新至屏幕物理显存 |
| | | */ |
| | | void OLED_Refresh(void) |
| | | { |
| | | uint8_t page; |
| | | i2c_msg_t msg; |
| | | |
| | | /* 锁住整个整幅图像的刷新周期,避免多页之间总线控制权被切走造成画面闪烁 */ |
| | | i2c_lock_dev(&oled); |
| | | |
| | | msg.addr = oled.dev_addr; |
| | | msg.flags = I2C_M_WR; |
| | | msg.len = X_WIDTH + 1; |
| | | msg.buf = s_tx_packet; |
| | | s_tx_packet[0] = (uint8_t)OLED_DATA; |
| | | |
| | | for (page = 0; page < OLED_PAGES; page++) |
| | | { |
| | | oled_set_pos(0, page); |
| | | |
| | | memcpy(&s_tx_packet[1], s_gram[page], X_WIDTH); |
| | | |
| | | if (i2c_transfer(oled.bus, &msg, 1) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | udelay(5); |
| | | } |
| | | |
| | | cleanup: |
| | | i2c_free_dev(&oled); |
| | | } |
| | | |
| | | /* |
| | | * ==================================== |
| | | * 2. 内存渲染 API (无需涉及I2C总线操作) |
| | | * ==================================== |
| | | */ |
| | | |
| | | /** |
| | | * @brief 清空软件 GRAM 缓冲区(全黑), 需配合 OLED_Refresh() 使用。 |
| | | */ |
| | | void OLED_Clear(void) |
| | | { |
| | | memset(s_gram, 0x00, sizeof(s_gram)); |
| | | } |
| | | |
| | | /** |
| | | * @brief 点亮软件 GRAM 缓冲区中所有像素(全白), 需配合 OLED_Refresh() 使用。 |
| | | */ |
| | | void OLED_On(void) |
| | | { |
| | | memset(s_gram, 0xFF, sizeof(s_gram)); |
| | | } |
| | | |
| | | /** |
| | | * @brief 在本地显存区绘制一个 ASCII 字符 |
| | | */ |
| | | void OLED_ShowChar(uint8_t x, uint8_t page, char chr, uint8_t char_size) |
| | | { |
| | | uint8_t c; |
| | | uint8_t i; |
| | | uint8_t col; |
| | | |
| | | if (chr < ' ' || chr > '~') |
| | | { |
| | | chr = '?'; |
| | | } |
| | | c = chr - ' '; |
| | | |
| | | if (char_size == OLED_FONT16) |
| | | { |
| | | for (i = 0; i < 8; i++) |
| | | { |
| | | col = x + i; |
| | | if (col >= X_WIDTH) |
| | | { |
| | | break; |
| | | } |
| | | if (page < OLED_PAGES) |
| | | { |
| | | s_gram[page][col] = F8X16[c * 16 + i]; |
| | | } |
| | | if ((page + 1) < OLED_PAGES) |
| | | { |
| | | s_gram[page + 1][col] = F8X16[c * 16 + i + 8]; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | for (i = 0; i < 6; i++) |
| | | { |
| | | col = x + i; |
| | | if (col >= X_WIDTH) |
| | | { |
| | | break; |
| | | } |
| | | if (page < OLED_PAGES) |
| | | { |
| | | s_gram[page][col] = F6x8[c][i]; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief 在本地显存区绘制字符串 |
| | | */ |
| | | void OLED_ShowString(uint8_t x, uint8_t page, const char *str, uint8_t font_size) |
| | | { |
| | | uint8_t char_width; |
| | | uint8_t char_pages; |
| | | |
| | | char_width = (font_size == OLED_FONT16) ? 8 : 6; |
| | | char_pages = (font_size == OLED_FONT16) ? 2 : 1; |
| | | |
| | | if (!str) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | while (*str != '\0') |
| | | { |
| | | if (page + char_pages > OLED_PAGES) |
| | | { |
| | | break; |
| | | } |
| | | |
| | | OLED_ShowChar(x, page, *str, font_size); |
| | | x += char_width; |
| | | if (x + char_width > X_WIDTH) |
| | | { |
| | | x = 0; |
| | | page += char_pages; |
| | | } |
| | | str++; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief 在本地显存区绘制 16x16 汉字 |
| | | */ |
| | | void OLED_ShowChinese(const uint8_t (*Hzk)[32], uint8_t x, uint8_t page, uint8_t index) |
| | | { |
| | | uint8_t i; |
| | | uint8_t col; |
| | | |
| | | if (!Hzk || (page + 1 >= OLED_PAGES)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | for (i = 0; i < 16; i++) |
| | | { |
| | | col = x + i; |
| | | if (col >= X_WIDTH) |
| | | { |
| | | break; |
| | | } |
| | | s_gram[page][col] = Hzk[2 * index][i]; |
| | | s_gram[page + 1][col] = Hzk[2 * index + 1][i]; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @brief 在本地显存区绘制单色 BMP 位图 |
| | | */ |
| | | void OLED_DrawBMP(uint8_t x0, uint8_t page0, uint8_t x_width, uint8_t y_width, const uint8_t *bmp) |
| | | { |
| | | uint8_t page; |
| | | uint8_t x; |
| | | uint8_t pages; |
| | | uint32_t j; |
| | | |
| | | pages = (y_width + 7) / 8; |
| | | j = 0; |
| | | |
| | | if (!bmp) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | for (page = page0; page < page0 + pages && page < OLED_PAGES; page++) |
| | | { |
| | | for (x = x0; x < x0 + x_width && x < X_WIDTH; x++) |
| | | { |
| | | s_gram[page][x] = bmp[j++]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * ==================================== |
| | | * 3. OLED 驱动测试及示范代码 |
| | | * ==================================== |
| | | */ |
| | | |
| | | void oled_test_example(void) |
| | | { |
| | | uint8_t i; |
| | | const char *title = "ISKBoard"; |
| | | |
| | | /* 1. 硬件总线与外设初始化 */ |
| | | OLED_Init(&i2c1_bus); |
| | | mdelay(500); |
| | | |
| | | /* 2. 第一阶段:全屏点阵 Logo 图像显示测试 */ |
| | | OLED_Clear(); |
| | | /* 参数说明: 起始X=0, 起始页=PAGE0, 宽度=128, 高度=32, 数据源 */ |
| | | OLED_DrawBMP(0, OLED_PAGE0, BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, bmp_logo); |
| | | OLED_Refresh(); /* 冲刷到物理屏幕 */ |
| | | mdelay(3000); /* 保持显示 3 秒 */ |
| | | |
| | | |
| | | /* 3. 第二阶段:16x16 宋体汉字 "凌云实验室" 显示测试 */ |
| | | OLED_Clear(); |
| | | /* * 基于 index 寻址: |
| | | * 传入 index=0,函数内部会自动抓取 Hzk_LingYun[0] 和 Hzk_LingYun[1] 组合成“凌” |
| | | * 传入 index=1,函数内部会自动抓取 Hzk_LingYun[2] 和 Hzk_LingYun[3] 组合成“云” |
| | | * 每个字横向占 16 像素,起始 X 从 24 开始,使 5 个字在 128 像素宽的屏幕上完美居中 |
| | | */ |
| | | OLED_ShowChinese(Hzk_LingYun, 24, OLED_PAGE1, 0); /* “凌” (index: 0) */ |
| | | OLED_ShowChinese(Hzk_LingYun, 40, OLED_PAGE1, 1); /* “云” (index: 1) */ |
| | | OLED_ShowChinese(Hzk_LingYun, 56, OLED_PAGE1, 2); /* “实” (index: 2) */ |
| | | OLED_ShowChinese(Hzk_LingYun, 72, OLED_PAGE1, 3); /* “验” (index: 3) */ |
| | | OLED_ShowChinese(Hzk_LingYun, 88, OLED_PAGE1, 4); /* “室” (index: 4) */ |
| | | OLED_Refresh(); /* 将渲染好的 5 个宋体汉字一次性刷入屏幕 */ |
| | | mdelay(2500); /* 保持显示 2.5 秒 */ |
| | | |
| | | /* 4. 第三阶段:标准 ASCII 字符串动效打字机显示测试 */ |
| | | OLED_Clear(); |
| | | OLED_Refresh(); |
| | | |
| | | /* 动态计算位置,从第 32 列、第 1 页开始以 16 号大字体逐字敲出 "ISKBoard" */ |
| | | for (i = 0; title[i] != '\0'; i++) |
| | | { |
| | | OLED_ShowChar(32 + (i * 8), OLED_PAGE1, title[i], OLED_FONT16); |
| | | OLED_Refresh(); /* 每写一个字符,立即同步刷新到屏幕,形成打字机动效 */ |
| | | mdelay(150); |
| | | } |
| | | mdelay(2000); |
| | | |
| | | /* 5. 第四阶段:测试结束,清屏复位 */ |
| | | OLED_Clear(); |
| | | OLED_ShowString(24, OLED_PAGE1, "- Test Over -", OLED_FONT16); |
| | | OLED_Refresh(); |
| | | mdelay(1000); |
| | | |
| | | /* 6. 将显示屏黑屏并关闭显示 */ |
| | | OLED_Clear(); |
| | | OLED_Refresh(); |
| | | OLED_Display_Off(); |
| | | } |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2021 LingYun IoT System Studio <www.weike-iot.com> |
| | | * Author: GuoWenxue<guowenxue@gmail.com> QQ: 281143292 |
| | | * Description: ISKBoard OLED(N091-2832TSWFG02-H14, 128x32) SSD1306 driver |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2021.08.10 GuoWenxue Release initial version |
| | | * V2.0.0 2026.04.29 Optimized GRAM buffered rendering |
| | | ***********************************************************************/ |
| | | |
| | | /* SSD1306 OLED显示器内部按页(Page)组织数据: |
| | | |
| | | 屏幕布局(128x32): |
| | | +------------------+ |
| | | | Page 0 (0~7) | ← 8像素 |
| | | +------------------+ |
| | | | Page 1 (8~15) | ← 8像素 |
| | | +------------------+ |
| | | | Page 2 (16~23) | ← 8像素 |
| | | +------------------+ |
| | | | Page 3 (24~31) | ← 8像素 |
| | | +------------------+ |
| | | |
| | | 字体大小说明: |
| | | +---------------+---------+-------+----------+-------------+ |
| | | | FONT | 宽度 | 高度 | 占用页数 | Y坐标类型 | |
| | | +---------------+---------+-------+----------+-------------+ |
| | | | FONT8(6x8) | 6像素 | 8像素 | 1页 | 页码(0~3) | |
| | | +---------------+---------+-------+----------+-------------+ |
| | | | FONT16(8x16) | 8像素 | 16像素| 2页 | 页码(0~2) | |
| | | +---------------+---------+-------+----------+-------------+ |
| | | | Chinese(16x16)| 16像素 | 16像素| 2页 | 页码(0~2) | |
| | | +---------------+---------+-------+----------+-------------+ |
| | | */ |
| | | |
| | | #ifndef __OLED_DRV_H |
| | | #define __OLED_DRV_H |
| | | |
| | | #include "stm32l4xx_hal.h" |
| | | #include "i2c_bitbang.h" |
| | | |
| | | /* OLED I2C 从设备地址 */ |
| | | #define OLED_I2C_ADDR 0x3C |
| | | |
| | | /* 屏幕物理尺寸 */ |
| | | #define X_WIDTH 128 |
| | | #define Y_WIDTH 32 |
| | | |
| | | /* 字体大小选项 */ |
| | | #define OLED_FONT16 16 /* 8×16 像素字体 */ |
| | | #define OLED_FONT8 8 /* 6×8 像素字体 */ |
| | | |
| | | /* SSD1306 页数(128×32 屏共 4 页,每页 8 行像素) */ |
| | | enum |
| | | { |
| | | OLED_PAGE0, /* 第0个页,控制纵坐标从 0 开始 */ |
| | | OLED_PAGE1, /* 第1个页,控制纵坐标从 8 开始 */ |
| | | OLED_PAGE2, /* 第2个页,控制纵坐标从 16 开始 */ |
| | | OLED_PAGE3, /* 第3个页,控制纵坐标从 24 开始 */ |
| | | OLED_PAGES, /* 总共 4 个页 */ |
| | | }; |
| | | |
| | | /* 根据 SSD1306 芯片 datasheet 说明定义控制流标记 */ |
| | | typedef enum |
| | | { |
| | | OLED_CMD = 0x00, /* Co=0, D/C#=0 -> 后面跟着命令 */ |
| | | OLED_DATA = 0x40, /* Co=0, D/C#=1 -> 后面跟着全数据流 */ |
| | | } oled_ctrl_t; |
| | | |
| | | /* |
| | | * ========================================================================= |
| | | * 显示控制 API |
| | | * ========================================================================= |
| | | */ |
| | | |
| | | /** |
| | | * @brief 初始化 OLED 显示屏(包含寄存器流配置、本地 GRAM 格式化、以及首次总线强刷) |
| | | * @param bus: 绑定的 i2c-bitbang 物理总线句柄 |
| | | */ |
| | | int OLED_Init(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief 清空软件 GRAM 缓冲区(全黑), 需配合 OLED_Refresh() 使用。 |
| | | */ |
| | | void OLED_Clear(void); |
| | | |
| | | /** |
| | | * @brief 点亮软件 GRAM 缓冲区中所有像素(全白), 需配合 OLED_Refresh() 使用。 |
| | | */ |
| | | void OLED_On(void); |
| | | |
| | | /** |
| | | * @brief 开启 OLED 显示(打开内建 Charge Pump 倍压器 + 开启显示面板) |
| | | */ |
| | | void OLED_Display_On(void); |
| | | |
| | | /** |
| | | * @brief 关闭 OLED 显示(进入超低功耗硬件待机模式,显存内容保持不动) |
| | | */ |
| | | void OLED_Display_Off(void); |
| | | |
| | | /** |
| | | * @brief 将软件 GRAM 缓冲区一次性突发刷新到 OLED 硬件显存中 |
| | | * 每页采用单次加锁机制,极大幅度压缩总线事务开销,给其他设备留足带宽。 |
| | | */ |
| | | void OLED_Refresh(void); |
| | | |
| | | /* |
| | | * ========================================================================= |
| | | * 绘制 API(写缓冲区,需配合 OLED_Refresh() 显示) |
| | | * ========================================================================= |
| | | */ |
| | | |
| | | /** |
| | | * @brief 在本地 GRAM 缓冲区中写入单个可打印 ASCII 字符 |
| | | * |
| | | * @param x 列坐标 (0 ~ X_WIDTH-1) |
| | | * @param page 页坐标 (0 ~ OLED_PAGES-1) |
| | | * @param chr ASCII 可打印字符 |
| | | * @param char_size OLED_FONT16 (占 2 页) 或 OLED_FONT8 (占 1 页) |
| | | */ |
| | | void OLED_ShowChar(uint8_t x, uint8_t page, char chr, uint8_t char_size); |
| | | |
| | | /** |
| | | * @brief 在本地 GRAM 缓冲区中写入 ASCII 字符串(到行尾自动换行) |
| | | * |
| | | * @param x 起始列 (0 ~ X_WIDTH-1) |
| | | * @param page 起始页 (0 ~ OLED_PAGES-1) |
| | | * @param str 以 '\0' 结尾的字符串指针(支持 const 静态字面量) |
| | | * @param font_size OLED_FONT16 或 OLED_FONT8 |
| | | */ |
| | | void OLED_ShowString(uint8_t x, uint8_t page, const char *str, uint8_t font_size); |
| | | |
| | | /** |
| | | * @brief 在本地 GRAM 缓冲区中写入一个 16×16 的标准汉字 |
| | | * |
| | | * @param Hzk 汉字字模二维数组只读指针(每个汉字 32 字节,分立上下两页) |
| | | * @param x 起始列 (0 ~ X_WIDTH-1) |
| | | * @param page 起始页 (0 ~ OLED_PAGES-1) |
| | | * @param index 目标汉字在点阵数组中的索引序号 |
| | | */ |
| | | void OLED_ShowChinese(const uint8_t (*Hzk)[32], uint8_t x, uint8_t page, uint8_t index); |
| | | |
| | | /** |
| | | * @brief 在本地 GRAM 缓冲区中绘制单色二进制 BMP 图像 |
| | | * |
| | | * @param x0 起始列 (0 ~ X_WIDTH-1) |
| | | * @param page0 起始页 (0 ~ OLED_PAGES-1) |
| | | * @param x_width 图像像素宽度 |
| | | * @param y_width 图像像素高度(工程规范:必须为 8 的整数倍) |
| | | * @param bmp 单色点阵数组指针(列行式,逆向取模) |
| | | */ |
| | | void OLED_DrawBMP(uint8_t x0, uint8_t page0, |
| | | uint8_t x_width, uint8_t y_width, |
| | | const uint8_t *bmp); |
| | | |
| | | /** |
| | | * @brief OLED 驱动功能及综合演示函数(包含动态打字机、混排、全图爆破等) |
| | | */ |
| | | void oled_test_example(void); |
| | | |
| | | #endif /* __OLED_DRV_H */ |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2021 LingYun IoT System Studio <www.weike-iot.com> |
| | | * Author: GuoWenxue<guowenxue@gmail.com> QQ: 281143292 |
| | | * Description: ISKBoard OLED font data (PCtoLCD.exe generated) |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2021.08.10 GuoWenxue Release initial version |
| | | ***********************************************************************/ |
| | | |
| | | #include "oled_font.h" |
| | | |
| | | /*+--------------------------------+ |
| | | *| ASCII font size 6x8 | |
| | | *+--------------------------------+*/ |
| | | |
| | | /* 可打印 ASCII 范围: ' '(0x20) ~ '~'(0x7E), 共 95 个字符 */ |
| | | const uint8_t 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,0x0C,0x30,0xC0,0x00,0x00},/* \ */ |
| | | {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 */ |
| | | }; |
| | | |
| | | /*+--------------------------------+ |
| | | *| ASCII font size 8x16 | |
| | | *+--------------------------------+*/ |
| | | |
| | | /* 每个字符 16 字节, 共 95 个字符 */ |
| | | const uint8_t 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,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,/* | 92 */ |
| | | 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,/* } 93 */ |
| | | 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/* ~ 94 */ |
| | | }; |
| | | |
| | | /*+--------------------------------+ |
| | | *| BMP Logo for 128x32 | |
| | | *+--------------------------------+*/ |
| | | |
| | | /* lingyun-128x32.bmp 使用 PCtoLCD.exe 取模软件生成配置(图形模式): 阴码、列行式、逆向、十六进制数、C51格式 */ |
| | | const uint8_t bmp_logo[] = { |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00, |
| | | 0x00,0xFC,0xFE,0x87,0x03,0x03,0x87,0xFE,0xFC,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03, |
| | | 0x00,0x00,0xF8,0xF8,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0x78,0x78,0x78,0x78,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xF8,0x78,0x78,0x78, |
| | | 0xF8,0xF8,0xF8,0xF0,0xE0,0x80,0x00,0x00,0x00,0x80,0x80,0xE0,0xE0,0xF0,0xF0,0x78, |
| | | 0x78,0x78,0x78,0x78,0x78,0xF0,0xF0,0xE0,0xE0,0xC0,0x80,0x00,0x00,0xF0,0xF0,0xF0, |
| | | 0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0xF0,0xF0, |
| | | 0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00, |
| | | 0xC0,0xE0,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xFB,0xFB,0xF3,0xF3,0xE3,0xC3,0x00,0x03, |
| | | 0x03,0x00,0x01,0x03,0x03,0x03,0x03,0x01,0x00,0x03,0x03,0x00,0x03,0x03,0x00,0x00, |
| | | 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00, |
| | | 0x00,0x01,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x07,0x03,0x00,0x00, |
| | | 0x00,0x00,0xE0,0xE0,0xE0,0xE0,0xE1,0xE3,0xE3,0xE3,0xE3,0xE0,0x00,0x1F,0x3F,0x7F, |
| | | 0xFF,0xFC,0xF0,0xE0,0xF0,0xF0,0xF8,0xFF,0xFF,0xFF,0x3F,0x1F,0x00,0x00,0xFF,0xFF, |
| | | 0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00, |
| | | 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| | | 0x00,0x00,0x7F,0x7F,0x7F,0x7F,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x00,0x00, |
| | | 0x7F,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00, |
| | | 0x00,0x00,0x7F,0x7F,0x7F,0x7F,0x00,0x00,0x03,0x0F,0x1F,0x3F,0x7E,0x7C,0x78,0x70, |
| | | 0x70,0x60,0x61,0x71,0x71,0x7F,0x7F,0x7F,0x3F,0x1F,0x07,0x03,0x00,0x00,0x00,0x00, |
| | | 0x00,0x01,0x7F,0x7F,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x1F, |
| | | 0x3F,0x7F,0x7F,0x78,0x70,0x70,0x70,0x70,0x78,0x7F,0x3F,0x1F,0x0F,0x00,0x00,0x00, |
| | | 0x7F,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x7F,0x00,0x00, |
| | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
| | | }; |
| | | |
| | | /*+--------------------------------+ |
| | | *| Chinese Font 16x16 SongTi | |
| | | *+--------------------------------+*/ |
| | | |
| | | /* 汉字生成使用 PCtoLCD.exe(字符模式):宋体、16x16、阴码、列行式、逆向、十六进制数、C51格式 |
| | | * 每个汉字 32 字节 (16x16 点阵, 上下各 16 字节分属两页) |
| | | */ |
| | | |
| | | /* 宋体 16X16: 凌云实验室 */ |
| | | const uint8_t Hzk_LingYun[][HZK_CHAR_BYTES]= |
| | | { |
| | | {0x00,0x02,0x0C,0xC0,0x00,0x20,0xA4,0x64,0xA4,0x3F,0x24,0x64,0xA4,0x20,0x20,0x00}, |
| | | {0x02,0x02,0x7F,0x00,0x80,0x89,0x44,0x46,0x2B,0x12,0x2A,0x46,0x80,0x81,0x00,0x00},/*"凌",0*/ |
| | | |
| | | {0x40,0x40,0x42,0x42,0x42,0x42,0xC2,0x42,0x42,0x42,0x42,0x42,0x42,0x40,0x40,0x00}, |
| | | {0x00,0x20,0x70,0x28,0x24,0x23,0x20,0x20,0x20,0x24,0x28,0x30,0xE0,0x00,0x00,0x00},/*"云",1*/ |
| | | |
| | | {0x10,0x0C,0x04,0x84,0x14,0x64,0x05,0x06,0xF4,0x04,0x04,0x04,0x04,0x14,0x0C,0x00}, |
| | | {0x04,0x84,0x84,0x44,0x47,0x24,0x14,0x0C,0x07,0x0C,0x14,0x24,0x44,0x84,0x04,0x00},/*"实",2*/ |
| | | |
| | | {0x02,0xFA,0x82,0x82,0xFE,0x80,0x40,0x20,0x50,0x4C,0x43,0x4C,0x50,0x20,0x40,0x00}, |
| | | {0x08,0x18,0x48,0x84,0x44,0x3F,0x40,0x44,0x58,0x41,0x4E,0x60,0x58,0x47,0x40,0x00},/*"验",3*/ |
| | | |
| | | {0x10,0x0C,0x24,0x24,0xA4,0x64,0x25,0x26,0x24,0x24,0xA4,0x24,0x24,0x14,0x0C,0x00}, |
| | | {0x40,0x40,0x48,0x49,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x4B,0x48,0x40,0x40,0x00},/*"室",4*/ |
| | | }; |
| | | |
| | | /* 宋体 16x16: 温度 */ |
| | | const uint8_t Hzk_Temp[][HZK_CHAR_BYTES]= |
| | | { |
| | | {0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00}, |
| | | {0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00},/*"温",0*/ |
| | | |
| | | {0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00}, |
| | | {0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00},/*"度",1*/ |
| | | }; |
| | | |
| | | /* 宋体 16x16: 湿度 */ |
| | | const uint8_t Hzk_Humd[][HZK_CHAR_BYTES]= |
| | | { |
| | | {0x10,0x60,0x02,0x8C,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00}, |
| | | {0x04,0x04,0x7E,0x01,0x44,0x48,0x50,0x7F,0x40,0x40,0x7F,0x50,0x48,0x44,0x40,0x00},/*"湿",0*/ |
| | | |
| | | {0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00}, |
| | | {0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00},/*"度",1*/ |
| | | }; |
| | | |
| | | /* 宋体 16X16: 光强 */ |
| | | const uint8_t Hzk_Light[][HZK_CHAR_BYTES]= |
| | | { |
| | | {0x40,0x40,0x42,0x44,0x58,0xC0,0x40,0x7F,0x40,0xC0,0x50,0x48,0x46,0x40,0x40,0x00}, |
| | | {0x80,0x80,0x40,0x20,0x18,0x07,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x78,0x00},/*"光",0*/ |
| | | |
| | | {0x02,0xE2,0x22,0x22,0x3E,0x00,0x80,0x9E,0x92,0x92,0xF2,0x92,0x92,0x9E,0x80,0x00}, |
| | | {0x00,0x43,0x82,0x42,0x3E,0x40,0x47,0x44,0x44,0x44,0x7F,0x44,0x44,0x54,0xE7,0x00},/*"强",1*/ |
| | | }; |
| | | |
| | | /* 宋体 16X16: 声音 */ |
| | | const uint8_t Hzk_Noisy[][HZK_CHAR_BYTES]= |
| | | { |
| | | {0x04,0x14,0xD4,0x54,0x54,0x54,0x54,0xDF,0x54,0x54,0x54,0x54,0xD4,0x14,0x04,0x00}, |
| | | {0x80,0x60,0x1F,0x02,0x02,0x02,0x02,0x03,0x02,0x02,0x02,0x02,0x03,0x00,0x00,0x00},/*"声",0*/ |
| | | |
| | | {0x40,0x40,0x44,0x44,0x54,0x64,0x45,0x46,0x44,0x64,0x54,0x44,0x44,0x40,0x40,0x00}, |
| | | {0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,0x00},/*"音",1*/ |
| | | }; |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2021 LingYun IoT System Studio <www.weike-iot.com> |
| | | * Author: GuoWenxue<guowenxue@gmail.com> QQ: 281143292 |
| | | * Description: ISKBoard OLED font data (PCtoLCD.exe generated) |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2021.08.10 GuoWenxue Release initial version |
| | | ***********************************************************************/ |
| | | |
| | | #ifndef __OLED_FONT_H |
| | | #define __OLED_FONT_H |
| | | |
| | | #include <stdint.h> |
| | | |
| | | /*+--------------------------------+ |
| | | *| ASCII font size 6x8 | |
| | | *+--------------------------------+*/ |
| | | #define F6x8_COUNT 95 |
| | | extern const uint8_t F6x8[][6]; |
| | | |
| | | /*+--------------------------------+ |
| | | *| ASCII font size 8x16 | |
| | | *+--------------------------------+*/ |
| | | #define F8X16_CHAR_BYTES 16 |
| | | #define F8X16_COUNT 95 |
| | | extern const uint8_t F8X16[]; |
| | | |
| | | /*+--------------------------------+ |
| | | *| BMP Logo for 128x32 | |
| | | *+--------------------------------+*/ |
| | | #define BMP_LOGO_WIDTH 128 |
| | | #define BMP_LOGO_HEIGHT 32 |
| | | #define BMP_LOGO_SIZE (BMP_LOGO_WIDTH * BMP_LOGO_HEIGHT / 8) |
| | | extern const uint8_t bmp_logo[]; |
| | | |
| | | /*+--------------------------------+ |
| | | *| Chinese Font 16x16 SongTi | |
| | | *+--------------------------------+*/ |
| | | |
| | | /* 每个汉字 32 字节 (16x16 点阵, 上下各 16 字节分属两页) */ |
| | | #define HZK_CHAR_BYTES 32 |
| | | |
| | | /* 宋体 16X16: 凌云实验室 */ |
| | | #define HZK_LEN_LINGYUN 5 |
| | | extern const uint8_t Hzk_LingYun[][HZK_CHAR_BYTES]; |
| | | |
| | | /* 宋体 16x16: 温度 */ |
| | | #define HZK_LEN_TEMP 2 |
| | | extern const uint8_t Hzk_Temp[][HZK_CHAR_BYTES]; |
| | | |
| | | /* 宋体 16x16: 湿度 */ |
| | | #define HZK_LEN_HUMD 2 |
| | | extern const uint8_t Hzk_Humd[][HZK_CHAR_BYTES]; |
| | | |
| | | /* 宋体 16X16: 光强 */ |
| | | #define HZK_LEN_LIGHT 2 |
| | | extern const uint8_t Hzk_Light[][HZK_CHAR_BYTES]; |
| | | |
| | | /* 宋体 16X16: 声音 */ |
| | | #define HZK_LEN_NOISY 2 |
| | | extern const uint8_t Hzk_Noisy[][HZK_CHAR_BYTES]; |
| | | |
| | | #endif /* __OLED_FONT_H */ |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * |
| | | * Description: SHT20 Temperature & humidity sensor driver on ISKBoard |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | * |
| | | ***********************************************************************/ |
| | | |
| | | #include <stdio.h> |
| | | #include "sht20.h" |
| | | #include "miscdev.h" /* udelay() / mdelay() */ |
| | | |
| | | /* SHT20 7位标准 I2C 从机地址 */ |
| | | #define SHT20_I2C_ADDR 0x40 |
| | | |
| | | /* SHT20 控制指令 (No Hold Master) */ |
| | | #define SHT20_CMD_TRIG_T 0xF3 /* 触发温度测量 (非阻塞) */ |
| | | #define SHT20_CMD_TRIG_RH 0xF5 /* 触发湿度测量 (非阻塞) */ |
| | | #define SHT20_CMD_SOFT_RESET 0xFE /* 软件复位 */ |
| | | |
| | | /* I2C 设备 SHT20 */ |
| | | static i2c_dev_t sht20; |
| | | |
| | | /* 前置静态辅助函数声明 */ |
| | | static uint8_t sht20_check_crc(uint8_t *data, uint8_t nbytes, uint8_t checksum); |
| | | i2c_status_t sht20_read_value(i2c_dev_t *sht20, uint8_t cmd, float *value); |
| | | |
| | | /** |
| | | * @brief SHT20 初始化并软复位芯片 |
| | | * @param bus: 绑定的 I2C 物理总线指针 |
| | | * @retval 0: 成功; -1: 失败 |
| | | */ |
| | | int sht20_init(i2c_bus_t *bus) |
| | | { |
| | | uint8_t cmd = SHT20_CMD_SOFT_RESET; |
| | | int rv = 0; |
| | | |
| | | if (!bus) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | mdelay(20); |
| | | |
| | | /* 绑定设备及其设备号到 I2C 总线上 */ |
| | | i2c_bind_dev(&sht20, bus, SHT20_I2C_ADDR); |
| | | |
| | | /* 将I2C总线加锁让设备独占总线 */ |
| | | i2c_lock_dev(&sht20); |
| | | |
| | | /* 向 SHT20 发送软件复位指令,并等待复位完成 */ |
| | | i2c_write_no_reg(sht20.bus, sht20.dev_addr, &cmd, 1); |
| | | mdelay(20); |
| | | |
| | | /* 释放设备的 I2C 总线锁 */ |
| | | i2c_free_dev(&sht20); |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief 应用层温湿度采样接口函数 (带总线锁) |
| | | * @param temperature: 存放输出温度结果的指针 |
| | | * @param humidity: 存放输出湿度结果的指针 |
| | | * @retval 0: 采样成功且CRC通过; -1: 采样或校验失败 |
| | | */ |
| | | int sht20_sample_TrH(float *temperature, float *humidity) |
| | | { |
| | | int rv = -1; |
| | | |
| | | if( !temperature || !humidity ) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | /* 将I2C总线加锁让设备独占总线 */ |
| | | i2c_lock_dev(&sht20); |
| | | |
| | | /* 2. 采集温度 */ |
| | | if (sht20_read_value(&sht20, SHT20_CMD_TRIG_T, temperature) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | /* 3. 采集湿度 */ |
| | | if (sht20_read_value(&sht20, SHT20_CMD_TRIG_RH, humidity) != I2C_OK) |
| | | { |
| | | goto cleanup; |
| | | } |
| | | |
| | | rv = 0; |
| | | |
| | | cleanup: |
| | | /* 4. 释放总线并解锁 */ |
| | | i2c_free_dev(&sht20); |
| | | return rv; |
| | | } |
| | | |
| | | /** |
| | | * @brief SHT20 硬件标准 CRC-8 校验 |
| | | * @note 多项式 P(x) = x^8 + x^5 + x^4 + 1 = 1 0011 0001 = 0x31 |
| | | * @param data: 待校验的数据缓冲区指针 (含 High Byte 和 Low Byte) |
| | | * @param nbytes: 校验的数据长度 (固定为 2 字节) |
| | | * @param checksum: SHT20 芯片硬件返回的 CRC 结果字节 |
| | | * @retval 0: 校验通过; 其余值: 校验失败 |
| | | */ |
| | | static uint8_t sht20_check_crc(uint8_t *data, uint8_t nbytes, uint8_t checksum) |
| | | { |
| | | uint8_t crc = 0x00; /* 初始值为 0 */ |
| | | uint8_t byte_ctr; |
| | | uint8_t bit; |
| | | |
| | | /* 逐个字节计算 */ |
| | | for (byte_ctr = 0; byte_ctr < nbytes; ++byte_ctr) |
| | | { |
| | | crc ^= (data[byte_ctr]); |
| | | |
| | | /* 按位进行模二除法 */ |
| | | for (bit = 8; bit > 0; --bit) |
| | | { |
| | | if (crc & 0x80) |
| | | { |
| | | crc = (uint8_t)((crc << 1) ^ 0x31); |
| | | } |
| | | else |
| | | { |
| | | crc = (uint8_t)(crc << 1); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (crc != checksum) |
| | | { |
| | | return 1; /* 校验不匹配 */ |
| | | } |
| | | |
| | | return 0; /* 成功 */ |
| | | } |
| | | |
| | | /** |
| | | * @brief 读取温湿度的底层通用核心函数 (加入完备的 CRC-8 硬件校验) |
| | | */ |
| | | i2c_status_t sht20_read_value(i2c_dev_t *dev, uint8_t cmd, float *value) |
| | | { |
| | | uint8_t raw_data[2]; |
| | | uint8_t crc_byte; |
| | | uint8_t rx_buf[3]; |
| | | uint16_t raw_result; |
| | | uint32_t poll_timeout = 2000; |
| | | i2c_status_t status; |
| | | |
| | | if ( !value ) |
| | | { |
| | | return I2C_ERROR; |
| | | } |
| | | |
| | | /* 1. 发送触发测量命令 (无寄存器写模式) */ |
| | | status = i2c_write_no_reg(dev->bus, dev->dev_addr, &cmd, 1); |
| | | if (status != I2C_OK) |
| | | { |
| | | return I2C_ERROR; |
| | | } |
| | | |
| | | /* 根据测量指令进行预留的 ADC 硬件转换安全延时 */ |
| | | if (cmd == SHT20_CMD_TRIG_T) |
| | | { |
| | | mdelay(65); |
| | | } |
| | | else |
| | | { |
| | | mdelay(25); |
| | | } |
| | | |
| | | /* 2. 利用高级读 API 的内部寻址应答机制等待芯片转换完成 */ |
| | | while (poll_timeout--) |
| | | { |
| | | /* SHT20 在进行 ADC 转换时,它会对读模式寻址返回 NACK。 |
| | | * i2c_read_no_reg() 发现地址无应答,会自动发 Stop 并返回错误。 |
| | | * 我们直接利用这一机制作为非阻塞就绪判断! |
| | | */ |
| | | status = i2c_read_no_reg(dev->bus, dev->dev_addr, rx_buf, 3); |
| | | if (status == I2C_OK) |
| | | { |
| | | /* 读取成功,3 字节(高、低、CRC)*/ |
| | | break; |
| | | } |
| | | |
| | | udelay(100); |
| | | } |
| | | |
| | | if (poll_timeout == 0) |
| | | { |
| | | return I2C_ERROR; |
| | | } |
| | | |
| | | /* 3. 分离出读回的 High Byte, Low Byte 以及 CRC 校验码 */ |
| | | raw_data[0] = rx_buf[0]; |
| | | raw_data[1] = rx_buf[1]; |
| | | crc_byte = rx_buf[2]; |
| | | |
| | | /* 4. 执行 CRC-8 校验 */ |
| | | if (sht20_check_crc(raw_data, 2, crc_byte) != 0) |
| | | { |
| | | printf("SHT20 CRC Check Failed!\r\n"); |
| | | return I2C_ERROR; |
| | | } |
| | | |
| | | /* 5. 清除低 2 位状态位 */ |
| | | raw_result = (uint16_t)((raw_data[0] << 8) | raw_data[1]); |
| | | raw_result &= ~0x0003; |
| | | |
| | | /* 6. 代入物理公式转换 */ |
| | | if (cmd == SHT20_CMD_TRIG_T) |
| | | { |
| | | *value = -46.85f + 175.72f * ((float)raw_result / 65536.0f); |
| | | } |
| | | else |
| | | { |
| | | *value = -6.0f + 125.0f * ((float)raw_result / 65536.0f); |
| | | } |
| | | |
| | | return I2C_OK; |
| | | } |
| New file |
| | |
| | | /********************************************************************** |
| | | * Copyright: (C)2024 LingYun IoT System Studio |
| | | * Author: GuoWenxue<guowenxue@gmail.com> |
| | | * |
| | | * Description: SHT20 Temperature & humidity sensor driver on ISKBoard |
| | | * |
| | | * ChangeLog: |
| | | * Version Date Author Description |
| | | * V1.0.0 2024.08.29 GuoWenxue Release initial version |
| | | * |
| | | ***********************************************************************/ |
| | | |
| | | #ifndef __SHT20_H |
| | | #define __SHT20_H |
| | | |
| | | #include "i2c_bitbang.h" |
| | | |
| | | /** |
| | | * @brief SHT20 初始化并软复位芯片 |
| | | * @param bus: 绑定的 I2C 物理总线指针 |
| | | * @retval 0: 成功; -1: 失败 |
| | | */ |
| | | extern int sht20_init(i2c_bus_t *bus); |
| | | |
| | | /** |
| | | * @brief 应用层温湿度采样接口函数 |
| | | * @param temperature: 存放输出温度结果的指针 |
| | | * @param humidity: 存放输出湿度结果的指针 |
| | | * @retval 0: 采样成功且CRC通过; -1: 采样或校验失败 |
| | | */ |
| | | extern int sht20_sample_TrH(float *temperature, float *humidity); |
| | | |
| | | #endif |
| New file |
| | |
| | | cmake_minimum_required(VERSION 3.22) |
| | | |
| | | # |
| | | # This file is generated only once, |
| | | # and is not re-generated if converter is called multiple times. |
| | | # |
| | | # User is free to modify the file as much as necessary |
| | | # |
| | | |
| | | # Setup compiler settings |
| | | set(CMAKE_C_STANDARD 11) |
| | | set(CMAKE_C_STANDARD_REQUIRED ON) |
| | | set(CMAKE_C_EXTENSIONS ON) |
| | | |
| | | |
| | | # Define the build type |
| | | if(NOT CMAKE_BUILD_TYPE) |
| | | set(CMAKE_BUILD_TYPE "Debug") |
| | | endif() |
| | | |
| | | # Set the project name |
| | | set(CMAKE_PROJECT_NAME ISKBoard) |
| | | |
| | | # Enable compile command to ease indexing with e.g. clangd |
| | | set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) |
| | | |
| | | # Core project settings |
| | | project(${CMAKE_PROJECT_NAME}) |
| | | message("Build type: " ${CMAKE_BUILD_TYPE}) |
| | | |
| | | # Enable CMake support for ASM and C languages |
| | | enable_language(C ASM) |
| | | |
| | | # Create an executable object type |
| | | add_executable(${CMAKE_PROJECT_NAME}) |
| | | |
| | | # Add STM32CubeMX generated sources |
| | | add_subdirectory(cmake/stm32cubemx) |
| | | |
| | | # Add our custom module subdirectories here |
| | | add_subdirectory(Board) |
| | | |
| | | # Link directories setup |
| | | target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE |
| | | # Add user defined library search paths |
| | | ) |
| | | |
| | | # Add sources to executable |
| | | target_sources(${CMAKE_PROJECT_NAME} PRIVATE |
| | | # Add user sources here |
| | | ) |
| | | |
| | | # Add include paths |
| | | target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE |
| | | # Add user defined include paths |
| | | ) |
| | | |
| | | # Add project symbols (macros) |
| | | target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE |
| | | # Add user defined symbols |
| | | ) |
| | | |
| | | # Remove wrong libob.a library dependency when using cpp files |
| | | list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_LIBRARIES ob) |
| | | |
| | | # Add linked libraries |
| | | target_link_libraries(${CMAKE_PROJECT_NAME} |
| | | stm32cubemx |
| | | board |
| | | |
| | | # Add user defined libraries |
| | | ) |
| | | |
| | | # Setup linker settings |
| | | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u _printf_float") |
| New file |
| | |
| | | /* USER CODE BEGIN Header */ |
| | | /** |
| | | ****************************************************************************** |
| | | * @file : main.c |
| | | * @brief : Main program body |
| | | ****************************************************************************** |
| | | * @attention |
| | | * |
| | | * Copyright (c) 2026 STMicroelectronics. |
| | | * All rights reserved. |
| | | * |
| | | * This software is licensed under terms that can be found in the LICENSE file |
| | | * in the root directory of this software component. |
| | | * If no LICENSE file comes with this software, it is provided AS-IS. |
| | | * |
| | | ****************************************************************************** |
| | | */ |
| | | /* USER CODE END Header */ |
| | | /* Includes ------------------------------------------------------------------*/ |
| | | #include "main.h" |
| | | #include "adc.h" |
| | | #include "tim.h" |
| | | #include "usart.h" |
| | | #include "gpio.h" |
| | | |
| | | /* Private includes ----------------------------------------------------------*/ |
| | | /* USER CODE BEGIN Includes */ |
| | | #include "miscdev.h" |
| | | #include "sht20.h" |
| | | #include "ds18b20.h" |
| | | #include "isl1208.h" |
| | | #include "oled_drv.h" |
| | | #include "oled_font.h" |
| | | /* USER CODE END Includes */ |
| | | |
| | | /* Private typedef -----------------------------------------------------------*/ |
| | | /* USER CODE BEGIN PTD */ |
| | | |
| | | /* USER CODE END PTD */ |
| | | |
| | | /* Private define ------------------------------------------------------------*/ |
| | | /* USER CODE BEGIN PD */ |
| | | |
| | | /* USER CODE END PD */ |
| | | |
| | | /* Private macro -------------------------------------------------------------*/ |
| | | /* USER CODE BEGIN PM */ |
| | | |
| | | /* USER CODE END PM */ |
| | | |
| | | /* Private variables ---------------------------------------------------------*/ |
| | | |
| | | /* USER CODE BEGIN PV */ |
| | | |
| | | /* USER CODE END PV */ |
| | | |
| | | /* Private function prototypes -----------------------------------------------*/ |
| | | void SystemClock_Config(void); |
| | | /* USER CODE BEGIN PFP */ |
| | | |
| | | /* USER CODE END PFP */ |
| | | |
| | | /* Private user code ---------------------------------------------------------*/ |
| | | /* USER CODE BEGIN 0 */ |
| | | |
| | | /** |
| | | * @brief OLED显示时间 |
| | | */ |
| | | void oled_show_time(void) |
| | | { |
| | | rtc_time_t tm; |
| | | char buf[64]; |
| | | |
| | | /* 获取RTC时间并保存到 buf */ |
| | | isl1208_get_time(&tm); |
| | | snprintf(buf, sizeof(buf), "20%02d-%02d-%02d %02d:%02d:%02d", |
| | | tm.year, tm.month, tm.day, |
| | | tm.hour, tm.minute, tm.second); |
| | | |
| | | /* 输出显示内容 OLED 屏幕上 */ |
| | | OLED_Clear(); |
| | | OLED_ShowString(10, OLED_PAGE2, buf, OLED_FONT8); |
| | | OLED_Refresh(); |
| | | |
| | | return; |
| | | } |
| | | |
| | | void oled_show_rh(void) |
| | | { |
| | | float temperature = 0.0; |
| | | float humidity = 0.0; |
| | | char buf[64]; |
| | | |
| | | /* 采样并输出显示内容到 buf */ |
| | | sht20_sample_TrH(&temperature, &humidity); |
| | | snprintf(buf, sizeof(buf), "%.2f'C %.2f%%RH", temperature, humidity); |
| | | |
| | | /* 输出显示内容 OLED 屏幕上 */ |
| | | OLED_Clear(); |
| | | OLED_ShowString(10, OLED_PAGE2, buf, OLED_FONT8); |
| | | OLED_Refresh(); |
| | | |
| | | return; |
| | | } |
| | | |
| | | void oled_show_logo(void) |
| | | { |
| | | /* 输出显示内容 OLED 屏幕上 */ |
| | | OLED_Clear(); |
| | | OLED_DrawBMP(0, OLED_PAGE0, BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, bmp_logo); |
| | | OLED_Refresh(); |
| | | |
| | | return; |
| | | } |
| | | |
| | | /* USER CODE END 0 */ |
| | | |
| | | /** |
| | | * @brief The application entry point. |
| | | * @retval int |
| | | */ |
| | | int main(void) |
| | | { |
| | | |
| | | /* USER CODE BEGIN 1 */ |
| | | float temperature; |
| | | /* 各个任务的计时基准 */ |
| | | uint32_t now = 0; |
| | | uint32_t last_time_tick = 0; |
| | | uint32_t last_rh_tick = 0; |
| | | uint32_t last_logo_tick = 0; |
| | | uint32_t display_unlock_time = 0; |
| | | |
| | | /* USER CODE END 1 */ |
| | | |
| | | /* MCU Configuration--------------------------------------------------------*/ |
| | | |
| | | /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ |
| | | HAL_Init(); |
| | | |
| | | /* USER CODE BEGIN Init */ |
| | | |
| | | /* USER CODE END Init */ |
| | | |
| | | /* Configure the system clock */ |
| | | SystemClock_Config(); |
| | | |
| | | /* USER CODE BEGIN SysInit */ |
| | | |
| | | /* USER CODE END SysInit */ |
| | | |
| | | /* Initialize all configured peripherals */ |
| | | MX_GPIO_Init(); |
| | | MX_USART1_UART_Init(); |
| | | MX_ADC1_Init(); |
| | | MX_TIM6_Init(); |
| | | MX_TIM1_Init(); |
| | | /* USER CODE BEGIN 2 */ |
| | | init_led(); |
| | | i2c_init(&i2c1_bus); |
| | | |
| | | beep_start(2, 300); |
| | | printf("ISKBoard: I2C Bitbang Drivers Demo.\r\n"); |
| | | |
| | | if( sht20_init(&i2c1_bus) != 0 ) |
| | | { |
| | | printf("SHT20 Sensor init failed!\r\n"); |
| | | } |
| | | |
| | | if( isl1208_init(&i2c1_bus) != 0 ) |
| | | { |
| | | printf("ISL1208 RTC init failed!\r\n"); |
| | | } |
| | | isl1208_set_time_str("2026-07-09 21:15:30"); |
| | | |
| | | if( OLED_Init(&i2c1_bus) != 0 ) |
| | | { |
| | | printf("OLED display init failed!\r\n"); |
| | | } |
| | | |
| | | OLED_Clear(); |
| | | OLED_ShowString(30, OLED_PAGE2, "ISKBoard", OLED_FONT16); |
| | | OLED_Refresh(); |
| | | |
| | | ds18b20_sample(&temperature); |
| | | printf("DS18B20 sample temperature: %.2f'C\r\n", temperature); |
| | | |
| | | /* USER CODE END 2 */ |
| | | |
| | | /* Infinite loop */ |
| | | /* USER CODE BEGIN WHILE */ |
| | | while (1) |
| | | { |
| | | /* 获取当前系统时间 */ |
| | | now = HAL_GetTick(); |
| | | |
| | | /* 心跳灯任务:不需要锁屏,始终高频调用 */ |
| | | heartbeat_led(3); |
| | | |
| | | /* 检查屏幕是否处于“锁定”状态 (正在显示温湿度或Logo) */ |
| | | if (now >= display_unlock_time) |
| | | { |
| | | /* 优先检查是否有高优先级任务触发 (Logo -> 温湿度) */ |
| | | uint8_t is_displaying = 0; |
| | | |
| | | /* 每隔 13s 显示 Logo,持续 1s */ |
| | | if (now - last_logo_tick >= 13000) |
| | | { |
| | | oled_show_logo(); // 执行显示 |
| | | last_logo_tick = now; // 重置Logo计时器 |
| | | display_unlock_time = now + 1000; |
| | | is_displaying = 1; |
| | | } |
| | | |
| | | /* 如果Logo刚显示了,本轮跳过温湿度 */ |
| | | else if (now - last_rh_tick >= 5000) |
| | | { |
| | | oled_show_rh(); // 执行显示 |
| | | last_rh_tick = now; // 重置温湿度计时器 |
| | | display_unlock_time = now + 2000; // 锁屏 2s |
| | | is_displaying = 1; |
| | | } |
| | | |
| | | /* 如果上面都没有显示特殊内容,则显示时间 */ |
| | | if (is_displaying == 0) |
| | | { |
| | | if (now - last_time_tick >= 1000) |
| | | { |
| | | oled_show_time(); // 执行显示 |
| | | last_time_tick = now; // 重置时间计时器 |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* USER CODE END WHILE */ |
| | | |
| | | /* USER CODE BEGIN 3 */ |
| | | } |
| | | /* USER CODE END 3 */ |
| | | } |
| | | |
| | | /** |
| | | * @brief System Clock Configuration |
| | | * @retval None |
| | | */ |
| | | void SystemClock_Config(void) |
| | | { |
| | | RCC_OscInitTypeDef RCC_OscInitStruct = {0}; |
| | | RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; |
| | | |
| | | /** Configure the main internal regulator output voltage |
| | | */ |
| | | if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) |
| | | { |
| | | Error_Handler(); |
| | | } |
| | | |
| | | /** Initializes the RCC Oscillators according to the specified parameters |
| | | * in the RCC_OscInitTypeDef structure. |
| | | */ |
| | | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; |
| | | RCC_OscInitStruct.HSEState = RCC_HSE_ON; |
| | | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; |
| | | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; |
| | | RCC_OscInitStruct.PLL.PLLM = 1; |
| | | RCC_OscInitStruct.PLL.PLLN = 20; |
| | | RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; |
| | | RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; |
| | | RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; |
| | | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) |
| | | { |
| | | Error_Handler(); |
| | | } |
| | | |
| | | /** Initializes the CPU, AHB and APB buses clocks |
| | | */ |
| | | RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |
| | | |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; |
| | | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; |
| | | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; |
| | | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; |
| | | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; |
| | | |
| | | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) |
| | | { |
| | | Error_Handler(); |
| | | } |
| | | } |
| | | |
| | | /* USER CODE BEGIN 4 */ |
| | | |
| | | /* USER CODE END 4 */ |
| | | |
| | | /** |
| | | * @brief This function is executed in case of error occurrence. |
| | | * @retval None |
| | | */ |
| | | void Error_Handler(void) |
| | | { |
| | | /* USER CODE BEGIN Error_Handler_Debug */ |
| | | /* User can add his own implementation to report the HAL error return state */ |
| | | __disable_irq(); |
| | | while (1) |
| | | { |
| | | } |
| | | /* USER CODE END Error_Handler_Debug */ |
| | | } |
| | | #ifdef USE_FULL_ASSERT |
| | | /** |
| | | * @brief Reports the name of the source file and the source line number |
| | | * where the assert_param error has occurred. |
| | | * @param file: pointer to the source file name |
| | | * @param line: assert_param error line source number |
| | | * @retval None |
| | | */ |
| | | void assert_failed(uint8_t *file, uint32_t line) |
| | | { |
| | | /* USER CODE BEGIN 6 */ |
| | | /* User can add his own implementation to report the file name and line number, |
| | | ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ |
| | | /* USER CODE END 6 */ |
| | | } |
| | | #endif /* USE_FULL_ASSERT */ |
| New file |
| | |
| | | #MicroXplorer Configuration settings - do not modify |
| | | ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_15 |
| | | ADC1.CommonPathInternal=null|null|null|null |
| | | ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,NbrOfConversion,CommonPathInternal |
| | | ADC1.NbrOfConversion=1 |
| | | ADC1.NbrOfConversionFlag=1 |
| | | ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE |
| | | ADC1.Rank-0\#ChannelRegularConversion=1 |
| | | ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5 |
| | | ADC1.master=1 |
| | | CAD.formats= |
| | | CAD.pinconfig= |
| | | CAD.provider= |
| | | File.Version=6 |
| | | GPIO.groupedBy=Group By Peripherals |
| | | KeepUserPlacement=false |
| | | Mcu.CPN=STM32L431RCT6 |
| | | Mcu.Family=STM32L4 |
| | | Mcu.IP0=ADC1 |
| | | Mcu.IP1=NVIC |
| | | Mcu.IP2=RCC |
| | | Mcu.IP3=SYS |
| | | Mcu.IP4=TIM1 |
| | | Mcu.IP5=TIM6 |
| | | Mcu.IP6=USART1 |
| | | Mcu.IPNb=7 |
| | | Mcu.Name=STM32L431R(B-C)Tx |
| | | Mcu.Package=LQFP64 |
| | | Mcu.Pin0=PC14-OSC32_IN (PC14) |
| | | Mcu.Pin1=PC15-OSC32_OUT (PC15) |
| | | Mcu.Pin10=PC6 |
| | | Mcu.Pin11=PC9 |
| | | Mcu.Pin12=PA9 |
| | | Mcu.Pin13=PA10 |
| | | Mcu.Pin14=PA11 |
| | | Mcu.Pin15=PD2 |
| | | Mcu.Pin16=VP_SYS_VS_Systick |
| | | Mcu.Pin17=VP_TIM6_VS_ClockSourceINT |
| | | Mcu.Pin2=PH0-OSC_IN (PH0) |
| | | Mcu.Pin3=PH1-OSC_OUT (PH1) |
| | | Mcu.Pin4=PB0 |
| | | Mcu.Pin5=PB1 |
| | | Mcu.Pin6=PB2 |
| | | Mcu.Pin7=PB12 |
| | | Mcu.Pin8=PB13 |
| | | Mcu.Pin9=PB14 |
| | | Mcu.PinsNb=18 |
| | | Mcu.ThirdPartyNb=0 |
| | | Mcu.UserConstants= |
| | | Mcu.UserName=STM32L431RCTx |
| | | MxCube.Version=6.18.0 |
| | | MxDb.Version=DB.6.0.180 |
| | | NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false |
| | | NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false |
| | | NVIC.EXTI15_10_IRQn=true\:2\:0\:true\:false\:true\:true\:true\:true |
| | | NVIC.ForceEnableDMAVector=true |
| | | NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false |
| | | NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false |
| | | NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false |
| | | NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false |
| | | NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 |
| | | NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false |
| | | NVIC.SysTick_IRQn=true\:1\:0\:true\:false\:true\:false\:true\:false |
| | | NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false |
| | | PA10.Mode=Asynchronous |
| | | PA10.Signal=USART1_RX |
| | | PA11.GPIOParameters=GPIO_PuPd |
| | | PA11.GPIO_PuPd=GPIO_PULLDOWN |
| | | PA11.Locked=true |
| | | PA11.Signal=S_TIM1_CH4 |
| | | PA9.Mode=Asynchronous |
| | | PA9.Signal=USART1_TX |
| | | PB0.Signal=ADCx_IN15 |
| | | PB1.Signal=ADCx_IN16 |
| | | PB12.GPIOParameters=GPIO_ModeDefaultEXTI |
| | | PB12.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING |
| | | PB12.Locked=true |
| | | PB12.Signal=GPXTI12 |
| | | PB13.GPIOParameters=GPIO_ModeDefaultEXTI |
| | | PB13.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING |
| | | PB13.Locked=true |
| | | PB13.Signal=GPXTI13 |
| | | PB14.GPIOParameters=GPIO_ModeDefaultEXTI |
| | | PB14.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING |
| | | PB14.Locked=true |
| | | PB14.Signal=GPXTI14 |
| | | PB2.Locked=true |
| | | PB2.Signal=GPIO_Output |
| | | PC14-OSC32_IN\ (PC14).Mode=LSE-External-Oscillator |
| | | PC14-OSC32_IN\ (PC14).Signal=RCC_OSC32_IN |
| | | PC15-OSC32_OUT\ (PC15).Mode=LSE-External-Oscillator |
| | | PC15-OSC32_OUT\ (PC15).Signal=RCC_OSC32_OUT |
| | | PC6.Locked=true |
| | | PC6.Signal=GPIO_Output |
| | | PC9.Locked=true |
| | | PC9.Signal=GPIO_Output |
| | | PD2.Locked=true |
| | | PD2.Signal=GPIO_Output |
| | | PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator |
| | | PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN |
| | | PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator |
| | | PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT |
| | | PinOutPanel.RotationAngle=0 |
| | | ProjectManager.AskForMigrate=true |
| | | ProjectManager.BackupPrevious=false |
| | | ProjectManager.CompilerLinker=GCC |
| | | ProjectManager.CompilerOptimize=6 |
| | | ProjectManager.ComputerToolchain=false |
| | | ProjectManager.CoupleFile=true |
| | | ProjectManager.CustomerFirmwarePackage= |
| | | ProjectManager.DefaultFWLocation=true |
| | | ProjectManager.DeletePrevious=true |
| | | ProjectManager.DeviceId=STM32L431RCTx |
| | | ProjectManager.FirmwarePackage=STM32Cube FW_L4 V1.18.2 |
| | | ProjectManager.FreePins=false |
| | | ProjectManager.FreePinsContext= |
| | | ProjectManager.HalAssertFull=false |
| | | ProjectManager.HeapSize=0x200 |
| | | ProjectManager.KeepUserCode=true |
| | | ProjectManager.LastFirmware=true |
| | | ProjectManager.LibraryCopy=1 |
| | | ProjectManager.MainLocation=Core/Src |
| | | ProjectManager.NoMain=false |
| | | ProjectManager.PreviousToolchain= |
| | | ProjectManager.ProjectBuild=false |
| | | ProjectManager.ProjectFileName=ISKBoard.ioc |
| | | ProjectManager.ProjectName=ISKBoard |
| | | ProjectManager.ProjectStructure= |
| | | ProjectManager.RegisterCallBack= |
| | | ProjectManager.StackSize=0x400 |
| | | ProjectManager.TargetToolchain=CMake |
| | | ProjectManager.ToolChainLocation= |
| | | ProjectManager.UAScriptAfterPath= |
| | | ProjectManager.UAScriptBeforePath= |
| | | ProjectManager.UnderRoot=false |
| | | ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM6_Init-TIM6-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true |
| | | RCC.ADCFreq_Value=32000000 |
| | | RCC.AHBFreq_Value=80000000 |
| | | RCC.APB1Freq_Value=80000000 |
| | | RCC.APB1TimFreq_Value=80000000 |
| | | RCC.APB2Freq_Value=80000000 |
| | | RCC.APB2TimFreq_Value=80000000 |
| | | RCC.CortexFreq_Value=80000000 |
| | | RCC.FCLKCortexFreq_Value=80000000 |
| | | RCC.FamilyName=M |
| | | RCC.HCLKFreq_Value=80000000 |
| | | RCC.HSE_VALUE=8000000 |
| | | RCC.HSI48_VALUE=48000000 |
| | | RCC.HSI_VALUE=16000000 |
| | | RCC.I2C1Freq_Value=80000000 |
| | | RCC.I2C2Freq_Value=80000000 |
| | | RCC.I2C3Freq_Value=80000000 |
| | | RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,MSI_VALUE,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PLLSourceVirtual,PWRFreq_Value,RNGFreq_Value,SAI1Freq_Value,SDMMCFreq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value |
| | | RCC.LPTIM1Freq_Value=80000000 |
| | | RCC.LPTIM2Freq_Value=80000000 |
| | | RCC.LPUART1Freq_Value=80000000 |
| | | RCC.LSCOPinFreq_Value=32000 |
| | | RCC.LSI_VALUE=32000 |
| | | RCC.MCO1PinFreq_Value=80000000 |
| | | RCC.MSI_VALUE=4000000 |
| | | RCC.PLLN=20 |
| | | RCC.PLLPoutputFreq_Value=22857142.85714286 |
| | | RCC.PLLQoutputFreq_Value=80000000 |
| | | RCC.PLLRCLKFreq_Value=80000000 |
| | | RCC.PLLSAI1PoutputFreq_Value=9142857.142857144 |
| | | RCC.PLLSAI1QoutputFreq_Value=32000000 |
| | | RCC.PLLSAI1RoutputFreq_Value=32000000 |
| | | RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE |
| | | RCC.PWRFreq_Value=80000000 |
| | | RCC.RNGFreq_Value=32000000 |
| | | RCC.SAI1Freq_Value=9142857.142857144 |
| | | RCC.SDMMCFreq_Value=32000000 |
| | | RCC.SWPMI1Freq_Value=80000000 |
| | | RCC.SYSCLKFreq_VALUE=80000000 |
| | | RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK |
| | | RCC.USART1Freq_Value=80000000 |
| | | RCC.USART2Freq_Value=80000000 |
| | | RCC.USART3Freq_Value=80000000 |
| | | RCC.VCOInputFreq_Value=8000000 |
| | | RCC.VCOOutputFreq_Value=160000000 |
| | | RCC.VCOSAI1OutputFreq_Value=64000000 |
| | | SH.ADCx_IN15.0=ADC1_IN15,IN15-Single-Ended |
| | | SH.ADCx_IN15.ConfNb=1 |
| | | SH.ADCx_IN16.0=ADC1_IN16,IN16-Single-Ended |
| | | SH.ADCx_IN16.ConfNb=1 |
| | | SH.GPXTI12.0=GPIO_EXTI12 |
| | | SH.GPXTI12.ConfNb=1 |
| | | SH.GPXTI13.0=GPIO_EXTI13 |
| | | SH.GPXTI13.ConfNb=1 |
| | | SH.GPXTI14.0=GPIO_EXTI14 |
| | | SH.GPXTI14.ConfNb=1 |
| | | SH.S_TIM1_CH4.0=TIM1_CH4,PWM Generation4 CH4 |
| | | SH.S_TIM1_CH4.ConfNb=1 |
| | | TIM1.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 |
| | | TIM1.IPParameters=Channel-PWM Generation4 CH4,Prescaler,RepetitionCounter,Period,Pulse-PWM Generation4 CH4 |
| | | TIM1.Period=370-1 |
| | | TIM1.Prescaler=80-1 |
| | | TIM1.Pulse-PWM\ Generation4\ CH4=185 |
| | | TIM1.RepetitionCounter=0 |
| | | TIM6.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_DISABLE |
| | | TIM6.IPParameters=Prescaler,Period,AutoReloadPreload |
| | | TIM6.Period=1 |
| | | TIM6.Prescaler=80-1 |
| | | USART1.IPParameters=VirtualMode-Asynchronous |
| | | USART1.VirtualMode-Asynchronous=VM_ASYNC |
| | | VP_SYS_VS_Systick.Mode=SysTick |
| | | VP_SYS_VS_Systick.Signal=SYS_VS_Systick |
| | | VP_TIM6_VS_ClockSourceINT.Mode=Enable_Timer |
| | | VP_TIM6_VS_ClockSourceINT.Signal=TIM6_VS_ClockSourceINT |
| | | board=custom |
| New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8" standalone="no" ?> |
| | | <ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd"> |
| | | |
| | | <SchemaVersion>1.0</SchemaVersion> |
| | | |
| | | <Header>### uVision Project, (C) Keil Software</Header> |
| | | |
| | | <Extensions> |
| | | <cExt>*.c</cExt> |
| | | <aExt>*.s*; *.src; *.a*</aExt> |
| | | <oExt>*.obj; *.o</oExt> |
| | | <lExt>*.lib</lExt> |
| | | <tExt>*.txt; *.h; *.inc; *.md</tExt> |
| | | <pExt>*.plm</pExt> |
| | | <CppX>*.cpp</CppX> |
| | | <nMigrate>0</nMigrate> |
| | | </Extensions> |
| | | |
| | | <DaveTm> |
| | | <dwLowDateTime>0</dwLowDateTime> |
| | | <dwHighDateTime>0</dwHighDateTime> |
| | | </DaveTm> |
| | | |
| | | <Target> |
| | | <TargetName>ISKBoard</TargetName> |
| | | <ToolsetNumber>0x4</ToolsetNumber> |
| | | <ToolsetName>ARM-ADS</ToolsetName> |
| | | <TargetOption> |
| | | <CLKADS>8000000</CLKADS> |
| | | <OPTTT> |
| | | <gFlags>1</gFlags> |
| | | <BeepAtEnd>1</BeepAtEnd> |
| | | <RunSim>0</RunSim> |
| | | <RunTarget>1</RunTarget> |
| | | <RunAbUc>0</RunAbUc> |
| | | </OPTTT> |
| | | <OPTHX> |
| | | <HexSelection>1</HexSelection> |
| | | <FlashByte>65535</FlashByte> |
| | | <HexRangeLowAddress>0</HexRangeLowAddress> |
| | | <HexRangeHighAddress>0</HexRangeHighAddress> |
| | | <HexOffset>0</HexOffset> |
| | | </OPTHX> |
| | | <OPTLEX> |
| | | <PageWidth>79</PageWidth> |
| | | <PageLength>66</PageLength> |
| | | <TabStop>8</TabStop> |
| | | <ListingPath></ListingPath> |
| | | </OPTLEX> |
| | | <ListingPage> |
| | | <CreateCListing>1</CreateCListing> |
| | | <CreateAListing>1</CreateAListing> |
| | | <CreateLListing>1</CreateLListing> |
| | | <CreateIListing>0</CreateIListing> |
| | | <AsmCond>1</AsmCond> |
| | | <AsmSymb>1</AsmSymb> |
| | | <AsmXref>0</AsmXref> |
| | | <CCond>1</CCond> |
| | | <CCode>0</CCode> |
| | | <CListInc>0</CListInc> |
| | | <CSymb>0</CSymb> |
| | | <LinkerCodeListing>0</LinkerCodeListing> |
| | | </ListingPage> |
| | | <OPTXL> |
| | | <LMap>1</LMap> |
| | | <LComments>1</LComments> |
| | | <LGenerateSymbols>1</LGenerateSymbols> |
| | | <LLibSym>1</LLibSym> |
| | | <LLines>1</LLines> |
| | | <LLocSym>1</LLocSym> |
| | | <LPubSym>1</LPubSym> |
| | | <LXref>0</LXref> |
| | | <LExpSel>0</LExpSel> |
| | | </OPTXL> |
| | | <OPTFL> |
| | | <tvExp>1</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <IsCurrentTarget>1</IsCurrentTarget> |
| | | </OPTFL> |
| | | <CpuCode>18</CpuCode> |
| | | <DebugOpt> |
| | | <uSim>0</uSim> |
| | | <uTrg>1</uTrg> |
| | | <sLdApp>1</sLdApp> |
| | | <sGomain>1</sGomain> |
| | | <sRbreak>1</sRbreak> |
| | | <sRwatch>1</sRwatch> |
| | | <sRmem>1</sRmem> |
| | | <sRfunc>1</sRfunc> |
| | | <sRbox>1</sRbox> |
| | | <tLdApp>1</tLdApp> |
| | | <tGomain>1</tGomain> |
| | | <tRbreak>1</tRbreak> |
| | | <tRwatch>1</tRwatch> |
| | | <tRmem>1</tRmem> |
| | | <tRfunc>1</tRfunc> |
| | | <tRbox>1</tRbox> |
| | | <tRtrace>1</tRtrace> |
| | | <sRSysVw>1</sRSysVw> |
| | | <tRSysVw>1</tRSysVw> |
| | | <sRunDeb>0</sRunDeb> |
| | | <sLrtime>0</sLrtime> |
| | | <bEvRecOn>1</bEvRecOn> |
| | | <bSchkAxf>0</bSchkAxf> |
| | | <bTchkAxf>0</bTchkAxf> |
| | | <nTsel>6</nTsel> |
| | | <sDll></sDll> |
| | | <sDllPa></sDllPa> |
| | | <sDlgDll></sDlgDll> |
| | | <sDlgPa></sDlgPa> |
| | | <sIfile></sIfile> |
| | | <tDll></tDll> |
| | | <tDllPa></tDllPa> |
| | | <tDlgDll></tDlgDll> |
| | | <tDlgPa></tDlgPa> |
| | | <tIfile></tIfile> |
| | | <pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon> |
| | | </DebugOpt> |
| | | <TargetDriverDllRegistry> |
| | | <SetRegEntry> |
| | | <Number>0</Number> |
| | | <Key>ARMRTXEVENTFLAGS</Key> |
| | | <Name>-L70 -Z18 -C0 -M0 -T1</Name> |
| | | </SetRegEntry> |
| | | <SetRegEntry> |
| | | <Number>0</Number> |
| | | <Key>DLGTARM</Key> |
| | | <Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)</Name> |
| | | </SetRegEntry> |
| | | <SetRegEntry> |
| | | <Number>0</Number> |
| | | <Key>ARMDBGFLAGS</Key> |
| | | <Name></Name> |
| | | </SetRegEntry> |
| | | <SetRegEntry> |
| | | <Number>0</Number> |
| | | <Key>DLGUARM</Key> |
| | | <Name>(105=-1,-1,-1,-1,0)</Name> |
| | | </SetRegEntry> |
| | | <SetRegEntry> |
| | | <Number>0</Number> |
| | | <Key>UL2CM3</Key> |
| | | <Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0STM32L4xx_256 -FS08000000 -FL040000 -FP0($$Device:STM32L431RCTx$CMSIS\Flash\STM32L4xx_256.FLM))</Name> |
| | | </SetRegEntry> |
| | | <SetRegEntry> |
| | | <Number>0</Number> |
| | | <Key>ST-LINKIII-KEIL_SWO</Key> |
| | | <Name>-U53FF69064885495006370487 -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256.FLM -FS08000000 -FL040000 -FP0($$Device:STM32L431RCTx$CMSIS\Flash\STM32L4xx_256.FLM)</Name> |
| | | </SetRegEntry> |
| | | </TargetDriverDllRegistry> |
| | | <Breakpoint> |
| | | <Bp> |
| | | <Number>0</Number> |
| | | <Type>0</Type> |
| | | <LineNumber>95</LineNumber> |
| | | <EnabledFlag>1</EnabledFlag> |
| | | <Address>0</Address> |
| | | <ByteObject>0</ByteObject> |
| | | <HtxType>0</HtxType> |
| | | <ManyObjects>0</ManyObjects> |
| | | <SizeOfObject>0</SizeOfObject> |
| | | <BreakByAccess>0</BreakByAccess> |
| | | <BreakIfRCount>0</BreakIfRCount> |
| | | <Filename>../Core/Src/main.c</Filename> |
| | | <ExecCommand></ExecCommand> |
| | | <Expression></Expression> |
| | | </Bp> |
| | | <Bp> |
| | | <Number>1</Number> |
| | | <Type>0</Type> |
| | | <LineNumber>97</LineNumber> |
| | | <EnabledFlag>1</EnabledFlag> |
| | | <Address>0</Address> |
| | | <ByteObject>0</ByteObject> |
| | | <HtxType>0</HtxType> |
| | | <ManyObjects>0</ManyObjects> |
| | | <SizeOfObject>0</SizeOfObject> |
| | | <BreakByAccess>0</BreakByAccess> |
| | | <BreakIfRCount>0</BreakIfRCount> |
| | | <Filename>../Core/Src/main.c</Filename> |
| | | <ExecCommand></ExecCommand> |
| | | <Expression></Expression> |
| | | </Bp> |
| | | </Breakpoint> |
| | | <Tracepoint> |
| | | <THDelay>0</THDelay> |
| | | </Tracepoint> |
| | | <DebugFlag> |
| | | <trace>0</trace> |
| | | <periodic>1</periodic> |
| | | <aLwin>1</aLwin> |
| | | <aCover>0</aCover> |
| | | <aSer1>0</aSer1> |
| | | <aSer2>0</aSer2> |
| | | <aPa>0</aPa> |
| | | <viewmode>1</viewmode> |
| | | <vrSel>0</vrSel> |
| | | <aSym>0</aSym> |
| | | <aTbox>0</aTbox> |
| | | <AscS1>0</AscS1> |
| | | <AscS2>0</AscS2> |
| | | <AscS3>0</AscS3> |
| | | <aSer3>0</aSer3> |
| | | <eProf>0</eProf> |
| | | <aLa>0</aLa> |
| | | <aPa1>0</aPa1> |
| | | <AscS4>0</AscS4> |
| | | <aSer4>0</aSer4> |
| | | <StkLoc>1</StkLoc> |
| | | <TrcWin>0</TrcWin> |
| | | <newCpu>0</newCpu> |
| | | <uProt>0</uProt> |
| | | </DebugFlag> |
| | | <LintExecutable></LintExecutable> |
| | | <LintConfigFile></LintConfigFile> |
| | | <bLintAuto>0</bLintAuto> |
| | | <bAutoGenD>0</bAutoGenD> |
| | | <LntExFlags>0</LntExFlags> |
| | | <pMisraName></pMisraName> |
| | | <pszMrule></pszMrule> |
| | | <pSingCmds></pSingCmds> |
| | | <pMultCmds></pMultCmds> |
| | | <pMisraNamep></pMisraNamep> |
| | | <pszMrulep></pszMrulep> |
| | | <pSingCmdsp></pSingCmdsp> |
| | | <pMultCmdsp></pMultCmdsp> |
| | | <DebugDescription> |
| | | <Enable>1</Enable> |
| | | <EnableFlashSeq>0</EnableFlashSeq> |
| | | <EnableLog>0</EnableLog> |
| | | <Protocol>2</Protocol> |
| | | <DbgClock>10000000</DbgClock> |
| | | </DebugDescription> |
| | | </TargetOption> |
| | | </Target> |
| | | |
| | | <Group> |
| | | <GroupName>Application/MDK-ARM</GroupName> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <cbSel>0</cbSel> |
| | | <RteFlg>0</RteFlg> |
| | | <File> |
| | | <GroupNumber>1</GroupNumber> |
| | | <FileNumber>1</FileNumber> |
| | | <FileType>2</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>startup_stm32l431xx.s</PathWithFileName> |
| | | <FilenameWithoutPath>startup_stm32l431xx.s</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | </Group> |
| | | |
| | | <Group> |
| | | <GroupName>Application/User/Core</GroupName> |
| | | <tvExp>1</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <cbSel>0</cbSel> |
| | | <RteFlg>0</RteFlg> |
| | | <File> |
| | | <GroupNumber>2</GroupNumber> |
| | | <FileNumber>2</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Core/Src/main.c</PathWithFileName> |
| | | <FilenameWithoutPath>main.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>2</GroupNumber> |
| | | <FileNumber>3</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Core/Src/gpio.c</PathWithFileName> |
| | | <FilenameWithoutPath>gpio.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>2</GroupNumber> |
| | | <FileNumber>4</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Core/Src/adc.c</PathWithFileName> |
| | | <FilenameWithoutPath>adc.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>2</GroupNumber> |
| | | <FileNumber>5</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Core/Src/tim.c</PathWithFileName> |
| | | <FilenameWithoutPath>tim.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>2</GroupNumber> |
| | | <FileNumber>6</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Core/Src/usart.c</PathWithFileName> |
| | | <FilenameWithoutPath>usart.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>2</GroupNumber> |
| | | <FileNumber>7</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Core/Src/stm32l4xx_it.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_it.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>2</GroupNumber> |
| | | <FileNumber>8</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Core/Src/stm32l4xx_hal_msp.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_msp.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | </Group> |
| | | |
| | | <Group> |
| | | <GroupName>Drivers/STM32L4xx_HAL_Driver</GroupName> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <cbSel>0</cbSel> |
| | | <RteFlg>0</RteFlg> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>9</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_adc.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>10</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_adc_ex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>11</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>12</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_rcc.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>13</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_rcc_ex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>14</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_flash.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>15</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_flash_ex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>16</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_flash_ramfunc.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>17</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_gpio.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>18</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_i2c.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>19</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_i2c_ex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>20</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_dma.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>21</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_dma_ex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>22</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_pwr.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>23</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_pwr_ex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>24</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_cortex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>25</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_exti.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>26</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_tim.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>27</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_tim_ex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>28</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_uart.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>3</GroupNumber> |
| | | <FileNumber>29</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c</PathWithFileName> |
| | | <FilenameWithoutPath>stm32l4xx_hal_uart_ex.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | </Group> |
| | | |
| | | <Group> |
| | | <GroupName>Drivers/CMSIS</GroupName> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <cbSel>0</cbSel> |
| | | <RteFlg>0</RteFlg> |
| | | <File> |
| | | <GroupNumber>4</GroupNumber> |
| | | <FileNumber>30</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>../Core/Src/system_stm32l4xx.c</PathWithFileName> |
| | | <FilenameWithoutPath>system_stm32l4xx.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | </Group> |
| | | |
| | | <Group> |
| | | <GroupName>Board</GroupName> |
| | | <tvExp>1</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <cbSel>0</cbSel> |
| | | <RteFlg>0</RteFlg> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>31</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\miscdev.c</PathWithFileName> |
| | | <FilenameWithoutPath>miscdev.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>32</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\buzzer.c</PathWithFileName> |
| | | <FilenameWithoutPath>buzzer.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>33</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\ds18b20.c</PathWithFileName> |
| | | <FilenameWithoutPath>ds18b20.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>34</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\eeprom.c</PathWithFileName> |
| | | <FilenameWithoutPath>eeprom.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>35</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\i2c_bitbang.c</PathWithFileName> |
| | | <FilenameWithoutPath>i2c_bitbang.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>36</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\isl1208.c</PathWithFileName> |
| | | <FilenameWithoutPath>isl1208.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>37</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\oled_drv.c</PathWithFileName> |
| | | <FilenameWithoutPath>oled_drv.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>38</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\oled_font.c</PathWithFileName> |
| | | <FilenameWithoutPath>oled_font.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | <File> |
| | | <GroupNumber>5</GroupNumber> |
| | | <FileNumber>39</FileNumber> |
| | | <FileType>1</FileType> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <bDave2>0</bDave2> |
| | | <PathWithFileName>..\Board\sht20.c</PathWithFileName> |
| | | <FilenameWithoutPath>sht20.c</FilenameWithoutPath> |
| | | <RteFlg>0</RteFlg> |
| | | <bShared>0</bShared> |
| | | </File> |
| | | </Group> |
| | | |
| | | <Group> |
| | | <GroupName>::CMSIS</GroupName> |
| | | <tvExp>0</tvExp> |
| | | <tvExpOptDlg>0</tvExpOptDlg> |
| | | <cbSel>0</cbSel> |
| | | <RteFlg>1</RteFlg> |
| | | </Group> |
| | | |
| | | </ProjectOpt> |
| New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8" standalone="no" ?> |
| | | <Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd"> |
| | | |
| | | <SchemaVersion>2.1</SchemaVersion> |
| | | |
| | | <Header>### uVision Project, (C) Keil Software</Header> |
| | | |
| | | <Targets> |
| | | <Target> |
| | | <TargetName>ISKBoard</TargetName> |
| | | <ToolsetNumber>0x4</ToolsetNumber> |
| | | <ToolsetName>ARM-ADS</ToolsetName> |
| | | <pCCUsed>6150000::V6.15::ARMCLANG</pCCUsed> |
| | | <uAC6>1</uAC6> |
| | | <TargetOption> |
| | | <TargetCommonOption> |
| | | <Device>STM32L431RCTx</Device> |
| | | <Vendor>STMicroelectronics</Vendor> |
| | | <PackID>Keil.STM32L4xx_DFP.2.5.0</PackID> |
| | | <PackURL>http://www.keil.com/pack/</PackURL> |
| | | <Cpu>IRAM(0x20000000-0x2000BFFF) IRAM2(0x10000000-0x10003FFF) IROM(0x8000000-0x803FFFF) CLOCK(8000000) FPU2 CPUTYPE("Cortex-M4") TZ</Cpu> |
| | | <FlashUtilSpec></FlashUtilSpec> |
| | | <StartupFile></StartupFile> |
| | | <FlashDriverDll></FlashDriverDll> |
| | | <DeviceId>0</DeviceId> |
| | | <RegisterFile></RegisterFile> |
| | | <MemoryEnv></MemoryEnv> |
| | | <Cmp></Cmp> |
| | | <Asm></Asm> |
| | | <Linker></Linker> |
| | | <OHString></OHString> |
| | | <InfinionOptionDll></InfinionOptionDll> |
| | | <SLE66CMisc></SLE66CMisc> |
| | | <SLE66AMisc></SLE66AMisc> |
| | | <SLE66LinkerMisc></SLE66LinkerMisc> |
| | | <SFDFile>$$Device:STM32L431RCTx$CMSIS\SVD\STM32L4x1.svd</SFDFile> |
| | | <bCustSvd>0</bCustSvd> |
| | | <UseEnv>0</UseEnv> |
| | | <BinPath></BinPath> |
| | | <IncludePath></IncludePath> |
| | | <LibPath></LibPath> |
| | | <RegisterFilePath></RegisterFilePath> |
| | | <DBRegisterFilePath></DBRegisterFilePath> |
| | | <TargetStatus> |
| | | <Error>0</Error> |
| | | <ExitCodeStop>0</ExitCodeStop> |
| | | <ButtonStop>0</ButtonStop> |
| | | <NotGenerated>0</NotGenerated> |
| | | <InvalidFlash>1</InvalidFlash> |
| | | </TargetStatus> |
| | | <OutputDirectory>ISKBoard\</OutputDirectory> |
| | | <OutputName>ISKBoard</OutputName> |
| | | <CreateExecutable>1</CreateExecutable> |
| | | <CreateLib>0</CreateLib> |
| | | <CreateHexFile>1</CreateHexFile> |
| | | <DebugInformation>1</DebugInformation> |
| | | <BrowseInformation>1</BrowseInformation> |
| | | <ListingPath></ListingPath> |
| | | <HexFormatSelection>1</HexFormatSelection> |
| | | <Merge32K>0</Merge32K> |
| | | <CreateBatchFile>0</CreateBatchFile> |
| | | <BeforeCompile> |
| | | <RunUserProg1>0</RunUserProg1> |
| | | <RunUserProg2>0</RunUserProg2> |
| | | <UserProg1Name></UserProg1Name> |
| | | <UserProg2Name></UserProg2Name> |
| | | <UserProg1Dos16Mode>0</UserProg1Dos16Mode> |
| | | <UserProg2Dos16Mode>0</UserProg2Dos16Mode> |
| | | <nStopU1X>0</nStopU1X> |
| | | <nStopU2X>0</nStopU2X> |
| | | </BeforeCompile> |
| | | <BeforeMake> |
| | | <RunUserProg1>0</RunUserProg1> |
| | | <RunUserProg2>0</RunUserProg2> |
| | | <UserProg1Name></UserProg1Name> |
| | | <UserProg2Name></UserProg2Name> |
| | | <UserProg1Dos16Mode>0</UserProg1Dos16Mode> |
| | | <UserProg2Dos16Mode>0</UserProg2Dos16Mode> |
| | | <nStopB1X>0</nStopB1X> |
| | | <nStopB2X>0</nStopB2X> |
| | | </BeforeMake> |
| | | <AfterMake> |
| | | <RunUserProg1>0</RunUserProg1> |
| | | <RunUserProg2>1</RunUserProg2> |
| | | <UserProg1Name></UserProg1Name> |
| | | <UserProg2Name></UserProg2Name> |
| | | <UserProg1Dos16Mode>0</UserProg1Dos16Mode> |
| | | <UserProg2Dos16Mode>0</UserProg2Dos16Mode> |
| | | <nStopA1X>0</nStopA1X> |
| | | <nStopA2X>0</nStopA2X> |
| | | </AfterMake> |
| | | <SelectedForBatchBuild>1</SelectedForBatchBuild> |
| | | <SVCSIdString></SVCSIdString> |
| | | </TargetCommonOption> |
| | | <CommonProperty> |
| | | <UseCPPCompiler>0</UseCPPCompiler> |
| | | <RVCTCodeConst>0</RVCTCodeConst> |
| | | <RVCTZI>0</RVCTZI> |
| | | <RVCTOtherData>0</RVCTOtherData> |
| | | <ModuleSelection>0</ModuleSelection> |
| | | <IncludeInBuild>1</IncludeInBuild> |
| | | <AlwaysBuild>0</AlwaysBuild> |
| | | <GenerateAssemblyFile>0</GenerateAssemblyFile> |
| | | <AssembleAssemblyFile>0</AssembleAssemblyFile> |
| | | <PublicsOnly>0</PublicsOnly> |
| | | <StopOnExitCode>3</StopOnExitCode> |
| | | <CustomArgument></CustomArgument> |
| | | <IncludeLibraryModules></IncludeLibraryModules> |
| | | <ComprImg>0</ComprImg> |
| | | </CommonProperty> |
| | | <DllOption> |
| | | <SimDllName>SARMCM3.DLL</SimDllName> |
| | | <SimDllArguments>-REMAP -MPU</SimDllArguments> |
| | | <SimDlgDll>DCM.DLL</SimDlgDll> |
| | | <SimDlgDllArguments>-pCM4</SimDlgDllArguments> |
| | | <TargetDllName>SARMCM3.DLL</TargetDllName> |
| | | <TargetDllArguments>-MPU</TargetDllArguments> |
| | | <TargetDlgDll>TCM.DLL</TargetDlgDll> |
| | | <TargetDlgDllArguments>-pCM4</TargetDlgDllArguments> |
| | | </DllOption> |
| | | <DebugOption> |
| | | <OPTHX> |
| | | <HexSelection>1</HexSelection> |
| | | <HexRangeLowAddress>0</HexRangeLowAddress> |
| | | <HexRangeHighAddress>0</HexRangeHighAddress> |
| | | <HexOffset>0</HexOffset> |
| | | <Oh166RecLen>16</Oh166RecLen> |
| | | </OPTHX> |
| | | </DebugOption> |
| | | <Utilities> |
| | | <Flash1> |
| | | <UseTargetDll>1</UseTargetDll> |
| | | <UseExternalTool>0</UseExternalTool> |
| | | <RunIndependent>0</RunIndependent> |
| | | <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging> |
| | | <Capability>1</Capability> |
| | | <DriverSelection>4101</DriverSelection> |
| | | </Flash1> |
| | | <bUseTDR>1</bUseTDR> |
| | | <Flash2>BIN\UL2V8M.DLL</Flash2> |
| | | <Flash3>"" ()</Flash3> |
| | | <Flash4></Flash4> |
| | | <pFcarmOut></pFcarmOut> |
| | | <pFcarmGrp></pFcarmGrp> |
| | | <pFcArmRoot></pFcArmRoot> |
| | | <FcArmLst>0</FcArmLst> |
| | | </Utilities> |
| | | <TargetArmAds> |
| | | <ArmAdsMisc> |
| | | <GenerateListings>0</GenerateListings> |
| | | <asHll>1</asHll> |
| | | <asAsm>1</asAsm> |
| | | <asMacX>1</asMacX> |
| | | <asSyms>1</asSyms> |
| | | <asFals>1</asFals> |
| | | <asDbgD>1</asDbgD> |
| | | <asForm>1</asForm> |
| | | <ldLst>0</ldLst> |
| | | <ldmm>1</ldmm> |
| | | <ldXref>1</ldXref> |
| | | <BigEnd>0</BigEnd> |
| | | <AdsALst>1</AdsALst> |
| | | <AdsACrf>1</AdsACrf> |
| | | <AdsANop>0</AdsANop> |
| | | <AdsANot>0</AdsANot> |
| | | <AdsLLst>1</AdsLLst> |
| | | <AdsLmap>1</AdsLmap> |
| | | <AdsLcgr>1</AdsLcgr> |
| | | <AdsLsym>1</AdsLsym> |
| | | <AdsLszi>1</AdsLszi> |
| | | <AdsLtoi>1</AdsLtoi> |
| | | <AdsLsun>1</AdsLsun> |
| | | <AdsLven>1</AdsLven> |
| | | <AdsLsxf>1</AdsLsxf> |
| | | <RvctClst>0</RvctClst> |
| | | <GenPPlst>0</GenPPlst> |
| | | <AdsCpuType>"Cortex-M4"</AdsCpuType> |
| | | <RvctDeviceName></RvctDeviceName> |
| | | <mOS>0</mOS> |
| | | <uocRom>0</uocRom> |
| | | <uocRam>0</uocRam> |
| | | <hadIROM>1</hadIROM> |
| | | <hadIRAM>1</hadIRAM> |
| | | <hadXRAM>0</hadXRAM> |
| | | <uocXRam>0</uocXRam> |
| | | <RvdsVP>2</RvdsVP> |
| | | <RvdsMve>0</RvdsMve> |
| | | <RvdsCdeCp>0</RvdsCdeCp> |
| | | <hadIRAM2>1</hadIRAM2> |
| | | <hadIROM2>0</hadIROM2> |
| | | <StupSel>8</StupSel> |
| | | <useUlib>1</useUlib> |
| | | <EndSel>0</EndSel> |
| | | <uLtcg>0</uLtcg> |
| | | <nSecure>0</nSecure> |
| | | <RoSelD>3</RoSelD> |
| | | <RwSelD>4</RwSelD> |
| | | <CodeSel>0</CodeSel> |
| | | <OptFeed>0</OptFeed> |
| | | <NoZi1>0</NoZi1> |
| | | <NoZi2>0</NoZi2> |
| | | <NoZi3>0</NoZi3> |
| | | <NoZi4>0</NoZi4> |
| | | <NoZi5>0</NoZi5> |
| | | <Ro1Chk>0</Ro1Chk> |
| | | <Ro2Chk>0</Ro2Chk> |
| | | <Ro3Chk>0</Ro3Chk> |
| | | <Ir1Chk>1</Ir1Chk> |
| | | <Ir2Chk>0</Ir2Chk> |
| | | <Ra1Chk>0</Ra1Chk> |
| | | <Ra2Chk>0</Ra2Chk> |
| | | <Ra3Chk>0</Ra3Chk> |
| | | <Im1Chk>1</Im1Chk> |
| | | <Im2Chk>1</Im2Chk> |
| | | <OnChipMemories> |
| | | <Ocm1> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </Ocm1> |
| | | <Ocm2> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </Ocm2> |
| | | <Ocm3> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </Ocm3> |
| | | <Ocm4> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </Ocm4> |
| | | <Ocm5> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </Ocm5> |
| | | <Ocm6> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </Ocm6> |
| | | <IRAM> |
| | | <Type>0</Type> |
| | | <StartAddress>0x20000000</StartAddress> |
| | | <Size>0xc000</Size> |
| | | </IRAM> |
| | | <IROM> |
| | | <Type>1</Type> |
| | | <StartAddress>0x8000000</StartAddress> |
| | | <Size>0x40000</Size> |
| | | </IROM> |
| | | <XRAM> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </XRAM> |
| | | <OCR_RVCT1> |
| | | <Type>1</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </OCR_RVCT1> |
| | | <OCR_RVCT2> |
| | | <Type>1</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </OCR_RVCT2> |
| | | <OCR_RVCT3> |
| | | <Type>1</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </OCR_RVCT3> |
| | | <OCR_RVCT4> |
| | | <Type>1</Type> |
| | | <StartAddress>0x8000000</StartAddress> |
| | | <Size>0x40000</Size> |
| | | </OCR_RVCT4> |
| | | <OCR_RVCT5> |
| | | <Type>1</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </OCR_RVCT5> |
| | | <OCR_RVCT6> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </OCR_RVCT6> |
| | | <OCR_RVCT7> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </OCR_RVCT7> |
| | | <OCR_RVCT8> |
| | | <Type>0</Type> |
| | | <StartAddress>0x0</StartAddress> |
| | | <Size>0x0</Size> |
| | | </OCR_RVCT8> |
| | | <OCR_RVCT9> |
| | | <Type>0</Type> |
| | | <StartAddress>0x20000000</StartAddress> |
| | | <Size>0xc000</Size> |
| | | </OCR_RVCT9> |
| | | <OCR_RVCT10> |
| | | <Type>0</Type> |
| | | <StartAddress>0x10000000</StartAddress> |
| | | <Size>0x4000</Size> |
| | | </OCR_RVCT10> |
| | | </OnChipMemories> |
| | | <RvctStartVector></RvctStartVector> |
| | | </ArmAdsMisc> |
| | | <Cads> |
| | | <interw>1</interw> |
| | | <Optim>2</Optim> |
| | | <oTime>0</oTime> |
| | | <SplitLS>0</SplitLS> |
| | | <OneElfS>1</OneElfS> |
| | | <Strict>0</Strict> |
| | | <EnumInt>0</EnumInt> |
| | | <PlainCh>0</PlainCh> |
| | | <Ropi>0</Ropi> |
| | | <Rwpi>0</Rwpi> |
| | | <wLevel>3</wLevel> |
| | | <uThumb>0</uThumb> |
| | | <uSurpInc>0</uSurpInc> |
| | | <uC99>1</uC99> |
| | | <uGnu>0</uGnu> |
| | | <useXO>0</useXO> |
| | | <v6Lang>3</v6Lang> |
| | | <v6LangP>3</v6LangP> |
| | | <vShortEn>1</vShortEn> |
| | | <vShortWch>1</vShortWch> |
| | | <v6Lto>0</v6Lto> |
| | | <v6WtE>0</v6WtE> |
| | | <v6Rtti>0</v6Rtti> |
| | | <VariousControls> |
| | | <MiscControls></MiscControls> |
| | | <Define>USE_HAL_DRIVER,STM32L431xx</Define> |
| | | <Undefine></Undefine> |
| | | <IncludePath>../Core/Inc;../Drivers/STM32L4xx_HAL_Driver/Inc;../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32L4xx/Include;../Drivers/CMSIS/Include;../Board</IncludePath> |
| | | </VariousControls> |
| | | </Cads> |
| | | <Aads> |
| | | <interw>1</interw> |
| | | <Ropi>0</Ropi> |
| | | <Rwpi>0</Rwpi> |
| | | <thumb>0</thumb> |
| | | <SplitLS>0</SplitLS> |
| | | <SwStkChk>0</SwStkChk> |
| | | <NoWarn>0</NoWarn> |
| | | <uSurpInc>0</uSurpInc> |
| | | <useXO>0</useXO> |
| | | <ClangAsOpt>1</ClangAsOpt> |
| | | <VariousControls> |
| | | <MiscControls></MiscControls> |
| | | <Define></Define> |
| | | <Undefine></Undefine> |
| | | <IncludePath></IncludePath> |
| | | </VariousControls> |
| | | </Aads> |
| | | <LDads> |
| | | <umfTarg>1</umfTarg> |
| | | <Ropi>0</Ropi> |
| | | <Rwpi>0</Rwpi> |
| | | <noStLib>0</noStLib> |
| | | <RepFail>1</RepFail> |
| | | <useFile>0</useFile> |
| | | <TextAddressRange></TextAddressRange> |
| | | <DataAddressRange></DataAddressRange> |
| | | <pXoBase></pXoBase> |
| | | <ScatterFile></ScatterFile> |
| | | <IncludeLibs></IncludeLibs> |
| | | <IncludeLibsPath></IncludeLibsPath> |
| | | <Misc></Misc> |
| | | <LinkerInputFile></LinkerInputFile> |
| | | <DisabledWarnings></DisabledWarnings> |
| | | </LDads> |
| | | </TargetArmAds> |
| | | </TargetOption> |
| | | <Groups> |
| | | <Group> |
| | | <GroupName>Application/MDK-ARM</GroupName> |
| | | <Files> |
| | | <File> |
| | | <FileName>startup_stm32l431xx.s</FileName> |
| | | <FileType>2</FileType> |
| | | <FilePath>startup_stm32l431xx.s</FilePath> |
| | | </File> |
| | | </Files> |
| | | </Group> |
| | | <Group> |
| | | <GroupName>Application/User/Core</GroupName> |
| | | <Files> |
| | | <File> |
| | | <FileName>main.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Core/Src/main.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>gpio.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Core/Src/gpio.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>adc.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Core/Src/adc.c</FilePath> |
| | | <FileOption> |
| | | <CommonProperty> |
| | | <UseCPPCompiler>2</UseCPPCompiler> |
| | | <RVCTCodeConst>0</RVCTCodeConst> |
| | | <RVCTZI>0</RVCTZI> |
| | | <RVCTOtherData>0</RVCTOtherData> |
| | | <ModuleSelection>0</ModuleSelection> |
| | | <IncludeInBuild>1</IncludeInBuild> |
| | | <AlwaysBuild>2</AlwaysBuild> |
| | | <GenerateAssemblyFile>2</GenerateAssemblyFile> |
| | | <AssembleAssemblyFile>2</AssembleAssemblyFile> |
| | | <PublicsOnly>2</PublicsOnly> |
| | | <StopOnExitCode>11</StopOnExitCode> |
| | | <CustomArgument></CustomArgument> |
| | | <IncludeLibraryModules></IncludeLibraryModules> |
| | | <ComprImg>1</ComprImg> |
| | | </CommonProperty> |
| | | <FileArmAds> |
| | | <Cads> |
| | | <interw>2</interw> |
| | | <Optim>0</Optim> |
| | | <oTime>2</oTime> |
| | | <SplitLS>2</SplitLS> |
| | | <OneElfS>2</OneElfS> |
| | | <Strict>2</Strict> |
| | | <EnumInt>2</EnumInt> |
| | | <PlainCh>2</PlainCh> |
| | | <Ropi>2</Ropi> |
| | | <Rwpi>2</Rwpi> |
| | | <wLevel>0</wLevel> |
| | | <uThumb>2</uThumb> |
| | | <uSurpInc>2</uSurpInc> |
| | | <uC99>2</uC99> |
| | | <uGnu>2</uGnu> |
| | | <useXO>2</useXO> |
| | | <v6Lang>0</v6Lang> |
| | | <v6LangP>0</v6LangP> |
| | | <vShortEn>2</vShortEn> |
| | | <vShortWch>2</vShortWch> |
| | | <v6Lto>2</v6Lto> |
| | | <v6WtE>2</v6WtE> |
| | | <v6Rtti>2</v6Rtti> |
| | | <VariousControls> |
| | | <MiscControls></MiscControls> |
| | | <Define></Define> |
| | | <Undefine></Undefine> |
| | | <IncludePath></IncludePath> |
| | | </VariousControls> |
| | | </Cads> |
| | | </FileArmAds> |
| | | </FileOption> |
| | | </File> |
| | | <File> |
| | | <FileName>tim.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Core/Src/tim.c</FilePath> |
| | | <FileOption> |
| | | <CommonProperty> |
| | | <UseCPPCompiler>2</UseCPPCompiler> |
| | | <RVCTCodeConst>0</RVCTCodeConst> |
| | | <RVCTZI>0</RVCTZI> |
| | | <RVCTOtherData>0</RVCTOtherData> |
| | | <ModuleSelection>0</ModuleSelection> |
| | | <IncludeInBuild>1</IncludeInBuild> |
| | | <AlwaysBuild>2</AlwaysBuild> |
| | | <GenerateAssemblyFile>2</GenerateAssemblyFile> |
| | | <AssembleAssemblyFile>2</AssembleAssemblyFile> |
| | | <PublicsOnly>2</PublicsOnly> |
| | | <StopOnExitCode>11</StopOnExitCode> |
| | | <CustomArgument></CustomArgument> |
| | | <IncludeLibraryModules></IncludeLibraryModules> |
| | | <ComprImg>1</ComprImg> |
| | | </CommonProperty> |
| | | <FileArmAds> |
| | | <Cads> |
| | | <interw>2</interw> |
| | | <Optim>0</Optim> |
| | | <oTime>2</oTime> |
| | | <SplitLS>2</SplitLS> |
| | | <OneElfS>2</OneElfS> |
| | | <Strict>2</Strict> |
| | | <EnumInt>2</EnumInt> |
| | | <PlainCh>2</PlainCh> |
| | | <Ropi>2</Ropi> |
| | | <Rwpi>2</Rwpi> |
| | | <wLevel>0</wLevel> |
| | | <uThumb>2</uThumb> |
| | | <uSurpInc>2</uSurpInc> |
| | | <uC99>2</uC99> |
| | | <uGnu>2</uGnu> |
| | | <useXO>2</useXO> |
| | | <v6Lang>0</v6Lang> |
| | | <v6LangP>0</v6LangP> |
| | | <vShortEn>2</vShortEn> |
| | | <vShortWch>2</vShortWch> |
| | | <v6Lto>2</v6Lto> |
| | | <v6WtE>2</v6WtE> |
| | | <v6Rtti>2</v6Rtti> |
| | | <VariousControls> |
| | | <MiscControls></MiscControls> |
| | | <Define></Define> |
| | | <Undefine></Undefine> |
| | | <IncludePath></IncludePath> |
| | | </VariousControls> |
| | | </Cads> |
| | | </FileArmAds> |
| | | </FileOption> |
| | | </File> |
| | | <File> |
| | | <FileName>usart.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Core/Src/usart.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_it.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Core/Src/stm32l4xx_it.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_msp.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Core/Src/stm32l4xx_hal_msp.c</FilePath> |
| | | </File> |
| | | </Files> |
| | | </Group> |
| | | <Group> |
| | | <GroupName>Drivers/STM32L4xx_HAL_Driver</GroupName> |
| | | <Files> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_adc.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c</FilePath> |
| | | <FileOption> |
| | | <CommonProperty> |
| | | <UseCPPCompiler>2</UseCPPCompiler> |
| | | <RVCTCodeConst>0</RVCTCodeConst> |
| | | <RVCTZI>0</RVCTZI> |
| | | <RVCTOtherData>0</RVCTOtherData> |
| | | <ModuleSelection>0</ModuleSelection> |
| | | <IncludeInBuild>1</IncludeInBuild> |
| | | <AlwaysBuild>2</AlwaysBuild> |
| | | <GenerateAssemblyFile>2</GenerateAssemblyFile> |
| | | <AssembleAssemblyFile>2</AssembleAssemblyFile> |
| | | <PublicsOnly>2</PublicsOnly> |
| | | <StopOnExitCode>11</StopOnExitCode> |
| | | <CustomArgument></CustomArgument> |
| | | <IncludeLibraryModules></IncludeLibraryModules> |
| | | <ComprImg>1</ComprImg> |
| | | </CommonProperty> |
| | | <FileArmAds> |
| | | <Cads> |
| | | <interw>2</interw> |
| | | <Optim>0</Optim> |
| | | <oTime>2</oTime> |
| | | <SplitLS>2</SplitLS> |
| | | <OneElfS>2</OneElfS> |
| | | <Strict>2</Strict> |
| | | <EnumInt>2</EnumInt> |
| | | <PlainCh>2</PlainCh> |
| | | <Ropi>2</Ropi> |
| | | <Rwpi>2</Rwpi> |
| | | <wLevel>0</wLevel> |
| | | <uThumb>2</uThumb> |
| | | <uSurpInc>2</uSurpInc> |
| | | <uC99>2</uC99> |
| | | <uGnu>2</uGnu> |
| | | <useXO>2</useXO> |
| | | <v6Lang>0</v6Lang> |
| | | <v6LangP>0</v6LangP> |
| | | <vShortEn>2</vShortEn> |
| | | <vShortWch>2</vShortWch> |
| | | <v6Lto>2</v6Lto> |
| | | <v6WtE>2</v6WtE> |
| | | <v6Rtti>2</v6Rtti> |
| | | <VariousControls> |
| | | <MiscControls></MiscControls> |
| | | <Define></Define> |
| | | <Undefine></Undefine> |
| | | <IncludePath></IncludePath> |
| | | </VariousControls> |
| | | </Cads> |
| | | </FileArmAds> |
| | | </FileOption> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_adc_ex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c</FilePath> |
| | | <FileOption> |
| | | <CommonProperty> |
| | | <UseCPPCompiler>2</UseCPPCompiler> |
| | | <RVCTCodeConst>0</RVCTCodeConst> |
| | | <RVCTZI>0</RVCTZI> |
| | | <RVCTOtherData>0</RVCTOtherData> |
| | | <ModuleSelection>0</ModuleSelection> |
| | | <IncludeInBuild>1</IncludeInBuild> |
| | | <AlwaysBuild>2</AlwaysBuild> |
| | | <GenerateAssemblyFile>2</GenerateAssemblyFile> |
| | | <AssembleAssemblyFile>2</AssembleAssemblyFile> |
| | | <PublicsOnly>2</PublicsOnly> |
| | | <StopOnExitCode>11</StopOnExitCode> |
| | | <CustomArgument></CustomArgument> |
| | | <IncludeLibraryModules></IncludeLibraryModules> |
| | | <ComprImg>1</ComprImg> |
| | | </CommonProperty> |
| | | <FileArmAds> |
| | | <Cads> |
| | | <interw>2</interw> |
| | | <Optim>0</Optim> |
| | | <oTime>2</oTime> |
| | | <SplitLS>2</SplitLS> |
| | | <OneElfS>2</OneElfS> |
| | | <Strict>2</Strict> |
| | | <EnumInt>2</EnumInt> |
| | | <PlainCh>2</PlainCh> |
| | | <Ropi>2</Ropi> |
| | | <Rwpi>2</Rwpi> |
| | | <wLevel>0</wLevel> |
| | | <uThumb>2</uThumb> |
| | | <uSurpInc>2</uSurpInc> |
| | | <uC99>2</uC99> |
| | | <uGnu>2</uGnu> |
| | | <useXO>2</useXO> |
| | | <v6Lang>0</v6Lang> |
| | | <v6LangP>0</v6LangP> |
| | | <vShortEn>2</vShortEn> |
| | | <vShortWch>2</vShortWch> |
| | | <v6Lto>2</v6Lto> |
| | | <v6WtE>2</v6WtE> |
| | | <v6Rtti>2</v6Rtti> |
| | | <VariousControls> |
| | | <MiscControls></MiscControls> |
| | | <Define></Define> |
| | | <Undefine></Undefine> |
| | | <IncludePath></IncludePath> |
| | | </VariousControls> |
| | | </Cads> |
| | | </FileArmAds> |
| | | </FileOption> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_rcc.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_rcc_ex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_flash.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_flash_ex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_flash_ramfunc.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_gpio.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_i2c.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_i2c_ex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_dma.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_dma_ex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_pwr.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_pwr_ex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_cortex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_exti.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_tim.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c</FilePath> |
| | | <FileOption> |
| | | <CommonProperty> |
| | | <UseCPPCompiler>2</UseCPPCompiler> |
| | | <RVCTCodeConst>0</RVCTCodeConst> |
| | | <RVCTZI>0</RVCTZI> |
| | | <RVCTOtherData>0</RVCTOtherData> |
| | | <ModuleSelection>0</ModuleSelection> |
| | | <IncludeInBuild>1</IncludeInBuild> |
| | | <AlwaysBuild>2</AlwaysBuild> |
| | | <GenerateAssemblyFile>2</GenerateAssemblyFile> |
| | | <AssembleAssemblyFile>2</AssembleAssemblyFile> |
| | | <PublicsOnly>2</PublicsOnly> |
| | | <StopOnExitCode>11</StopOnExitCode> |
| | | <CustomArgument></CustomArgument> |
| | | <IncludeLibraryModules></IncludeLibraryModules> |
| | | <ComprImg>1</ComprImg> |
| | | </CommonProperty> |
| | | <FileArmAds> |
| | | <Cads> |
| | | <interw>2</interw> |
| | | <Optim>0</Optim> |
| | | <oTime>2</oTime> |
| | | <SplitLS>2</SplitLS> |
| | | <OneElfS>2</OneElfS> |
| | | <Strict>2</Strict> |
| | | <EnumInt>2</EnumInt> |
| | | <PlainCh>2</PlainCh> |
| | | <Ropi>2</Ropi> |
| | | <Rwpi>2</Rwpi> |
| | | <wLevel>0</wLevel> |
| | | <uThumb>2</uThumb> |
| | | <uSurpInc>2</uSurpInc> |
| | | <uC99>2</uC99> |
| | | <uGnu>2</uGnu> |
| | | <useXO>2</useXO> |
| | | <v6Lang>0</v6Lang> |
| | | <v6LangP>0</v6LangP> |
| | | <vShortEn>2</vShortEn> |
| | | <vShortWch>2</vShortWch> |
| | | <v6Lto>2</v6Lto> |
| | | <v6WtE>2</v6WtE> |
| | | <v6Rtti>2</v6Rtti> |
| | | <VariousControls> |
| | | <MiscControls></MiscControls> |
| | | <Define></Define> |
| | | <Undefine></Undefine> |
| | | <IncludePath></IncludePath> |
| | | </VariousControls> |
| | | </Cads> |
| | | </FileArmAds> |
| | | </FileOption> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_tim_ex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c</FilePath> |
| | | <FileOption> |
| | | <CommonProperty> |
| | | <UseCPPCompiler>2</UseCPPCompiler> |
| | | <RVCTCodeConst>0</RVCTCodeConst> |
| | | <RVCTZI>0</RVCTZI> |
| | | <RVCTOtherData>0</RVCTOtherData> |
| | | <ModuleSelection>0</ModuleSelection> |
| | | <IncludeInBuild>1</IncludeInBuild> |
| | | <AlwaysBuild>2</AlwaysBuild> |
| | | <GenerateAssemblyFile>2</GenerateAssemblyFile> |
| | | <AssembleAssemblyFile>2</AssembleAssemblyFile> |
| | | <PublicsOnly>2</PublicsOnly> |
| | | <StopOnExitCode>11</StopOnExitCode> |
| | | <CustomArgument></CustomArgument> |
| | | <IncludeLibraryModules></IncludeLibraryModules> |
| | | <ComprImg>1</ComprImg> |
| | | </CommonProperty> |
| | | <FileArmAds> |
| | | <Cads> |
| | | <interw>2</interw> |
| | | <Optim>0</Optim> |
| | | <oTime>2</oTime> |
| | | <SplitLS>2</SplitLS> |
| | | <OneElfS>2</OneElfS> |
| | | <Strict>2</Strict> |
| | | <EnumInt>2</EnumInt> |
| | | <PlainCh>2</PlainCh> |
| | | <Ropi>2</Ropi> |
| | | <Rwpi>2</Rwpi> |
| | | <wLevel>0</wLevel> |
| | | <uThumb>2</uThumb> |
| | | <uSurpInc>2</uSurpInc> |
| | | <uC99>2</uC99> |
| | | <uGnu>2</uGnu> |
| | | <useXO>2</useXO> |
| | | <v6Lang>0</v6Lang> |
| | | <v6LangP>0</v6LangP> |
| | | <vShortEn>2</vShortEn> |
| | | <vShortWch>2</vShortWch> |
| | | <v6Lto>2</v6Lto> |
| | | <v6WtE>2</v6WtE> |
| | | <v6Rtti>2</v6Rtti> |
| | | <VariousControls> |
| | | <MiscControls></MiscControls> |
| | | <Define></Define> |
| | | <Undefine></Undefine> |
| | | <IncludePath></IncludePath> |
| | | </VariousControls> |
| | | </Cads> |
| | | </FileArmAds> |
| | | </FileOption> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_uart.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>stm32l4xx_hal_uart_ex.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c</FilePath> |
| | | </File> |
| | | </Files> |
| | | </Group> |
| | | <Group> |
| | | <GroupName>Drivers/CMSIS</GroupName> |
| | | <Files> |
| | | <File> |
| | | <FileName>system_stm32l4xx.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>../Core/Src/system_stm32l4xx.c</FilePath> |
| | | </File> |
| | | </Files> |
| | | </Group> |
| | | <Group> |
| | | <GroupName>Board</GroupName> |
| | | <Files> |
| | | <File> |
| | | <FileName>miscdev.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\miscdev.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>buzzer.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\buzzer.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>ds18b20.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\ds18b20.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>eeprom.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\eeprom.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>i2c_bitbang.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\i2c_bitbang.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>isl1208.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\isl1208.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>oled_drv.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\oled_drv.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>oled_font.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\oled_font.c</FilePath> |
| | | </File> |
| | | <File> |
| | | <FileName>sht20.c</FileName> |
| | | <FileType>1</FileType> |
| | | <FilePath>..\Board\sht20.c</FilePath> |
| | | </File> |
| | | </Files> |
| | | </Group> |
| | | <Group> |
| | | <GroupName>::CMSIS</GroupName> |
| | | </Group> |
| | | </Groups> |
| | | </Target> |
| | | </Targets> |
| | | |
| | | <RTE> |
| | | <apis/> |
| | | <components> |
| | | <component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="6.2.0" condition="ARMv6_7_8-M Device" ymlID="CMSIS:CORE"> |
| | | <package name="CMSIS" schemaVersion="1.7.53" url="https://www.keil.com/pack/" vendor="ARM" version="6.3.0"/> |
| | | <targetInfos> |
| | | <targetInfo name="ISKBoard"/> |
| | | </targetInfos> |
| | | </component> |
| | | </components> |
| | | <files/> |
| | | </RTE> |
| | | |
| | | </Project> |
| New file |
| | |
| | | @echo off |
| | | setlocal |
| | | |
| | | cd /d "%~dp0" |
| | | |
| | | REM ===== Clean Core (keep main.c) ===== |
| | | if exist "Core\Src\main.c" ( |
| | | copy /y "Core\Src\main.c" "main.c" >nul |
| | | rmdir /s /q "Core" 2>nul |
| | | mkdir "Core\Src" 2>nul |
| | | copy /y "main.c" "Core\Src\main.c" >nul |
| | | del /f /q "main.c" |
| | | ) |
| | | |
| | | REM ===== Clean artifacts ===== |
| | | call :del_file .mxproject |
| | | call :del_file .cproject |
| | | call :del_file .project |
| | | call :del_file .clangd |
| | | call :del_file *.json |
| | | call :del_file *.ld |
| | | call :del_file *.s |
| | | |
| | | call :del_dir .settings |
| | | call :del_dir Drivers |
| | | call :del_dir Debug |
| | | call :del_dir Release |
| | | call :del_dir build |
| | | call :del_dir cmake |
| | | |
| | | exit /b |
| | | |
| | | :del_file |
| | | if exist "%~1" del /f /q "%~1" |
| | | exit /b |
| | | |
| | | :del_dir |
| | | if exist "%~1\" rmdir /s /q "%~1" |
| | | exit /b |
| New file |
| | |
| | | 1. stm32flash.exe 是一个开源命令行工具,通过串口向 STM32 单片机的内置 ISP Bootloader 烧录、读取或校验固件,它只支持 .bin 文件。 |
| | | 其下载地址: https://sourceforge.net/projects/stm32flash/files/stm32flash-0.7-binaries.zip/download |
| | | |
| | | 2. arm-none-eabi-objcopy.exe 它拷贝自 STM32CubeIDE,是 GNU ARM 嵌入式工具链中的目标文件转换工具,常用于把编译生成的二进制 |
| | | .elf/.hex 文件转换成 .bin 文件,以便烧录到单片机中。 |
| New file |
| | |
| | | [COMMON] |
| | | COM_PORT=COM22 |
| | | BAUDRATE=115200 |
| | | PRJPATH=.. |
| New file |
| | |
| | | @echo off |
| | | setlocal EnableDelayedExpansion |
| | | set PATH=%PATH%;bin |
| | | |
| | | rem ==================================================== |
| | | rem 配置 |
| | | rem ==================================================== |
| | | set STM32FLASH=stm32flash.exe |
| | | set ADDRESS=0x8000000 |
| | | |
| | | rem ==================================================== |
| | | rem 解析 config.ini |
| | | rem ==================================================== |
| | | for /f "usebackq tokens=1,2 delims==" %%a in ("config.ini") do ( |
| | | if /i "%%a"=="COM_PORT" set COM_PORT=%%b |
| | | if /i "%%a"=="BAUDRATE" set BAUDRATE=%%b |
| | | if /i "%%a"=="PRJPATH" set PRJPATH=%%b |
| | | ) |
| | | |
| | | if not defined COM_PORT ( |
| | | echo [ERROR] COM_PORT not found in config.ini |
| | | pause & exit /b 1 |
| | | ) |
| | | if not defined BAUDRATE set BAUDRATE=115200 |
| | | if not defined PRJPATH set PRJPATH=.. |
| | | |
| | | rem 转为绝对路径 |
| | | pushd "%PRJPATH%" >nul 2>&1 |
| | | if errorlevel 1 ( |
| | | echo [ERROR] PRJPATH "%PRJPATH%" does not exist |
| | | pause & exit /b 1 |
| | | ) |
| | | set PRJPATH_ABS=%CD% |
| | | popd |
| | | |
| | | echo Project root: "%PRJPATH_ABS%" |
| | | echo COM port: %COM_PORT% @ %BAUDRATE% bps |
| | | echo. |
| | | |
| | | rem ==================================================== |
| | | rem 扫描固件文件 |
| | | rem 优先级: MDK-ARM(hex) -> Release -> Debug |
| | | rem ==================================================== |
| | | set INDEX=0 |
| | | |
| | | echo Scanning for firmware files... |
| | | |
| | | for /r "%PRJPATH_ABS%" %%f in ( |
| | | MDK-ARM\ISKBoard\ISKBoard.hex |
| | | build\Release\ISKBoard.elf |
| | | build\Debug\ISKBoard.elf |
| | | ) do ( |
| | | if exist "%%f" ( |
| | | set /a INDEX+=1 |
| | | set "FILE_!INDEX!=%%f" |
| | | echo !INDEX!^) %%~f |
| | | ) |
| | | ) |
| | | |
| | | if %INDEX%==0 ( |
| | | echo [ERROR] No firmware file found under "%PRJPATH_ABS%" |
| | | echo Expected patterns: |
| | | echo - MDK-ARM/ISKBoard/ISKBoard.hex |
| | | echo - build/Release/ISKBoard.elf |
| | | echo - build/Debug/ISKBoard.elf |
| | | pause & exit /b 1 |
| | | ) |
| | | |
| | | echo. |
| | | set /p CHOICE="Select firmware to flash [1-%INDEX%]: " |
| | | |
| | | rem 校验输入 |
| | | if "%CHOICE%"=="" ( |
| | | echo [ERROR] No selection made |
| | | pause & exit /b 1 |
| | | ) |
| | | if %CHOICE% LSS 1 ( |
| | | echo [ERROR] Invalid selection |
| | | pause & exit /b 1 |
| | | ) |
| | | if %CHOICE% GTR %INDEX% ( |
| | | echo [ERROR] Invalid selection |
| | | pause & exit /b 1 |
| | | ) |
| | | |
| | | call set SELECTED_FILE=%%FILE_%CHOICE%%% |
| | | echo. |
| | | echo Selected: "%SELECTED_FILE%" |
| | | echo. |
| | | |
| | | rem ==================================================== |
| | | rem 确定输出 bin 文件路径(放在源文件同目录下) |
| | | rem ==================================================== |
| | | for %%f in ("%SELECTED_FILE%") do set "BIN_FILE=%%~dpnf.bin" |
| | | |
| | | rem ==================================================== |
| | | rem 转换 hex/elf -> bin |
| | | rem ==================================================== |
| | | echo Converting to binary... |
| | | |
| | | for %%f in ("%SELECTED_FILE%") do set "EXT=%%~xf" |
| | | |
| | | if /i "%EXT%"==".hex" ( |
| | | arm-none-eabi-objcopy.exe -I ihex -O binary "%SELECTED_FILE%" "%BIN_FILE%" |
| | | ) else if /i "%EXT%"==".elf" ( |
| | | arm-none-eabi-objcopy.exe -O binary "%SELECTED_FILE%" "%BIN_FILE%" |
| | | ) else ( |
| | | echo [ERROR] Unsupported file type: "%EXT%" |
| | | pause & exit /b 1 |
| | | ) |
| | | |
| | | if %errorlevel% neq 0 ( |
| | | echo [ERROR] objcopy conversion failed. Error code: %errorlevel% |
| | | pause & exit /b 1 |
| | | ) |
| | | |
| | | echo Binary ready: "%BIN_FILE%" |
| | | echo. |
| | | |
| | | rem ==================================================== |
| | | rem ISP 模式提示(共用入口) |
| | | rem ==================================================== |
| | | :ISP_FLASH |
| | | echo ==================================================== |
| | | echo Serial port: %COM_PORT% @ %BAUDRATE% bps |
| | | echo. |
| | | echo Please ensure ISKBoard is in ISP mode, |
| | | echo then press any key to start flashing... |
| | | echo ==================================================== |
| | | pause >nul |
| | | |
| | | rem ==================================================== |
| | | rem 执行烧录 |
| | | rem ==================================================== |
| | | echo. |
| | | echo Flashing... |
| | | %STM32FLASH% -b %BAUDRATE% -w "%BIN_FILE%" -v -g %ADDRESS% %COM_PORT% |
| | | |
| | | if %errorlevel% neq 0 ( |
| | | echo [ERROR] Flashing failed. Error code: %errorlevel% |
| | | pause & exit /b 1 |
| | | ) |
| | | |
| | | echo. |
| | | echo [SUCCESS] Firmware flashed and verified! |
| | | |
| | | endlocal |