一、实验题目:串口通信实验
二、实验目的
1、熟悉STM32的编程环境的使用;
2、掌握STM32的串口的编程;
三、实验内容
编写STM32 的串行通信程序,实现由串口调试助手输入任意字符串,STM接收后返回到串口调试助手输出。
四、实验步骤
1、建立工程,编写主要代码
2、时钟配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
3、GPIOA配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // USART1_TX (PA.9)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1_RX (PA.10)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
4、USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
USART_Cmd(USART1, ENABLE); //使能串口
5、串口中断初始化函数
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成{
if(USART_RX_STA&0x4000)//接收到了0x0d{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D{
if(Res==0x0d)USART_RX_STA|=0x4000;
else{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
}
}
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
7、在main函数编写
int main(void) {
u8 t;
u8 len;
delay_init(); //延时函数初始化
NVIC_Configuration(); // 设置中断优先级分组
uart_init(9600); //串口初始化为9600
LED_Init(); //初始化与LED连接的硬件接口
while(1) {
if(USART_RX_STA&0x8000) { //接收完毕
len=USART_RX_STA&0x3fff; //得到此次接收到的数据长度
printf("\r\n您发送的消息为:\r\n");
for(t=0;t<len;t++){
USART_SendData(USART1,USART_RX_BUF[t]); //发送一个字节的数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); } //等待发送结束
LED1=!LED1;
delay_ms(200);
LED1=!LED1;
printf("\r\n\r\n"); //插入换行
USART_RX_STA=0;
}
else{
printf("请输入数据,以空格键结束\r\n");
delay_ms(15000); }
}
}
五、实验结果
第二篇:ARM的串行口实验报告
ARM的串行口实验报告
班级: 电信091
学号: 200916022121
姓名:
指导教师: 陶福寿
日期: 20##年10月12日
目录
一、实验目的... 3
二、实验内容... 3
三、预备知识... 3
四、实验设备及工具... 3
五、实验原理及说明... 4
六、实验步骤... 4
七、思考题... 7
1.232串行通讯的数据格式是什么?... 7
2.串行通讯最少需要几根线,分别如何连接?... 8
3.ARM的串行口有几个,相应的寄存器是什么?... 8
4.用中断方式实现串口驱动。... 9
ARM的串行口实验
一、实验目的
1.掌握ARM的串行口工作原理。
2.学习编程实现ARM的UART通讯。
3.掌握CPU利用串口通讯的方法。
二、实验内容
学习串行通讯原理,了解串行通讯控制器,阅读ARM芯片文档,掌握ARM的UART相关寄存器的功能,熟悉ARM系统硬件的UART相关接口。编程实现ARM和计算机实现串行通讯:
ARM监视串行口,将接收到的字符再发送给串口(计算机与开发板是通过超级终端通讯的),即按PC键盘通过超级终端发送数据,开发板将接收到的数据再返送给PC,在超级终端上显示。
三、预备知识
1、用EWARM集成开发环境,编写和调试程序的基本过程。
2、ARM应用程序的框架结构。
3、了解串行总线
四、实验设备及工具
硬件:ARM嵌入式开发平台、PC机Pentium100以上、用于ARM920T的JTAG仿真器、串口线。
软件:PC机操作系统Win2000或WinXP、EWARM集成开发环境、仿真器驱动程序、超级终端通讯程序。
五、实验原理及说明
异步串行I/O
异步串行方式是将传输数据的每个字符一位接一位(例如先低位、后高位)地传送。数据的各不同位可以分时使用同一传输通道,因此串行I/O可以减少信号连线,最少用一对线即可进行。接收方对于同一根线上一连串的数字信号,首先要分割成位,再按位组成字符。为了恢复发送的信息,双方必须协调工作。在微型计算机中大量使用异步串行I/O方式,双方使用各自的时钟信号,而且允许时钟频率有一定误差,因此实现较容易。但是由于每个字符都要独立确定起始和结束(即每个字符都要重新同步),字符和字符间还可能有长度不定的空闲时间,因此效率较低。
六、实验步骤
1.编写串口驱动函数
2.在主函数中实现将从串口0接收到的数据发送到串口0(Main.c):
3. 启动H-JTAG 仿真器并进行初始化配置。
4. 启动EWARM新建工程,将“Exp1 ARM串口实验”中的文件添加到工程中并调试运行
七、思考题
1.232串行通讯的数据格式是什么?
答:开始前,线路处于空闲状态,送出连续“1”。传送开始时首先发一个“0”作为起始位,然后出现在通信线上的是字符的二进制编码数据。每个字符的数据位长可以约定为5 位、6 位、7 位或8 位,一般采用ASCII 编码。后面是奇偶校验位,根据约定,用奇偶校验位将所传字符中为“1”的位数凑成奇数个或偶数个。也可以约定不要奇偶校验,这样就取消奇偶校验位。最后是表示停止位的“1”信号,这个停止位可以约定持续1 位、1.5 位或2 位的时间宽度。至此一个字符传送完毕,线路又进入空闲,持续为“1”。经过一段随机的时间后,下一个字符开始传送才又发出起始位。每一个数据位的宽度等于传送波特率的倒数。微机异步串行通信中,常用的波特率为50,95,110,150,300,600,1200,2400,4800,9600 等。
接收方按约定的格式接收数据,并进行检查,可以查出以下三种错误:
1)奇偶错:在约定奇偶检查的情况下,接收到的字符奇偶状态和约定不符。
2)帧格式错:一个字符从起始位到停止位的总位数不对。
3)溢出错:若先接收的字符尚未被微机读取,后面的字符又传送过来,则产生溢出错。
每一种错误都会给出相应的出错信息,提示用户处理。
2.串行通讯最少需要几根线,分别如何连接?
答:TXD/RXD 是一对数据线,TXD 称发送数据输出,RXD 称接收数据输入。当两台微机以
全双工方式直接通信(无MODEM 方式)时,双方的这两根线应交叉联接(扭接)。
所有的信号都要通过信号地线构成耦合回路。通信线有以上三条(TXD、RXD 和信号地)就能工作了。其余信号主要用于双方设备通信过程中的联络(握手信号),而且有些信号仅用于和MODEM 的联络。若采取微型机对微型机直接通信,且双方可直接对异步串行通信电路芯片编程,若设置成不要任何联络信号,则其它线都可不接。有时在通信线的同一端将相关信号短接以“自握手”方式满足联络要求。
3.ARM的串行口有几个,相应的寄存器是什么?
答:ARM 自带三个UART 端口,每个UART 通道都有16 字节的FIFO(先入先出寄存器)用于接受和发送。用系统时钟最大波特率可达230.4K,如果用外部时钟(UCLK)UART 可以以更高的波特率运行。
UART线控制寄存器包括ULCON0,ULCON1和ULCON2,主要用来选择每帧数据位数、停止位数,奇偶校验模式及是否使用红外模式。
UART控制寄存器包括UCON0, UCON1 and UCON2,主要用来选择时钟,接收和发送中断类型(即电平还是脉冲触发类型),接收超时使能,接收错误状态中断使能,回环模式,发送接收模式等。
UART错误状态寄存器包括UERSTAT0, UERSTAT1 and UERSTAT2,此状态寄存器的相关位表明是否有帧错误或溢出错误发生。
UART 模块中有三个接收/发送状态寄存器,包括UTRSTAT0,UTRSTAT1 和UTRSTAT2。在UART 模块中有3 个UART 发送缓冲寄存器,包括UTXH0,UTXH1 和UTXH2,UTXHn 有8位发送数据。
在UART 模块中有3 个UART 接收缓冲寄存器,包括URXH0,URXH1 和URXH2,URXHn 有8位接收数据。
UART包括三个波特率因子寄存器UBRDIV0, UBRDIV1 and UBRDIV2,存储在波特率因子寄存器(UBRDIVn)中的值决定串口发送和接收的时钟数率(波特率)
4.用中断方式实现串口驱动。
答:/***************************************************************************\
Copyright (c) 20##-2007 threewater@up-tech.com, All rights reserved.
by threewter 2004.5.12
\***************************************************************************/
/***************************************************************************\
#说明: C main 函数,ucos-ii初始化等定义
---------------------------------- Bug --------------------------------------
---------------------------------- TODO list --------------------------------------
----------------------------------修正--------------------------------------
20##-5-12 创建
\***************************************************************************/
//#include"../ucos-ii/includes.h" /* uC/OS interface */
//#include "../ucos-ii/add/osaddition.h"
//#include "../inc/drivers.h"
//#include "../inc/sys/lib.h"
//#include "../src/gui/gui.h"
#define U8 unsigned char
#include <string.h>
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#pragma import(__use_no_semihosting_swi) // ensure no functions that use semihosting
#define rUTRSTAT0 (*(volatile unsigned *)0x50000010)
#define rUTRSTAT1 (*(volatile unsigned *)0x50004010)
#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)
#define WrUTXH1(ch) (*(volatile unsigned char *)0x50004020)=(unsigned char)(ch)
#define RdURXH0() (*(volatile unsigned char *)0x50000024)
#define RdURXH1() (*(volatile unsigned char *)0x50004024)
//void Uart_SendByten(int Uartnum, U8 data);
void Uart_SendByten(int,U8);
char Uart_Getchn(char* Revdata, int Uartnum, int timeout);
void ARMTargetInit(void);
void hudelay(int time);
int main(void)
{ //int ndev;
char c1[1];
char input1[1];
char input2[1];
char input3[1];
char err;
ARMTargetInit(); // do target (uHAL based ARM system) initialisation //
// err=Uart_Getchn(c1,0,0); //从串口采集数据
// Uart_SendByten(0,c1[0]); //显示采集的数据
while(1){
Uart_SendByten(0,0xa);//换行
Uart_SendByten(0,0xd);//回车
do{
err=Uart_Getchn(input1,0,0); //从串口采集数据
if(input1[0]=='a')
{
err=Uart_Getchn(input2,0,0); //从串口采集数据
if(input2[0]=='b')
{
err=Uart_Getchn(input3,0,0); //从串口采集数据
if(input3[0]=='c')
{Uart_SendByten(0,input1[0]);
Uart_SendByten(0,input2[0]);
Uart_SendByten(0,input3[0]);}
else continue;
}
else continue;
}
else continue;
Uart_SendByten(0,0xa);//换行
Uart_SendByten(0,0xd);//回车
}while(1);
err=Uart_Getchn(c1,0,0); //从串口采集数据
Uart_SendByten(0,c1[0]); //显示采集的数据
}
}
void Uart_SendByten(int Uartnum, U8 data)//ok eric rong
{ //int i;
if(Uartnum==0)
{
while(!(rUTRSTAT0 & 0x4)); //Wait until THR is empty.
hudelay(10);
WrUTXH0(data);
}
else
{
while(!(rUTRSTAT1 & 0x4)); //Wait until THR is empty.
hudelay(10);
WrUTXH1(data);
}
}
char Uart_Getchn(char* Revdata, int Uartnum, int timeout)
{
if(Uartnum==0){
while(!(rUTRSTAT0 & 0x1)); //Receive data read
*Revdata=RdURXH0();
return TRUE;
}
else{
while(!(rUTRSTAT1 & 0x1));//Receive data read
*Revdata=RdURXH1();
return TRUE;
}
}
程序中划线部分使我们的程序。保证的了只有在连续输入abc,时,超级终端上才产生输出abc。