TERMIOS C程序与STM32F103和#xB5通信;C

TERMIOS C程序与STM32F103和#xB5通信;C,c,usb,microcontroller,stm32,termios,C,Usb,Microcontroller,Stm32,Termios,我在stm32f103c8t6上,使用STMDP Lib,使用stm32的usb库作为虚拟com端口,希望通过termios Pc程序与µC通话。termios程序可以读取芯片通过USB发送的数据,但当我想要应答时,芯片不会对我发送的数据做出反应。发送时我做错了什么 termios计划: #include <stdio.h> #include <unistd.h> #include <termios.h> #include <fcntl.h> #i

我在stm32f103c8t6上,使用STMDP Lib,使用stm32的usb库作为虚拟com端口,希望通过termios Pc程序与µC通话。termios程序可以读取芯片通过USB发送的数据,但当我想要应答时,芯片不会对我发送的数据做出反应。发送时我做错了什么

termios计划:

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
typedef联合{
int-num;
字符部分[2];
}_16至8;
静态void sendData(int tty,无符号字符c){
写入(tty和c,1);
}
静态无符号字符读取数据(int-tty){
无符号字符c;
while(read(tty,&c,1)>8);
_16to8num={0};
num.part[0]=sizR[0];
零件编号[1]=尺寸[1];
sendCmd(tty_fd,(char*)和num.num,2);
字符缓冲区[2]={0};
int i=0;
while(fread(&buffer,1,4,fd)){
//sendCmd(tty_fd,缓冲器,4);
//printf(“%s\n”,readALotOfData(tty_fd,5));
}
}否则{
printf(“将擦除设备的内存\n”);
sendCmd(tty_fd,(char*)0xE2A5,2);
}
关闭(tty_fd);
返回0;
}
µC程序:

#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();
      }
    }
  }
}
#包括“stm32f10x_conf.h”
#包括“main.h”
无效擦除FlashPage(uint8\u t页){
uint32\u t addr=闪存地址+0x400*页;
闪光解锁();
闪存清除标志(闪存清除标志|闪存清除标志|闪存清除标志|闪存清除标志| EOP);
闪存页(地址);
闪光锁();
}
无效writeFlashAddr(uint8页面,uint16偏移量,uint32数据){
uint32\u t addr=闪存地址+0x400*页面+偏移量;
闪光解锁();
闪存清除标志(闪存清除标志|闪存清除标志|闪存清除标志|闪存清除标志| EOP);
闪存编程字(地址,(uint32)数据);
闪光锁();
}
uint32\u t readFlashAddr(uint8\u t页){
uint32\u t addr=闪存地址+0x400*页;
返回*(uint32_t*)地址;
}
void TIM2_IRQHandler(){
静态整数计数=0;
if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=重置){
TIM_ClearITPendingBit(TIM2,TIM_IT_更新);
如果(模式){
如果(计数=2){
计数=0;
GPIO_切换位(GPIOA、GPIO_引脚_15);
}
计数++;
}否则{
GPIO_切换位(GPIOA、GPIO_引脚_15);
}
}
}
int main(){
Set_System();
设置_USBClock();
USB_中断_配置();
USB_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,启用);
RCC_APB2PeriphLockCmd(RCC_APB2Periph_GPIOA,启用);
GPIO_重新映射配置(GPIO_重新映射_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_写入比特(GPIOA、GPIO_引脚_15、位_复位);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,启用);/200Hz->8Hz
TIM_TimeBaseInitTypeDef timStruct;
timStruct.TIM_预分频器=60000;
timStruct.TIM\u CounterMode=TIM\u CounterMode\u Up;
timStruct.TIM_Period=50;//0.125s时的ISR
timStruct.TIM_ClockDivision=TIM_CKD_DIV4;
timStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2和timStruct);
TIM_Cmd(TIM2,启用);
TIM_ITConfig(TIM2、TIM_IT_更新、启用);
NVIC_InitTypeDef nvicStruct;
nvicStruct.NVIC_IRQChannel=TIM2_IRQn;
nvicStruct.NVIC\u IRQChannelPreemptionPriority=0;
nvicStruct.NVIC_IRQChannelSubPriority=1;
nvicStruct.NVIC_IRQChannelCmd=启用;
NVIC_Init(&nvicStruct);
_延迟μms(500);
而(1){
模式=0;
接收长度=0;
char bootID[64];
对于(挥发性uint32_t cnt=0;cnt<4800*5000/4/25;cnt++){
_printf(“1234AABBCC1234”);
CDC_接收_数据();
如果(接收长度>=14){
_获取((char*)&bootID,14);
如果(!memcmp(bootID,“4321CCBBAA4321”,14)){
模式=1;
打破
}
接收长度=0;
}
}
如果(模式){
uint32_t opt=0;
_printf(“操作模式?\n”);//调试
_获取((char*)&opt,2);
如果(opt==0xF1A5){
uint32_t len=0;
uint32_t数据=0;
uint16_t i=0;
_获取((char*)&len,2);
_printf(“从0x%x\n开始写入%d/%d字节”,len,(117-开始页)*1024,FLASH\u ADDR);//调试
如果(len<(117-起始页)*1024){//117或64?
_printf(“开始写入闪存”;//调试
对于(i=0;i ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
NVIC->ICPR[0]=0xFFFFFFFF;
NVIC->ICPR[1]=0xFFFFFFFF;
断电();
p函数jmpUser;
uint32\u t jmpAddr=*(\u IO uint32\u t*)(闪存地址+4);
jmpUser=(pFunction)jmpadr;
__设置MSP(*(IO uint32 t*)闪存地址;
jmpUser();
}
}否则{
_printf(“可用闪存空间不足\n”);//调试
}
}else if(opt==0xE2A5){
对于(int i=0;i<(117-起始页面);i++){
第(i)页;
_printf(“擦除页面%d\n”,i);//调试
}
}
}否则{
uint32_t sp=*(uint32_t*)闪存地址;
如果((sp&0x2FF0000)==0x20000000){
TIM_Cmd(TIM2,禁用);
GPIO_写入比特(GPIOA、GPIO_引脚_15、位_复位);
NVIC->ICER[0]=0xFFFFFFFF;
NVIC->ICER[1]=0xFFFFFFFF;
NVIC->ICPR[0]=0xFFFFFFFF;
NVIC->ICPR[1]=0xFFFFFFFF;
断电();
p函数jmpUser;
uint32\u t jmpAddr=*(\u IO uint32\u t*)(闪存地址+4);
jmpUser=(pFunction)jmpadr;
__设置MSP(*(IO uint32 t*)闪存地址;
jmpUser();
}
}
}
}
我想发送标识字符串,然后输入操作…我的一个朋友得到了一个使用serialport库的工作程序,但我想使用termios


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

好吧,代码开头的联合是个问题,也许你很幸运,也许你没有。没有深入研究其余部分。控制器看到了什么?你发送的是什么,是你期望的吗(将它循环回另一个uart