Частина 19 - Ввід
Останні дві лекції, надіяється, показали необхідність серйозного підходу до обробки вхідних даних будь-якої серйозної програми.
Сьогодні ми розробимо належну архітектуру вхідних даних для Pico, пов'язану зі STDIN і STDIO.
Давайте почнемо з створення input.h наступним чином.
ХМДХ
void input_proc(char type, char* p_usb_char, char* p_usb_string, const XMDXe9864ddd1ad6XMDX* p_USB_STRING_SIZE); void flush_input(char* p_usb_string);ХМДХ
У цьому місці ми встановлюємо наш вхідний заголовок ХМДХfileХМДХ для обробки параметрів, про які ми говорили в останній лекції. Також ми встановлюємо функцію flusХМДХh_inputХМДХ для очищення буфера вхідних даних після використання, щоб він був чистий перед отриманням нових даних для іншого ХМДХcallХМДХ до inpuХМДХt_proc.ХМДХ
Наступно ми створимо наш print.h наступним чином.
ХМДХ
void print_proc(char* p_usb_char, char* p_usb_string);ХМДХ
Дуже просто ми передаємо вхідний масив символів від викликаючого програми для обробки кожного символу і масив символів від викликаючого програми для створення рядка.
Наступно ми створимо наш input.c наступним чином.
ХМДХ
#include <stdio.h>include <string.h>
include "pico/stdlib.h"
define ZERO 0x30
define NINE 0x39
define PERIOD 0x2e
define CAPITAL_A 0x41
define LOWER_CASE_Z 0x7a
define BACKSPACE 0x08
define DEL 0x7f
void input_proc(char type, char p_usb_char, char p_usb_string, const XMDX832e312cd521XMDX p_USB_STRING_SIZE) { p_usb_char = ' '; p_usb_char = getchar_timeout_us(0); if(p_usb_char == BACKSPACE || p_usb_char == DEL) { if(p_usb_string[0]!= ' ') { XMDX75f455ff1d42XMDX(""); XMDXf86a742b2f82XMDX(" "); XMDX60f73982f8b3XMDX(""); p_usb_string[XMDX247b21c28542XMDX(p_usb_string)-1] = ' '; } } if(type == 'f') { char period; while((p_usb_char >= ZERO && p_usb_char <= NINE) || p_usb_char == PERIOD) { if(p_usb_char == PERIOD) period = strchr(p_usb_string, '.'); if(period == NULL) { if(XMDX3a372fad8be0XMDX(p_usb_string) < p_USB_STRING_SIZE) { putchar(p_usb_char); strncat(p_usb_string, p_usb_char, 1); } p_usb_char = ' '; } else break; } } else if(type == 'd') { while(p_usb_char >= ZERO && p_usb_char <= NINE) { if(XMDX8506512399f4XMDX(p_usb_string) < p_USB_STRING_SIZE) { putchar(p_usb_char); strncat(p_usb_string, p_usb_char, 1); } p_usb_char = ' '; } } else if(type == 's') { while(p_usb_char >= CAPITAL_A && p_usb_char <= LOWER_CASE_Z) { if(XMDXbe8e15c35d9fXMDX(p_usb_string) < p_USB_STRING_SIZE) { putchar(p_usb_char); strncat(p_usb_string, p_usb_char, 1); } *p_usb_char = ' '; } } }
void flush_input(char* p_usb_string) { p_usb_string[0] = ' '; } </pre>ХМДХ
Усі речі повинні бути повністю зрозумілі на цьому етапі. Якщо ні, будь ласка, перегляньте останні дві лекції.
Наступно ми створимо наш print.c наступним чином.
ХМДХ
#include <stdio.h>include "pico/stdlib.h"
include "input.h"
define RETURN 0x0d
void print_proc(char p_usb_char, char p_usb_string) { if(*p_usb_char == RETURN) { if(p_usb_string[0] == ' ') XMDXc8307a612988XMDX(" "); else XMDX428e829bd103XMDX(" %s ", p_usb_string); flush_input(p_usb_string); } } </pre>ХМДХ
У цьому місці ми імпортуємо можливість роботи з символами і рядками і якщо натиснути клавішу повернення друкуємо вміст рядка і потім ХМДХcallХМДХ викликаємо flusХМДХh_inputХМДХ для очищення буфера, про який було згадано раніше.
Останнім кроком буде створення нашого main.c наступним чином.
ХМДХ
#include <stdio.h>include "pico/stdlib.h"
include "print.h"
include "input.h"
XMDXce80d5ec65b1XMDX main() { stdio_init_all();
const XMDX3d327eec65caXMDX USB_STRING_SIZE = 100; char usb_char; usb_char = ' '; char usb_string[USB_STRING_SIZE]; usb_string[0] = ' '; while(1) { input_proc('f', &usb_char, usb_string, &USB_STRING_SIZE); print_proc(&usb_char, usb_string); }
return 0; } </pre>ХМДХ
У цьому місці ми встановлюємо вхідну процедуру для обробки даних типу float.
Давайте створимо нову папку 0x07ХМДХ_input andХМДХ і додамо наш CMakeLists.txt ХМДХfileХМДХ в неї.
ХМДХ
cmake_minimum_required(VERSION 3.13)include(pico_sdk_import.cmake)
project(test_project C CXX ASM) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") pico_sdk_init()
add_executable(main main.c print.c input.c )
pico_enable_stdio_usb(main 1) pico_enable_stdio_uart(main 0) pico_add_extra_outputs(main)
target_link_libraries(main pico_stdlib hardware_i2c)
add_custom_target(flash COMMAND cp main.uf2 /Volumes/RPI-RP2/ DEPENDS main ) </pre>ХМДХ
Наступно нам потрібно скопіювати picХМДХo_sdk_import.cmake XMDX11312150a2d0XMDXХМДХ з зовнішньої папки в pico-sdk встановлення в папку 0x07ХМДХ_input projectХМДХ.
ХМДХ
cp../pico-sdk/external/pico_sdk_import.cmake.ХМДХОстаннім кроком буде підготовка до збірки.
ХМДХ
mkdir build cd build export PICO_SDK_PATH=../../pico-sdk cmake.. make make flashХМДХЯ додав рутину для збереження часу від копіювання в makefile. Пам'ятайте, що потрібно встановити Pico в режим flash першого.
Далі потрібно знайти зовнішній накопичувач, щоб виконати наступні дії.
ХМДХ
ls /dev/tty.ХМДХНатисніть tab, щоб знайти накопичувач, а потім у моїх випадках я використовую screen для підключення.
ХМДХ
screen /dev/tty.usbmodem0000000000001ХМДХБум! Тепер ви побачите, що зможете тільки вводити числа і тільки одне місце після коми. Правильно обробляється відміна символів і коли досягнеться максимальна кількість 100 символів, воно не дозволить вам вводити більше символів. Останнім кроком буде друкування того, що ви ввели.
ХМДХ
32.3333 32.3333 32.11111111 32.11111111 7.99999003902930420384802384082304820384028342340284923840238948230482938429034823948293849023849223 7.99999003902930420384802384082304820384028342340284923840238948230482938429034823948293849023849223ХМДХУ наступній лекції ми розпочнемо роботу над відлагодженням програми.