【问题标题】:PySerial and microcontrollerPySerial 和微控制器
【发布时间】:2012-06-09 21:28:21
【问题描述】:

我正在尝试使用 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;
    }

UART 配置:

#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'))) 都产生相同的结果。

非常感谢任何帮助!

【问题讨论】:

标签: python microcontroller pic pyserial uart


【解决方案1】:

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

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

我通常的解决方法是:

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

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

【讨论】:

  • 你的权利!函数getsnU1 也使用getU1,表示一次一个字符。我必须使用 7 的字节大小,因为如果我不这样做,我就不会从 PIC 中获得任何可读数据。这有点奇怪,因为 PIC 的字节大小为 8。我试图实现一个软件控制流来摆脱一些奇怪的行为,但它不起作用,因为接收到的字符的比较不起作用。 if (c == '\x11') --> 不能使用 serial.write('\x11') putsU1("string\n"); --> 产生类似 s\x7f\tr\x7fi\x7fng 的输出并且字节 \x7f 随机出现
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 2011-02-24
  • 2021-12-03
相关资源
最近更新 更多