找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1032|回复: 0
打印 上一主题 下一主题
收起左侧

51低速数字信号发生和采样器 51单片机Python串口上位机代码

[复制链接]
跳转到指定楼层
楼主

简介:配合Python上位机独立控制51单片机的4个GPIO端口的输入输出,在9600波特率下通过上位机控制MCU翻转IO速率达到218Hz,可适用于低速情况下的自动化测试场景。本项目仅供学习娱乐,可能存在未知问题和疏漏,不建议用于真实场景,对此不负任何责任。

关于通信协议:
默认波特率为9600,使用偶校验
数据位76543210
说明P3端口
read  = 0
write = 1
P2端口
read  = 0
write = 1
P1端口
read  = 0
write = 1
P0端口
read  = 0
write = 1
使能P3端口使能P2端口使能P1端口使能P0端口


示例:






MCU代码:

Python上位机代码:




  1. # TEST = 0x00
  2. # ERASE_EXTERNAL_FLASH_SECTOR = 0x06
  3. # WRITE_EXTERNAL_FLASH_SECTOR = 0x07
  4. # READ_SECTOR = 0x08
  5. # RESET = 0x04
  6. import serial

  7. PORT   = 0b1111
  8. PORT_0 = 0b0001
  9. PORT_1 = 0b0010
  10. PORT_2 = 0b0100
  11. PORT_3 = 0b1000

  12. PORT_READ    = 0b00000000
  13. PORT_WRITE   = 0b11110000
  14. PORT_0_WRITE = 0b00010000
  15. PORT_1_WRITE = 0b00100000
  16. PORT_2_WRITE = 0b01000000
  17. PORT_3_WRITE = 0b10000000

  18. def GPIO_CTL(serial_f,PORT, OP, data = []):
  19.     readSize = 0
  20.     readSize += (PORT & PORT_0 > 0)
  21.     readSize += (PORT & PORT_1 > 0)
  22.     readSize += (PORT & PORT_2 > 0)
  23.     readSize += (PORT & PORT_3 > 0)

  24.     CMD = bytes([OP | PORT])
  25.     if (OP & PORT_0_WRITE):
  26.         CMD += data[0].to_bytes(1,byteorder="big",signed=False)
  27.         readSize -=1
  28.     if (OP & PORT_1_WRITE):
  29.         CMD += data[1].to_bytes(1,byteorder="big",signed=False)
  30.         readSize -=1
  31.     if (OP & PORT_2_WRITE):
  32.         CMD += data[2].to_bytes(1,byteorder="big",signed=False)
  33.         readSize -=1
  34.     if (OP & PORT_3_WRITE):
  35.         CMD += data[3].to_bytes(1,byteorder="big",signed=False)
  36.         readSize -=1

  37.     serial_f.write(CMD)
  38.     readDatas = serial_f.read(readSize)
  39.     return list(readDatas)

  40. if __name__ == "__main__":
  41.     #打开串口
  42.     try:
  43.         myserial = serial.Serial()
  44.         myserial.port = "COM34"
  45.         myserial.baudrate = 9600
  46.         myserial.timeout = 5
  47.         myserial.parity = serial.PARITY_EVEN
  48.         myserial.open()
  49.         # time.sleep(1)
  50.     except Exception as e:
  51.         print("ERROR: ", e)
  52.         exit()

  53.     for i in range(256):
  54.         write = [i, 255-i, 0, 0]
  55.         GPIO_CTL(myserial, PORT_0 | PORT_1, PORT_0_WRITE | PORT_1_WRITE, write)
  56.         read = GPIO_CTL(myserial, PORT_1 , PORT_READ)
  57.         print('write',write,'read',read)
复制代码

单片机源程序如下:
  1. #include "REG52.h"
  2. #include <stdio.h>
  3. #include "SysTimer.h"
  4. #include "serial.h"
  5. #include "binary.h"
  6. #include "typedef.h"

  7. #define GPIO_P0 P0
  8. #define GPIO_P1 P1
  9. #define GPIO_P2 P2
  10. #define GPIO_P3 P3

  11. void main(void)
  12. {
  13.     uint8_t UART_data, cmd, rw, GPIO_Port,i;
  14.     //初始化滴答定时器
  15.     Timer0_Init();
  16.     //初始化串口
  17.     UART_Init();
  18.     // SCON = 0xD0; //1101,0000 9 位可变波特率,偶校验位, 串口1模式3
  19.     // printf("READY\n");
  20.     while (1) {
  21.         if (UART_stcRingBuf.u16UsedSize) {
  22.             RingBufRead(&UART_stcRingBuf, &cmd);
  23.             // bit 0: Port 0
  24.             // bit 1: Port 1
  25.             // bit 2: Port 2
  26.             // bit 3: Port 3
  27.             // bit 4: Port r/w
  28.             // bit 5: Port r/w
  29.             // bit 6: Port r/w
  30.             // bit 7: Port r/w
  31.             // rw = UART_data & B100;
  32.             // GPIO_Port = UART_data & B11;
  33.             //检查协议头
  34.                 // printf("raw:%d\trw:%d\tPort:%d\n",(int)UART_data,(int)rw,(int)GPIO_Port);
  35.             for (i=B0001;i<=B1000;i<<=1) {
  36.                 //扫描端口
  37.                 GPIO_Port = cmd & i;
  38.                 if (!GPIO_Port) continue;
  39.                 rw = (cmd & (i<<4));
  40.                 // printf("raw:%X\trw:%d\tPort:%d\n",(int)cmd,(int)rw,(int)GPIO_Port);
  41.                 if (rw>0) {
  42.                     //写
  43.                     while(RingBufRead(&UART_stcRingBuf, &UART_data));
  44.                     // printf("write:%X\n", (int)UART_data);
  45.                     switch(GPIO_Port) {
  46.                         case B0001: GPIO_P0 = UART_data; break;
  47.                         case B0010: GPIO_P1 = UART_data; break;
  48.                         case B0100: GPIO_P2 = UART_data; break;
  49.                         case B1000: GPIO_P3 = (UART_data & B11111100) | B11; break;
  50.                     }
  51.                 }else{
  52.                     //读
  53.                     // printf("read\n");
  54.                     switch(GPIO_Port) {
  55.                         case B0001: putchar(GPIO_P0); break;
  56.                         case B0010: putchar(GPIO_P1); break;
  57.                         case B0100: putchar(GPIO_P2); break;
  58.                         case B1000: putchar(GPIO_P3); break;
  59.                     }
  60.                 }
  61.             }
  62.         }
  63.     }
  64. }
复制代码


上图文件下载:
C51_UART_EIO.zip (24.26 KB, 下载次数: 15)

评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表