Skip to main content
 首页 » 编程设计

python之PySerial 和微 Controller

2025年05月04日10davidwang456

我正在尝试使用 pySerial 通过 UART 与 MCU 通信。 我使用 Arduino USB2Serial Light Converter 将数据从 PC 发送到我的 PIC33F。 由于 Arduino 转换器,我无法使用 CTS 或 RTS。

我设法向 MCU 发送数据并从中接收数据。但问题是 数据并不总是应有的样子。

例如,我想将整个字符串从 MCU 发送到终端,但我得到的不是 MCU 程序代码中给出的字符串。另一个问题是 角色之间没有比较有效。这意味着我向 MCU 发送一个字符,MCU 将它与一个字符进行比较以做出决定。

现在开始一些代码:

1。从 PIC33F 发送字符串到 PC 并用 pySerial 读取它

putsU1("string"); 
 
// print a string 
 
    int putsU1(char *s) { 
     while(*s) 
        putU1(*s++);  
    } 
 
// print a character 
 
    int putU1(int c) { 
      while (_UTXBF); 
        U1TXREG = c; 
      return c;  
    } 

如果我通过 pySerial 读取这段代码,我得到的结果如下;

In [13]: ser = serial.Serial('/dev/ttyACM0', 9600, bytesize=7, xonxoff=0) 
 
In [14]: while True:                                                      
            print(struct.unpack('s', ser.read())) 
         ....:      
('\x7f',) 
('c',) 
('\x11',) 
('\t',) 
('e',) 
('y',) 
('=',) 
('\x7f',) 

2。使用 pySerial 向 PIC33F 发送数据并回显

这只适用于单个字符,不适用于字符串。回显的字符也在大写和小写之间随机切换。

     getsnU1(s, BUF_SIZE); 
 
     char *getsnU1(char *s, int len) { 
        char *p = s; 
        int cc = 0; 
        do { 
           *s = getU1(); 
           putU1(*s); 
 
           if ((*s == 0x8) && (s > p)) { 
              putU1(' '); 
              putU1(0x8); 
              len++; 
              s--; 
              continue; 
           } 
 
           if (*s == '\n') 
              continue; 
 
           if (*s == '\r') 
              break; 
           s++; 
          len--; 
       } while (len > 1); 
 
      *s = '\0'; 
 
      return p; 
    } 

串口配置:

#define FOSC            8000000 
#define FCY             (FOSC/2) 
#define BAUD            9600 
#define U1BRGValue      (((FCY/BAUD)/16)-1) 
 
void initUART1(void) { 
/* general UART config */ 
RPINR18bits.U1RXR = U1RXPIN;            // set RP5 as UART1 RX 
_RP6R = 0b00011;                        // set RP6 as UART Tx pin 
U1RXPINTRIS = 1;                        // set RP5 (RB5) as input 
U1MODEbits.PDSEL = DATAPARITY;           // set data bits and parity 
U1MODEbits.STSEL = STOPBITS;            // set stop bits 
U1MODEbits.ABAUD = 0;                   // auto-baud disabled 
U1MODEbits.BRGH = 0;                    // low speed baud rate 
U1BRG = U1BRGValue;                     // set baud value 
 
 
/* enable interrupt on error */ 
IEC4bits.U1EIE = 1;                     // enable UART1 error interrupt 
IPC16bits.U1EIP = 6;                     // set interrupt priority to 6 
 
/* enable RX buffer interrupt */ 
IEC0bits.U1RXIE = 0;                    // enable UART1 RX interrupt 
U1STAbits.URXISEL = 0b00;                // interrupt flag is set when buffer is 3/4 full 
IPC2bits.U1RXIP = 6;                     // set interrupt priority to 6 
 
/* enable TX interrupt */ 
IEC0bits.U1TXIE = 0; 
 
 
/* enable UART1 module */ 
U1MODEbits.UEN = 0b00; 
U1MODEbits.UARTEN = 1; 
_UTXEN = 1;                             // enable UART Tx 

我有点沮丧,因为我无法弄清楚问题出在哪里。已经测试和阅读了几个小时,到处都是,启动和运行它似乎很简单,但它不会在我这边;(。 我尝试使用 serial.write('text'.encode('ascii')) 将数据写入 PIC33F 并 serial.write(struct.pack('s',('test'))) 产生相同的结果。

非常感谢任何帮助!

请您参考如下方法:

我认为您不需要 bytesize=7(除非您确切知道原因)。

此外,UART 的一个经典问题是单个字符有效,但整个字符串无效 - 这通常发生在接收微 Controller 仅在硬件中缓冲单个字符时。我不知道 PIC,但在上面的代码中,你执行 getU1() 后跟 putU1() 我猜 putU1() 等待一个字符的持续时间,所以当你稍后再次调用 getU1() 时你会错过一个字符(如果软件没有暂停发送它)。

我通常的解决方法是这样的:

def write(s): 
    for c in s: 
        ser.write(c) 
        time.sleep(0.001) # often not required 

一般来说,pyserial 似乎对我的所有项目都可以正常工作,但你也应该检查一个普通的终端程序来确定。除此之外,我只能建议您仔细检查微 Controller 上的波特率和 FOSC。