IO接口编程

IO接口编程_第1张图片

IO接口编程

作者:毛茏玮 / Saint
掘金:https://juejin.im/user/5aa1f89b6fb9a028bb18966a
微博:https://weibo.com/5458277467/profile?topnav=1&wvr=6&is_all=1
GitHub:github.com/saint-000
CSDN: https://me.csdn.net/qq_40531974

一、实验目的
1.掌握ARM的GPIO,UART接口工作原理。
2.学习编程实现GPIO接口的控制及ARM和PC机的UART通信。
3.掌握ARM裸机下C语言编程方法。

二、实验内容
1.学习串行通信原理,了解串行通信控制寄存器。
2.实现I/O接口编程。

三、实验步骤
1.数码管实验

1.双击打开对应工程文件夹下的vivado project file
2.在File菜单下选择Export,点击包括比特流,点击OK
3.在File菜单下选择luanch SDK,打开SDK软件
4.新建工程并命名,类型选择Empty Application
5.在新建的工程中添加源文件,新建Source File
6.为文件命名,注意要跟上文件类型.c,点击Finish
7.补全seg_test.c文件中缺失的代码,添加至源文件中:需完成的功能:
使用开关控制右四位数码管显示数字0~9,当值大于9时,数码管无显示
其中开关从右至左为低位至高位,开关开状态为1,关状态为0,开关组成的2进制值对 应数码管上显示的十进制数值
8.点击保存,软件自动编译程序
9.用USB数据线将开发板2处接口与电脑主机连接,打开板子电源开关7,开发板1处拨码开关全部打到”on”
10.在vivado中点击左下角Open Hardware Manager,选择open target, 再选择Auto Connection
11.点击Program device,在弹出的窗口中找到工程的比特流,比特流文件在工程中的路径为:project_name/project_name.runs/impl_1/system_wrapper.bit,如下图,点击Program下载比特流到板子
12.运行程序
13.拨动开关,观察数码管上的显示
14.可使用debug调试程序,具体参见实验二

2.UART串口实验

1.双击打开对应工程文件夹下的vivado project file
2.在File菜单下选择Export,点击包括比特流,点击OK
3.在File菜单下选择luanch SDK,打开SDK软件
4.新建工程并命名,类型选择Empty Application
5.在新建的工程中添加源文件,新建Source File
6.为文件命名,注意要跟上文件类型.c,点击Finish
7.补全common_uart.c文件中缺失的代码,添加至源文件中,需完成的功能:
通过PL上的UART串口发送单个字符,接收后向串口回传该字符,若收到的字符为“x”,则退出程序
8.点击保存,软件会自动编译程序
9.用USB数据线将开发板2处UART接口与电脑主机连接,将5上方的USB口用双头USB线连接至主机,打开板子电源开关7
10.在vivado中点击左下角Open Hardware Manager,选择open target, 再选择Auto Connection
11.点击Program device,在弹出的窗口中找到工程的比特流,比特流文件在工程中的路径为:project_name/project_name.runs/impl_1/system_wrapper.bit,如下图,点击Program下载比特流到板子
12.计算机→管理,在设备管理器→端口里查看Silicon Labs CP210x USB to UART Bridge对应的端口号
13.打开串口调试助手,将串口设置为该端口号,将波特率设为9600,其余配置不改变,然后打开串口
14.运行程序
15.在串口助手里,输入字符,点击TX发送,在左上方的框里看是否有接受到正确的字符

四、实验结果
实验1.在搭建好的工程文件下编写实验程序,实现对数码管的位选和段选的控制。实验截图如下:
IO接口编程_第2张图片

实验代码如下:

#include"xparameters.h"
#include"xgpio.h"
#include"xil_cache.h"

//设备ID
#define GPIO_SEG_W_DEVICE_ID 1
#define GPIO_SW_DEVICE_ID 2
#define GPIO_SEG_D_DEVICE_ID 0
//通道号
#define SEG_CHANNEL 1

//指向设备的指针
XGpio GpioOutput0; //位选对应寄存器
XGpio GpioOutput1; //段选对应寄存器
XGpio GpioInput;//按键对应寄存器

u32 flag=0;
u32 DataRead;

int Gpio_w_seg(u16 Deviceid)
{
	int w;
	int status;
	/*请补全代码,给w赋值*/
	w=15;
	
	status=XGpio_Initialize(&GpioOutput0,Deviceid);
		if(status !=XST_SUCCESS)
		{
			return XST_FAILURE;
		}
	XGpio_SetDataDirection(&GpioOutput0,SEG_CHANNEL,0x0);
    	XGpio_DiscreteWrite(&GpioOutput0,SEG_CHANNEL,w);

	return XST_SUCCESS;
}

int Gpio_d_seg(u16 Deviceid,u32 data)
{

	u32 a;
	int status;
	status=XGpio_Initialize(&GpioOutput1,Deviceid);
		if(status !=XST_SUCCESS)
		{
			return XST_FAILURE;
		}
	/*设置GPIO为输出*/
	XGpio_SetDataDirection(&GpioOutput1,SEG_CHANNEL,0x0);
	
	switch(data)
	{
	    case 0 :a=0x3f;
	            break;
		/*补全余下代码,定义data为1~9时对应的数码管值*/
		case 1 :a=0x06;
				break;
		case 2 :a=0x5b;
				break;
		case 3 :a=0x4f;
				break;
		case 4 :a=0x66;
				break;
		case 5 :a=0x6d;
				break;
		case 6 :a=0x7d;
				break;
		case 7 :a=0x07;
				break;
		case 8 :a=0x7f;
				break;
		case 9 :a=0x6f;
				break;
	}
    /*向数码管寄存器中写入值*/
	XGpio_DiscreteWrite(&GpioOutput1,SEG_CHANNEL,a);
	
	return XST_SUCCESS;
}

u32 Gpio_sw(u16 Deviceid,u32 *DataRead)
{
	int Status;
    Status = XGpio_Initialize(&GpioInput, Deviceid);
	if (Status != XST_SUCCESS)
	{
		return XST_FAILURE;
	}
	/*补全代码,读取并返回按键的值*/
	return XGpio_DiscreteRead(&GpioInput, SEG_CHANNEL);
}

void main()
{
	while(1)
	{
		flag =Gpio_sw(GPIO_SW_DEVICE_ID,&DataRead);
		Gpio_w_seg(GPIO_SEG_W_DEVICE_ID);
	    if(flag < 10)
	    {
		     Gpio_d_seg(GPIO_SEG_D_DEVICE_ID,flag);

	   }
	   else
	   {
		   /*补全代码,使数码管不显示*/
			XGpio_Initialize(&GpioOutput0,GPIO_SEG_D_DEVICE_ID);
			XGpio_SetDataDirection(&GpioOutput1,SEG_CHANNEL,0x0);
			XGpio_DiscreteWrite(&GpioOutput1,SEG_CHANNEL,0x0000);
	    }
	}
}

实验现象如下图:
IO接口编程_第3张图片

实验2. ARM C语言实现串口通信实验。实验代码如下:

#include "xparameters.h"
#include "xil_printf.h"
#include "sleep.h"
#include 
#include "xil_io.h"

#define uart_bas_addr  0x42c00000
#define uart_rxd_addr  0x42c00000//接收数据输入地址
#define uart_txd_addr  0x42c00004//发送数据输出地址
#define uart_stat_addr 0x42c00008 // 串口状态寄存器
#define uart_ctrl_addr 0x42c0000c

int main()
{
	while(1)
    {	 /*补全代码,接收字符并回传,当接收到字符x时退出程序*/						
	static int a;
	if((Xil_In8(uart_stst_addr))&0x01==1)//判断串口状态寄存器的最低位是否为1
{
	a=Xil_In8(uart_txd_addr, a);//若为1,接收串口数据,并赋给一个变量
	if(a=='x')//将接收到的数据回传
        {
	    break;//判断接收到的数据是否位‘x’,若是,跳出while循环
        }
}																	                          

     }
    return 0;
}

实验截图如下:
IO接口编程_第4张图片
五、实验总结
1.知道八段数码管由“位选”和“段选”两块电路驱动以及引脚约束条件。
2.理解了接口函数的用法。
3.用串口助手修改波特率,连接开发板的UART进行匹配打印返回值

实验心得:
(1)串口通信的实验明显要比之前的实验要难了,代码的数量明显变多了 。头文件里有很多的代码,比之前的实验的代码要多的多。
但是只要认真的去看代码,使用编译器自带的查找功能找到关键的函数,很容就看懂代码本身的意思。
(2)串口通信的概念,即串口按位(bit)发送和接收字节。通过这次实验,我掌握了串口的使用方法,串口初始化,发送数据和接收数据,为以后的实验奠定了基础。通过有关书籍,我了解到嵌入式系统中串口是一个重要的资源,常用来做输入输出设备。
(3)UART(通用异步收发器)结构包括波特率发生器,发送器,接收器以及控制单元;
有同时代表收发缓冲区状态的只读UTRSTAT寄存器,和其他收发数据,设计相应收发模式查询方式的寄存器;
实验过程就是对发送数据格式,端口,寄存器等初始化,接收数据(接收缓冲区接收到数据),发送数据(发送缓冲区为空)的处理。

六、实验思考题
(1)查看相关寄存器,思考怎么配置UART时钟信号?
改变ulcon的值可以配置UART配置寄存器。我们实验室用的芯片xc7z020clg484-1,所以我们查看xc7z020的数据手册,查看CLOCK&POWER MANAGEMENT和UART模块相关配置时钟信号的寄存器来确定时钟信号。

(2) 要实现控制数码管闪烁的功能,有什么办法可以完成?
可以向命令寄存器写入闪烁控制命令,也可以通过向命令寄存器中写入“下载数据并译码(Download)"命令来完成,因为该命令的底八位的D6位可以控制数码管的闪烁。

你可能感兴趣的:(ARM)