TERMIOS C程序与STM32F103和#xB5通信;C
我在stm32f103c8t6上,使用STMDP Lib,使用stm32的usb库作为虚拟com端口,希望通过termios Pc程序与µC通话。termios程序可以读取芯片通过USB发送的数据,但当我想要应答时,芯片不会对我发送的数据做出反应。发送时我做错了什么 termios计划: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
#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