TERMIOS C与STM32F103μC进行通信的程序

时间:2017-05-30 05:20:24

标签: c usb microcontroller stm32 termios

我在stm32f103c8t6上使用STDP-Lib,使用stm32的usb库进行虚拟com端口,并想通过termios-Pc-program与μC交谈。 termios程序可以读取芯片通过USB发送的数据,但是当我想回答时,芯片对我发送的数据没有反应。发送时我做错了什么?

termios-program:

#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

typedef union {
  int num;
  char part[2];
} _16to8;

static void sendData(int tty, unsigned char c) {
  write(tty, &c, 1);
}

static unsigned char readData(int tty) {
  unsigned char c;
  while(read(tty, &c, 1) <= 0);
  return c;
}

static unsigned char* readALotOfData(int tty, int len) {
  unsigned char* c = NULL;
  c = calloc(len, sizeof(unsigned char));
  for(int i = 0; i < len; i++) {
    c[i] = readData(tty);
  }
  return c;
}

static void sendCmd(int tty, char* c, size_t len) {
  unsigned char* a = NULL;
  int i = 0;
  a = calloc(len, sizeof(unsigned char));
  memcpy(a, c, len);
  for(; i < len; i++) {
    sendData(tty, a[i]);
  }
  free(a);
  a = NULL;
}

int main(int argc, char** argv) {
  struct termios tio;
  int tty_fd;
  FILE* fd;

  struct stat st;

  unsigned char c;
  unsigned char* buf = NULL;
  buf = calloc(4096, sizeof(unsigned char));

  memset(&tio, 0, sizeof(tio));
  tio.c_cflag = CS8;

  tty_fd = open(argv[1], O_RDWR | O_NONBLOCK);
  if(tty_fd == -1) {
    printf("failed to open port\n");
    return 1;
  }

  char mode;
  if(!strcmp(argv[2], "flash")) {
    mode = 1;
    fd = fopen(argv[3], "r");
    if(fd == NULL) {
      printf("failed to open file\n");
      return 1;
    }
  } else if(!strcmp(argv[2], "erase")) {
    mode = 0;
  } else {
    printf("unknown operation mode\n");
    return 1;
  }

  cfsetospeed(&tio, B115200);
  cfsetispeed(&tio, B115200);

  tcsetattr(tty_fd, TCSANOW, &tio);

  unsigned char* id = readALotOfData(tty_fd, 20);
  printf("%s\n", id);
  if(strstr((const char*)id, "1234AABBCC1234")) {
    sendCmd(tty_fd, "4321CCBBAA4321", 14);
    printf("id verified\n");
  } else {
    printf("Could not identify device\n");
    return 1;
  }

  if(mode) {
    printf("going to flash the device\n");
    sendCmd(tty_fd, "\xF1\xA5", 2);
    stat(argv[3], &st);
    int siz = st.st_size;
    char sizR[2] = "\0";
    sizR[1] = (unsigned char)(siz & 0xFF);
    sizR[0] = (unsigned char)(siz >> 8);
    _16to8 num = {0};
    num.part[0] = sizR[0];
    num.part[1] = sizR[1];
    sendCmd(tty_fd, (char*)&num.num, 2);
    char buffer[2] = {0};
    int i = 0;
    while(fread(&buffer, 1, 4, fd)) {
      // sendCmd(tty_fd, buffer, 4);
      // printf("%s\n", readALotOfData(tty_fd, 5));
    }
  } else {
    printf("going to erase the device's memory\n");
    sendCmd(tty_fd, (char*)0xE2A5, 2);
  }

  close(tty_fd);

  return 0;
}

μCProgram:

#include "stm32f10x_conf.h"
#include "main.h"

void eraseFlashPage(uint8_t page) {
  uint32_t addr = FLASH_ADDR + 0x400 * page;
  FLASH_Unlock();
  FLASH_ClearFlag(FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_EOP);
  FLASH_ErasePage(addr);
  FLASH_Lock();
}

void writeFlashAddr(uint8_t page, uint16_t offset, uint32_t data) {
  uint32_t addr = FLASH_ADDR + 0x400 * page + offset;
  FLASH_Unlock();
  FLASH_ClearFlag(FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_EOP);
  FLASH_ProgramWord(addr, (uint32_t)data);
  FLASH_Lock();
}

uint32_t readFlashAddr(uint8_t page) {
  uint32_t addr = FLASH_ADDR + 0x400 * page;
  return *(uint32_t*)addr;
}

void TIM2_IRQHandler() {
  static int count = 0;
  if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    if(mode) {
      if(count == 2) {
        count = 0;
        GPIO_ToggleBits(GPIOA, GPIO_Pin_15);
      }
      count++;
    } else {
      GPIO_ToggleBits(GPIOA, GPIO_Pin_15);
    }
  }
}

int main() {
  Set_System();
  Set_USBClock();
  USB_Interrupts_Config();
  USB_Init();

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  GPIO_InitTypeDef gpioStruct;
  gpioStruct.GPIO_Pin = GPIO_Pin_15;
  gpioStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  gpioStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &gpioStruct);
  GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_RESET);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 200Hz -> 8Hz
  TIM_TimeBaseInitTypeDef timStruct;
  timStruct.TIM_Prescaler = 60000;
  timStruct.TIM_CounterMode = TIM_CounterMode_Up;
  timStruct.TIM_Period = 50;                          // ISR at 0.125s
  timStruct.TIM_ClockDivision = TIM_CKD_DIV4;
  timStruct.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM2, &timStruct);
  TIM_Cmd(TIM2, ENABLE);
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

  NVIC_InitTypeDef nvicStruct;
  nvicStruct.NVIC_IRQChannel = TIM2_IRQn;
  nvicStruct.NVIC_IRQChannelPreemptionPriority = 0;
  nvicStruct.NVIC_IRQChannelSubPriority = 1;
  nvicStruct.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&nvicStruct);

  _delay_ms(500);

  while(1) {

    mode = 0;
    Receive_length = 0;
    char bootID[64];

    for(volatile uint32_t cnt = 0; cnt < 4800 * 5000 / 4 / 25; cnt++) {
      _printf("1234AABBCC1234");
      CDC_Receive_DATA();
      if(Receive_length >= 14) {
        _gets((char*)&bootID, 14);
        if(!memcmp(bootID, "4321CCBBAA4321", 14)) {
          mode = 1;
          break;
        }
        Receive_length = 0;
      }
    }

    if(mode) {
      uint32_t opt = 0;
      _printf("operating mode?\n"); //debug
      _gets((char*)&opt, 2);

      if(opt == 0xF1A5) {
        uint32_t len = 0;
        uint32_t data = 0;
        uint16_t i = 0;

        _gets((char*)&len, 2);
        _printf("writing %d/%d bytes starting at 0x%x\n", len, (117 - START_PAGE) * 1024, FLASH_ADDR); // debug

        if(len < (117 - START_PAGE) * 1024) { // 117 or 64?
          _printf("start writing to flash\n"); //debug

          for(i = 0; i <= len / 1024; i++) {
            eraseFlashPage(i);
            _printf("erasing page %d\n", i); //debug
          }

          for(i = 0; i < len; i += 4) {
            uint8_t page = i / 1024;
            _printf("i:%d page:%d offset:%d\n", i, page, i - page * 1024); // debug
            _gets((char*)&data, 4);
            writeFlashAddr(page, i - page * 1024, data);
            _printf("Page %d and 0x%x\n", page, FLASH_ADDR + 0x400 * page + i - page * 1024); // debug
          }

          _printf("done\n"); //debug

          uint32_t sp = *(uint32_t*) FLASH_ADDR;
          if((sp & 0x2FFF0000) == 0x20000000) {
            TIM_Cmd(TIM2, DISABLE);
            GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_RESET);
            NVIC->ICER[0] = 0xFFFFFFFF;
            NVIC->ICER[1] = 0xFFFFFFFF;
            NVIC->ICPR[0] = 0xFFFFFFFF;
            NVIC->ICPR[1] = 0xFFFFFFFF;
            PowerOff();
            pFunction jmpUser;
            uint32_t jmpAddr = *(__IO uint32_t*)(FLASH_ADDR + 4);
            jmpUser = (pFunction)jmpAddr;
            __set_MSP(*(__IO uint32_t*)FLASH_ADDR);
            jmpUser();
          }
        } else {
          _printf("not enought flash space available\n"); //debug
        }
      } else if(opt == 0xE2A5) {
        for(int i = 0; i < (117 - START_PAGE); i++) {
          eraseFlashPage(i);
          _printf("erasing page %d\n", i); //debug
        }
      }
    } else {
      uint32_t sp = *(uint32_t*) FLASH_ADDR;
      if((sp & 0x2FFF0000) == 0x20000000) {
        TIM_Cmd(TIM2, DISABLE);
        GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_RESET);
        NVIC->ICER[0] = 0xFFFFFFFF;
        NVIC->ICER[1] = 0xFFFFFFFF;
        NVIC->ICPR[0] = 0xFFFFFFFF;
        NVIC->ICPR[1] = 0xFFFFFFFF;
        PowerOff();
        pFunction jmpUser;
        uint32_t jmpAddr = *(__IO uint32_t*)(FLASH_ADDR + 4);
        jmpUser = (pFunction)jmpAddr;
        __set_MSP(*(__IO uint32_t*)FLASH_ADDR);
        jmpUser();
      }
    }
  }
}

我想发送识别字符串然后输入操作....我的朋友得到了一个使用serialport-lib的工作程序,但我想使用termios ...

任何人都知道为什么控制器没有对发送的数据做出反应?

0 个答案:

没有答案
相关问题