嵌入式实验四:串口传输实验

  • 格式:docx
  • 大小:697.42 KB
  • 文档页数:37

实 验 报 告 课程名称 嵌入式系统设计 实验仪器 清华同方辰源嵌入式系统实验箱 实验名称 实验四:串口传输实验

系 别 计算机学院 专 业 计算机科学与技术 班级/学号 学生姓名 实验日期 成 绩 指导教师 实验四:串口传输实验 一、实验问题回答 (1)本实验引入了Send和Receive两个变量表示上传或下传数据,用状态机怎么实现? 答:switch(oledkey[0])

{ case 'F': state=1; //Receive = 1; //Send = 0; break; case 'E': state=2; //Send = 1; //Receive = 0; break; switch(state) { case 0: break; case 1: recive(); break; case 2: send(); break;

(2)了解串口通讯原理。 答:串口按位(bit)发送和接收字节,串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。 1、51系列单片机的串口有4个模式,可分别用作串并转换、并串转换、异步串行通信(2种模式)。异步串行通信中,有1+8+1和1+8+1+1两种帧格式,多机通信是特殊的通信方式。 2、基本原理是两组移位寄存器。将并行通信转换成串行通信模式(发送部分),或反之(接收部分)。可全双工运行。 3、速度通过移位脉冲决定。具体一般通过定时器1的自动装载模式产生的溢出脉冲给出。 4、电平上采用的是CMOS逻辑。 5、以上是物理层和数据链路层的单片机串口模块的约定,其他层需要软件人员根据需要自行把握。另外,电平需要根据实际通信环境做变换,如232、485或红外等。

(3)了解在上位机(PC端)端,C程序中如何调用串口?

答:#include

#include HANDLE hCom; int main(void) { hCom=CreateFile(TEXT("COM3"),//COM1口 GENERIC_READ|GENERIC_WRITE, //允许读和写 0, //独占方式 NULL, OPEN_EXISTING, //打开而不是创建 0, //同步方式 NULL); if(hCom==(HANDLE)-1) { printf("打开COM失败!\n"); return FALSE; } else { printf("COM打开成功!\n"); } SetupComm(hCom,1024,1024); //输入缓冲区和输出缓冲区的大小都是1024 COMMTIMEOUTS TimeOuts; //设定读超时 TimeOuts.ReadIntervalTimeout=1000; TimeOuts.ReadTotalTimeoutMultiplier=500; TimeOuts.ReadTotalTimeoutConstant=5000; //设定写超时 TimeOuts.WriteTotalTimeoutMultiplier=500; TimeOuts.WriteTotalTimeoutConstant=2000; SetCommTimeouts(hCom,&TimeOuts); //设置超时 DCB dcb; GetCommState(hCom,&dcb); dcb.BaudRate=9600; //波特率为9600 dcb.ByteSize=8; //每个字节有8位 dcb.Parity=NOPARITY; //无奇偶校验位 dcb.StopBits=ONE5STOPBITS; //两个停止位 SetCommState(hCom,&dcb); DWORD wCount;//读取的字节数 BOOL bReadStat; while(1) { PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR); //清空缓冲区 char str[9]={0}; printf("%s\n",str); bReadStat=ReadFile(hCom,str,9,&wCount,NULL); if(!bReadStat) { printf("读串口失败!"); return FALSE; } else { str[8]='\0'; printf("%s\n",str); } Sleep(100); } }

(4)了解在上位机(PC端)端,JAVA程序中如何调用串口? 答:public static void process() {

try { Enumeration portList = CommPortIdentifier.getPortIdentifiers(); while (portList.hasMoreElements()) { CommPortIdentifier portId = (CommPortIdentifier) portList.nextElement(); if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)//如果端口类型是串口则判断名称 { if(portId.getName().equals("COM1")){//如果是COM1端口则退出循环 break; }else{ portId=null; } } } SerialPort serialPort = (SerialPort)portId.open("Serial_Communication", 1000);//打开串口的超时时间为1000ms

serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);//设置串口速率为9600,数据位8位,停止位1们,奇偶校验无 InputStream in = serialPort.getInputStream();//得到输入流 OutputStream out = serialPort.getOutputStream();//得到输出流

//进行输入输出操作 //操作结束后 in.close(); out.close(); serialPort.close();//关闭串口

} catch (PortInUseException e) { e.printStackTrace(); } catch (UnsupportedCommOperationException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }

} 二、实验目的和效果

实验目的: (1)学习、理解、掌握利用串口实现上位机和下位机之间的通讯(数据上传和控制)。 达到实验要求,拓展二未实现。 实验效果: 三、实验内容和步骤 实验内容: (1)默认在在OLED屏幕上分行显示串口号、波特率、数据位、校验位、停止位、“E”键发送模式、“F”键接收模式。 思路:E键发送模式设置send=1 receive=0 F键接受模式设置 send=0 receive=1 (2)按下小键盘的“E”键,表示下位机(实验箱)往上位机(PC)

发送数据,上位机开启“超级终端”,下位机循环往上位机发送“0”“1”“2”。。。“9”字符,上位机在“超级终端”中可以看到。 思路:定义一个全局变量字符数组,char rxchar[2];

GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0,GPIO_PIN_0); SysCtlDelay(2000000); UARTSend((unsigned char *)&rxchar, 1); SysCtlDelay(2000000); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0,0);

rxchar[0]值不断由0x30-0x39之间进行变化。 if((rxchar[0] >= 0x39) || (rxchar[0] < 0x30)) rxchar[0] = 0x30; else rxchar[0]++;

(3)按下小键盘的“F”键,表示上位机(PC)往下位机(实验箱)发送数据,上位机开启“超级终端”,输入“A”、“B”、“C”、“D”等,下位机接受数据,和小键盘输入一样进行相应显示。 思路:if(UARTCharsAvail(UART0_BASE))

{ rxchar[0] = UARTCharGet(UART0_BASE); // 等待接收字符 rxchar[1] = '\0'; GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0,GPIO_PIN_0); RIT128x96x4StringDraw("Receive: ", 12,80, 15); RIT128x96x4StringDraw(rxchar, 66,80,15); RIT128x96x4StringDraw(" ", 72,80,15); SysCtlDelay(1000000); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0,0); }

(4)扩展:按照状态机模式修改程序。 思路:根据按键的不同判断状态,三种状态,空闲,接收,发送。根据状态的不同调用相应的方法。