<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      stm32最小核心板 串口篇

      「進串口」系統 Bootloader 燒錄(可選)

      如果你想 通過串口直接下載程序(不是用 ST-Link),F103 的系統引導支持串口 ISP:
      拉高 BOOT0(接 3.3V),BOOT1 置 0(接 GND;很多小板 BOOT1 固定為 0)。
      復位/上電,芯片進入 System Memory (內置 bootloader)。
      用 STM32CubeProgrammer(或老的 Flash Loader Demonstrator)選擇 UART,波特率 115200,連上你的 USB-TTL(仍是 TX?RX 交叉、GND 共地)。
      識別到芯片后,選擇要燒的 .hex/.bin 下載。
      燒完把 BOOT0 拉回 0,再復位,才會從 用戶 Flash 運行你的應用。
      如果連不上:檢查波特率、接線、是否真的把 BOOT0 拉到 1;某些小板需要按住復位再松開。

      0x00目標外設與引腳

      • USART1:PA9(TX), PA10(RX) @ 115200, 8N1,中斷收
      • I2C1:PB6(SCL), PB7(SDA) @ 100 kHz(先穩后快)
      • 上拉:SCL/SDA 建議各接 4.7k–10kΩ 到 3.3V(若暫時沒有,見文末“臨時上拉”)

      0x01) 時鐘(RCC → Clock Configuration)

      HSE: Crystal/Ceramic Resonator(8 MHz 常見)
      PLL: ON, PLL MUL = x9
      SYSCLK = 72 MHz
      AHB = 72 MHz, APB1 = 36 MHz, APB2 = 72 MHz
      Flash Latency: 2 WS
      SysTick: 1ms(默認)

      這套時鐘能保證 USART 波特率精準、I2C穩定。

      0x02) GPIO(Pinout & Configuration)

      無需手動給 I2C/USART 分配模式,CubeMX 勾外設會自動配置:

      • USART1_TX → PA9(AF Push-Pull)

      • USART1_RX → PA10(Input Floating)

      • I2C1_SCL → PB6(AF Open-Drain)

      • I2C1_SDA → PB7(AF Open-Drain)

      如果你暫時沒有外部上拉,見第 6 節“臨時內部上拉”。

      0x03) I2C1 配置(Peripherals → I2C1)

      Mode: I2C
      Timing/Speed: Standard Mode (100 kHz)(跑通后再改 400 kHz)
      Own Address1: 0
      Addressing: 7-bit
      Stretch Mode: Enabled(默認)
      NVIC: 都不勾(用阻塞/簡單 HAL 調用即可;你的 SSD1306 驅動都是阻塞發)

      你的代碼用 HAL_I2C_Master_Transmit(&hi2c1, 0x78, ...),這是8位地址(0x3C<<1)。保持即可。

      0x04) USART1 配置(Peripherals → USART1)

      Mode: Asynchronous
      Baud Rate: 115200
      Word Length: 8 Bits
      Parity: None
      Stop Bits: 1
      OverSampling: 16
      NVIC:勾選 USART1 global interrupt(開啟中斷)
      DMA:暫不啟用(先中斷版穩定后再上 DMA)
      生成后在 main() 里調用一次 HAL_UART_Receive_IT(&huart1, &rx_byte, 1); 開始中斷收。

      0x06) (可選)“臨時內部上拉”方案

      不建議長期使用,僅在你手上沒電阻、線很短(<5cm)、速度 100 kHz 時湊合測通電:
      在 MX_I2C1_Init() 之前,手動給 PB6/PB7 加上拉(F1 的 I2C 引腳內部上拉弱):
      在 MX_I2C1_Init() 之前,手動給 PB6/PB7 加上拉(F1 的 I2C 引腳內部上拉弱):

      // 在 MX_I2C1_Init(); 調用之前插入:
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      __HAL_RCC_GPIOB_CLK_ENABLE();
      GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
      GPIO_InitStruct.Pull = GPIO_PULLUP;              // 臨時內部上拉(弱)
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
      
      若出現 NACK/卡死/亂碼,立刻改用外部 4.7k–10kΩ上拉。
      點擊查看代碼
      #include "main.h"
      #include "gpio.h"
      #include "i2c.h"
      #include "usart.h"
      #include "oled.h"     // 你提供的
      #include <string.h>
      #include <ctype.h>
      
      #define OLED_COLS 16   // 128/8 = 16 列(你的 8x16 字庫)
      #define OLED_LINES 4   // 64/16 = 4 行
      
      // ====== 串口中斷接收相關 ======
      static uint8_t rx_byte;                 // 單字節中斷接收
      static char    line_buf[64];            // 輸入緩沖(足夠放一行及回車)
      static uint8_t line_len = 0;
      
      // 保持 4 行窗口滾動顯示
      static char scr[OLED_LINES][OLED_COLS+1];  // 每行16列 + '\0'
      
      static void SCR_ClearAll(void) {
          for (int r=0; r<OLED_LINES; ++r) {
              memset(scr[r], ' ', OLED_COLS);
              scr[r][OLED_COLS] = '\0';
          }
      }
      
      static void SCR_Render(void) {
          // 將 scr[0..3] 渲染到 OLED 第 1..4 行
          for (int r=0; r<OLED_LINES; ++r) {
              OLED_ShowString(r+1, 1, scr[r]);
          }
      }
      
      // 將一段字符串分塊(<=16列)寫入屏幕,自動滾動
      static void SCR_PushText(const char* s) {
          size_t n = strlen(s);
          size_t idx = 0;
          while (idx < n) {
              char line[OLED_COLS+1];
              size_t chunk = (n - idx > OLED_COLS) ? OLED_COLS : (n - idx);
              memcpy(line, s + idx, chunk);
              // 填空格到16列
              if (chunk < OLED_COLS) memset(line + chunk, ' ', OLED_COLS - chunk);
              line[OLED_COLS] = '\0';
      
              // 滾動:0<-1<-2<-3,最后一行寫新內容
              for (int r=0; r<OLED_LINES-1; ++r) {
                  memcpy(scr[r], scr[r+1], OLED_COLS+1);
              }
              memcpy(scr[OLED_LINES-1], line, OLED_COLS+1);
      
              idx += chunk;
          }
          SCR_Render();
      }
      
      // 顯示提示或系統消息(前綴 ">> ",便于區分)
      static void SCR_PushSys(const char* s) {
          char msg[64];
          snprintf(msg, sizeof(msg), ">> %s", s);
          SCR_PushText(msg);
      }
      
      // 在收到一行(以 \n 結束)時調用:把 line_buf 顯示出來(忽略控制字符)
      static void Handle_OneLine(const char* in) {
          char cleaned[sizeof(line_buf)];
          size_t w = 0;
          for (size_t i=0; in[i] && w < sizeof(cleaned)-1; ++i) {
              char c = in[i];
              if (c == '\r' || c == '\n') continue;
              // 僅顯示可打印 ASCII(0x20~0x7E)
              if (isprint((unsigned char)c)) cleaned[w++] = c;
          }
          cleaned[w] = '\0';
          if (w == 0) return;
      
          SCR_PushText(cleaned);
      }
      
      int main(void)
      {
          HAL_Init();
          SystemClock_Config();
      
          MX_GPIO_Init();
          MX_I2C1_Init();
          MX_USART1_UART_Init();
      
          // OLED 初始化 & 清屏
          OLED_Init();
          SCR_ClearAll();
          OLED_Clear();
          SCR_PushSys("UART@115200 8N1");
          SCR_PushSys("Send text to show");
      
          // 啟動一次串口中斷接收
          HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
      
          while (1) {
              HAL_Delay(50);
          }
      }
      
      // 串口中斷回調:逐字接收,遇到 '\n' 視為一行
      void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
      {
          if (huart->Instance == USART1) {
              uint8_t c = rx_byte;
      
              // 回顯(可選):把收到的字節發回 PC
              HAL_UART_Transmit(&huart1, &c, 1, 10);
      
              if (c == '\n') {
                  // 結束一行
                  line_buf[line_len] = '\0';
                  Handle_OneLine(line_buf);
                  line_len = 0;
              } else if (c != '\r') {
                  // 累積到緩沖(防溢出)
                  if (line_len < sizeof(line_buf) - 1) {
                      line_buf[line_len++] = (char)c;
                  } else {
                      // 太長則直接做成一行顯示并清空
                      line_buf[line_len] = '\0';
                      Handle_OneLine(line_buf);
                      line_len = 0;
                  }
              }
      
              // 繼續掛下一次接收
              HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
          }
      }
      

      image
      image
      image
      image

      posted @ 2025-08-12 13:35  huh&uh  閱讀(96)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲av无码国产在丝袜线观看| 都昌县| 久久精品熟女亚洲av麻| 粉嫩一区二区三区精品视频 | 成人国产一区二区三区精品| 久久综合亚洲鲁鲁九月天| 延吉市| 韩国三级在线 中文字幕 无码| 日韩精品成人一区二区三区| 日韩V欧美V中文在线| 色综合久久中文字幕综合网| 久久久av男人的天堂| 国产一区二区三区禁18| 正在播放酒店约少妇高潮| 国产性一交一乱一伦一色一情| 久久精品国产亚洲综合av| 国产99久一区二区三区a片| 天堂中文8资源在线8| 国产精品丝袜亚洲熟女| 亚洲精品毛片一区二区| 97人妻无码一区| 国产69精品久久久久99尤物| 共和县| 亚洲中文一区二区av| 116美女极品a级毛片| 99久久亚洲综合精品成人网| 国产对白老熟女正在播放| 毛片亚洲AV无码精品国产午夜| 亚洲国产成人无码影院| 在线精品另类自拍视频| 国产啪视频免费观看视频| 久久三级国内外久久三级| 国产一区二区波多野结衣| 亚洲一区二区精品极品| 亚洲乱码日产精品一二三| 久久天天躁狠狠躁夜夜躁2o2o| 成全高清在线播放电视剧| 一 级做人爱全视频在线看| 精品一区二区不卡免费| 欧洲中文字幕一区二区| 米奇亚洲国产精品思久久|