RS232-USART1 รับค่า Keyboard ผิดพลาด ครับ

Started by TaoTao, March 13, 2017, 11:31:10 AM

Previous topic - Next topic

TaoTao

คือ ผมใช้ Keyboard Com ส่งค่าผ่าน RS-232 เข้า USART1 แบบ DMA ของ STM32F103
แล้ว MCU รับค่าเก็บในตัวแปร key_get[6]
จากนั้น แสดงผลออก จอ LCD แบบ I2C

หาก ตั้งค่า USART เก็บทีละ มากกว่า 1 char ก็แสดงผลปกติดี
(รูปแนบ 2 ไฟล์แรก)

แต่ ทีผิดปกติ คือ
หากผมตั้งค่า URAST_DMA เก็บทีละ 1 char แล้วส่งค่าสู่ LCD เพื่อแสดงผลทันที

เมื่อกดแป้น KEYBOARD ป้อนตัวเลขเดิม เช่น 1111
แต่ ปรากฎ มันกลายเป็น 1ฑ1ฑ ครับ (รูปแนบ 2 ไฟล์ ล่าง)

กำลังไล่อยู่ ว่า ปัญหาเกิดที่ไหน
เพราะ ฑ Hex เท่ากับ (0x31+0x80)
ซึ่ง 0x80 = 128 คือ 7 bits พอดีเลย

ไม่ได้เป็นเฉพาะเลข 1 นะครับ
แต่เป็นทุกตัวเลย คือ ถ้ากดซ้ำแล้วมันจะรับค่าเพี้ยนทันที
แต่ กดอีกที ค่าจะถูกต้อง สลับกันอยู่อย่างนี้  :-[

ใครเคยเจอปัญหานี้บ้างเปล่าครับ

ขอบคุณล่วงหน้าครับ
นี่โค้ดครับ

char key_get[6]= {0,0,0,0,0,0};

int main(void)
{

  /* USER CODE BEGIN 1 */

uint16_t i = 0;
char key_get[6]= {0,0,0,0,0,0};

  /* USER CODE END 1 */

  /* MCU Configuration---------123-------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

LCD_init();
LCD_put_str(0x85, "Hello", 0);

HAL_UART_Receive_DMA(&huart1, key_get, 1);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

if( key_get[i] == 0 ){
continue;
}

// ESCAPE : CLR_DISPLAY
if( key_get[i] == 0x1B ){
LCD_CLR;
i=0;
key_get[0] = 0;
key_get[1] = 0;
key_get[2] = 0;
key_get[3] = 0;
key_get[4] = 0;
key_get[5] = 0;
HAL_UART_Receive_DMA(&huart1, &key_get[0], 1);
continue;
}

if( ++ i == 5 ){

LCD_put_str(0xC0, "     ", i);
LCD_put_str(0xC0, key_get, 4);

i=0;
key_get[0] = 0;
key_get[1] = 0;
key_get[2] = 0;
key_get[3] = 0;
key_get[4] = 0;
key_get[5] = 0;
HAL_UART_Receive_DMA(&huart1, &key_get[0], 1);
continue;
}

LCD_put_str(0xC0, "     ", i);
LCD_put_str(0xC0, key_get, i);

HAL_UART_Receive_DMA(&huart1, &key_get[i], 1);
continue;
}
  /* USER CODE END 3 */
}

TaoTao

ปัจจุบัน ผมสร้างโค้ด ดักไม่ให้ค่ามันเกิน 0x80
เพื่อให้มันแสดงผลถูกต้อง
แต่ ยังไม่รู้สาเหตุน่ะครับ

หมูน้อย

ตรงฟังก์ชัน MX_USART1_UART_Init เซ็ตค่า WordLength ไว้เท่าไหร่ครับ

ลองเปลี่ยนเป็น huart1.Init.WordLength = UART_WORDLENGTH_8B; ดูครับ


az

7 bit data + no parity bit + 1 stop bit  หรือ
8 bit data + no parity bit + 1 stop bit

ตรวจสอบ config ก่อนครับ  แล้วลองจับสัญญาณ usart time frame ดูครับ
เพราะแสวงหา..  มิใช่เพราะรอคอย
เพราะเชี่ยวชาญ..  มิใช่เพราะโอกาส
เพราะสามารถ..  มิใช่เพราะโชคช่วย
ดังนี้แล้ว "ลิขิตฟ้า  หรือจะสู้มานะตน..."

TaoTao

ขอบคุณทุกคนมากครับ

เซ็ต MX ให้ initial เป็น :
8 bits length + no_par + 1_stop มันจะเป็นครับ

พอมาเซ็ต MX เป็น 9 bits length + no_par + 1_stop
แต่ hyper termital ยังเซ็ต ดาต้า เป็น 8 bits
อ่าว หายแหล่ว
ทำไมเป็นเช่นนี้
:P

โคด ที่ใช้แล้วแสดงค่า ปกติ ครับ
ไม่ได้พิมพ์เองครับ MX เค้าจัดให้
;D

/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_9B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
}

az

ถ้าใช้ 8 bits length + no_par + 1_stop แต่ลดค่า BaudRate เป็น 9600 ผลลัพธ์เป็นอย่างไรบ้างครับ
เพราะแสวงหา..  มิใช่เพราะรอคอย
เพราะเชี่ยวชาญ..  มิใช่เพราะโอกาส
เพราะสามารถ..  มิใช่เพราะโชคช่วย
ดังนี้แล้ว "ลิขิตฟ้า  หรือจะสู้มานะตน..."