IO接口编程[通俗易懂]

IO接口编程[通俗易懂]IO接口编程作者:毛茏玮/Saint掘金:https://juejin.im/user/5aa1f89b6fb9a028bb18966a微博:https://weibo.com/5458277467/profile?topnav=1&wvr=6&is_all=1GitHub:github.com/saint-000CSDN:https://me.csdn.net/…

大家好,又见面了,我是你们的朋友全栈君。

在这里插入图片描述

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.在搭建好的工程文件下编写实验程序,实现对数码管的位选和段选的控制。实验截图如下:
在这里插入图片描述

实验代码如下:

#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);
	    }
	}
}

实验现象如下图:
在这里插入图片描述

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

#include "xparameters.h"
#include "xil_printf.h"
#include "sleep.h"
#include <stdio.h>
#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;
}

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143835.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 卡片式电脑介绍

    卡片式电脑介绍

    2021年11月13日
  • AD域控制器时间同步[通俗易懂]

    AD域控制器时间同步[通俗易懂]域控制器时间同步现象:域控制器和域内的计算机时间与internet上的时间不同步,老慢几分钟。解决办法:设置NTP服务器,和外网时间同步。下面是最近操作的时间同步方法修改主域控制器上同步Internet时间服务器:主域控制器修改运行gpedit.msc打开本地策略组,路径为:计算机配置-管理模板-系统-Windows时间服务:1.1配置WindowsNTP客户端…

    2022年5月17日
  • struts2 一个简洁的struts.xml

    struts2 一个简洁的struts.xml

    2021年12月8日
  • 数据库设计 Step by Step (8)——视图集成

    数据库设计 Step by Step (8)——视图集成

    2021年9月3日
  • 二、第一个java程序:HelloWorld

    二、第一个java程序:HelloWorld前面讲解了java程序的配置,现在要开始进入实例的编程了,第一个程序还是沿用经典的HelloWorld程序进行讲解。一、编程源代码     打开记事本,输入以下代码:publicclassHelloWorld{     //程序的主函数入门     publicstaticvoidmain(Stringargs[])

    2022年5月28日
  • 代理模式(proxy)

    前言 代理模式是一个大类,而且会经常用到,它包含了远程代理,虚拟代理,防火墙代理等,当然还有动态代理了,学过spring的人应该不陌生。 各种代理模式样式差别很大,不容易从程序上辨认,但是可以从功能上认出来,今天我就举个例子聊聊代理模式最基本的样子,从例子中认识代理模式。 举例为静态代理的基本应用,稍后再介绍代理模式的一些特点。  情境引入      本次我们以滴滴为例…

    2022年4月4日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号