C基础与SDK调试方法

REVIEW

上次学习了一下软件使用流程zynq PS点灯-CSDN博客

本次学习一下C编程基础与调试方法

 1.  硬件编程原理

小梅哥视频链接:

07_Xilinx嵌入式裸机硬件编程原理_哔哩哔哩_bilibili

对应的课程笔记:【zynq课程笔记】【裸机】【第7课 】【硬件编程原理】 - ACZ702开发板 - 芯路恒电子技术论坛 - Powered by Discuz! (corecourse.cn)

①典型GPIO结构

R1:方向/输出使能控制寄存器
R2:输出状态/数据寄存器
R3:输入状态/数据寄存器

②Zynq7000 GPIO结构

zynq PS端 GPIO-CSDN博客

GPIO控制的编程思路

初始化
根据GPIO对应位的工作场景,设置其方向、中断屏蔽位、中断检测类型。
工作
输入:若开启了中断,则编写中断处理函数;

           若不开启中断,则在需要的时候直接读取输入寄存器的值。
输出:则通过写数据寄存器或输出置位/清零寄存器来修改该位的输出值。

2.  寄存器操作

小梅哥视频:06_Zynq SoC嵌入式逻辑C编程基础_哔哩哔哩_bilibili

课程笔记:【zynq课程笔记】【裸机】【第6课 】【C编程基础】 - ACZ702开发板 - 芯路恒电子技术论坛 - Powered by Discuz! (corecourse.cn)

cpu编程,本质上就是对指定地址进行读写操作

视频课程用到的代码:实现让开发板上的PS_LED0亮灭

        端口为MIO7

场景分析:该场景下只需要简单的控制GPIO的对应位输出高低电平即可,用不到中断功能。
初始化
关闭中断
INT_DIS/ INT_EN:
这是一组作用于同一个功能的2个独立的寄存器,一个负责使能GPIO的每一位的中断,另一个负责禁止GPIO的每一位的中断。
本应用中,对应GPIO无需开启中断,所以设计时针对INT_DIS/ INT_EN寄存器,需要明确:
关闭某位中断该操作哪个寄存器,往该寄存器写0关闭中断,还是写1关闭中断。
根据UG585中的描述,对INT_DIS寄存器的对应位写1就可以禁止该位对应的IO产生中断。所以本例中初始化时,理论上需要对INT_DIS寄存器进行操作。设置MIO7对应的中断控制位不打开。
Data = (1<<7);
Xil_Out32(XPAR_PS7_GPIO_0_BASEADDR + XGPIOPS_INTDIS_OFFSET, Data);

#include "stdio.h"
#include "xparameters.h"
#include "xil_io.h"
#include "xgpiops.h"
#include "sleep.h"

int main(void)
{

        u32 reg_val = 0;
        u32 Data = 0;

                //设置方向和输出使能
                //OUTEN、DIRM寄存器

        //设置IO方向,bit7的方向为输出
        reg_val = Xil_In32(XPAR_PS7_GPIO_0_BASEADDR + XGPIOPS_DIRM_OFFSET);
        Data = reg_val | (1<<7);
        Xil_Out32(XPAR_PS7_GPIO_0_BASEADDR + XGPIOPS_DIRM_OFFSET ,  Data);

        //设置输出使能,bit7输出使能
        reg_val = Xil_In32(XPAR_PS7_GPIO_0_BASEADDR + XGPIOPS_OUTEN_OFFSET);
        Data = reg_val | (1<<7);
        Xil_Out32(XPAR_PS7_GPIO_0_BASEADDR + XGPIOPS_OUTEN_OFFSET, Data);

                 //设置方向和输出使能
                //OUTEN、DIRM寄存器

        由于是点亮LED,属于输出型GPIO,因此,根据GPIO的结构图知道,需要使output enable信号为高电平,以使能IO Pin上的三态缓冲器输出。

        而output enable为1的条件则是OUTENDIRM两个寄存器对应的位都为1
        由于这两个寄存器均是32位同时写入型,所以为了不干扰寄存器中其他位的值,

需要采用read-modify-write的操作顺序,也就是先读出,再修改,最后再写回。

        while(1)
        {

                //MASK_DATA寄存器
            //设置bit7输出1
            Data = ((~(1<<7)) << 16) | (1<<7);
            Xil_Out32(XPAR_PS7_GPIO_0_BASEADDR + XGPIOPS_DATA_LSW_OFFSET,  Data);
            usleep(1000000);//延时1000000us

            //设置bit7输出0
            Data = ((~(1<<7)) << 16) & (~(1<<7));
            Xil_Out32(XPAR_PS7_GPIO_0_BASEADDR + XGPIOPS_DATA_LSW_OFFSET,  Data);
            sleep(1);//延时1000000us
        }
        
        
        return 0;
}

                  //MASK_DATA寄存器

        写MASK_DATA寄存器时需要注意,对于每一个GPIO Bank,由MASK_DATA_LSWMASK_DATA_MSW两个寄存器组成,其中MASK_DATA_LSW控制该组GPIO中低16位的状态,MASK_DATA_MSW控制该组GPIO中高16位的状态。
        MASK_DATA的高16位中,哪些位为0,这些位对应的数据寄存器的值才允许被更新,更新的值由MASK_DATA寄存器的低16位来指定。

① bsp(board  support package)板级支持包

        用户编程时,可以使用该支持包中提供的驱动和函数,来避免自己编写应用函数和基于寄存器读写的驱动。

        由于这些驱动程序中加了很多安全判断和兼容操作,所以,在对程序尺寸和运行效率要求不高的场合,推荐使用BSP提供的驱动和函数,而在对性能和程序尺寸有要求的场合,推荐自己编写基于寄存器读写的驱动。

        //对与本摸鱼怪来说,这一点后面需要的话,再肥来恶补知识叭~

② 如何实现对指定地址的读写操作

使用指针

例如对地址为0x00000020的寄存器进行读写,就可以使用下面的形式:

        读寄存器:return (volatile u8 ) 0x00000020;

        写寄存器:(volatile u8 ) 0x00000020 = 0x12;

使用IO读写函数   xil_io.h

Xil_In8(addr);

Xil_In16(addr);

Xil_In32(addr);

Xil_In64(addr);

Xil_Out8 (addr, data);

Xil_Out16(addr, data);

Xil_Out32(addr, data);

Xil_Out64(addr, data);

这些函数就是对指针操作的封装

③ 如何知道各个外设的硬件信息(寄存器地址,位功能)

查看datasheet

在UG585的附录B中,有所有外设的每个寄存器的地址和功能描述。

reg_val = Xil_In32(XPAR_PS7_GPIO_0_BASEADDR + XGPIOPS_DIRM_OFFSET);

XPAR_PS7_GPIO_0_BASEADDR 为基地址

XGPIOPS_DIRM_OFFSET  为偏移地址

使用BSP提供的驱动和硬件信息文件

在bsp工程中,Xilinx为每一个硬件功能都提供了描述其寄存器地址和位功能的.h文件:

这类文件字母x开头,然后紧跟外设功能名,最后以_hw结尾。

例如,对于GPIO,提供的该文件名为xgpiops_hw.h,

          对于串口(uart),提供的该文件名为xuartps_hw.h,

          对于SD/MMC外设控制器,提供的该文件名为xsdps_hw.h。

需要注意的是,SDK在生成BSP时,会仅针对系统中配置使能了的硬件生成硬件信息文件,对于没有配置使能的硬件,则可能不会生成硬件信息文件,例如我们开发流程课程中,因为没有使能SD/MMC外设和UART外设,所以在SDK中生成的LED_bsp下就找不到刚刚说的xsdps_hw.h和xuartps_hw.h。

④如何实现程序中的延时

对精度要求较高的延时,可以使用BSP中提供的基于CPU心跳定时器的定时/延时函数,例如

微秒单位延迟usleep(unsigned long useconds)

秒单位延迟sleep(unsigned int seconds)

⑤使用跨平台可移植的数据类型

include “stdint.h”

uint8_t us8_type;

uint16_t us16_type;

uint32_t us32_type;

uint64_t us64_type;

int8_t s8_type;

int16_t s16_type;

int32_t s32_type;

int64_t s64_type;

3.  使用硬件库进行编程

小梅哥视频链接:

08_基于SDK硬件驱动库的编程方法_哔哩哔哩_bilibili

对应的课程笔记:【zynq课程笔记】【裸机】【第8课 】【使用SDK硬件驱动库】 - ACZ702开发板 - 芯路恒电子技术论坛 - Powered by Discuz! (corecourse.cn)

#include "xgpiops.h"

#include "unistd.h"


XGpioPs Gpio;

XGpioPs_Config *ConfigPtr;


int main(void)

{

    ConfigPtr =  XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);

    XGpioPs_CfgInitialize(&Gpio,  ConfigPtr, ConfigPtr->BaseAddr);


    XGpioPs_SetDirectionPin(&Gpio,  7, 1);

    XGpioPs_SetOutputEnablePin(&Gpio,  7, 1);


    while(1)

    {

       //设置bit7输出1

       XGpioPs_WritePin(&Gpio,  7, 0x1);

       usleep(500000);


       //设置bit7输出0

       XGpioPs_WritePin(&Gpio,  7, 0x0);

       usleep(500000);

    }

    return 0;

}

XGpioPs_LookupConfig

  

寻找指定GPIO设备的配置信息

XGpioPs_CfgInitialize

对GPIO的驱动程序进行初始化

XGpioPs_SetDirectionPin

设置指定Pin的方向

XGpioPs_SetOutputEnablePin

设置指定Pin的输出使能

XGpioPs_WritePin

写/更新指定管脚的值/状态

4.调试

小梅哥视频:

09_Zynq SoC ARM裸机程序调试方法_哔哩哔哩_bilibili

对应课程笔记:【zynq课程笔记】【裸机】【第9课 】【裸机程序调试方法】 - ACZ702开发板 - 芯路恒电子技术论坛 - Powered by Discuz! (corecourse.cn)

5.  小作业

①GPIO_MIO  PS按键控制PS_LED闪烁

#include "COMMON.h"
#include "sleep.h"

int main(void)
{
    u8 State_PS_KEY; //存放按键(MIO7)的电平状态,0 为低电平,1 为高电平
    PS_GPIO_Init(); //初始化 PS 端 MIO 和 EMIO

    //设置 PS_LED(MIO7)为输出并且初始为低电平
    PS_GPIO_SetMode(PS_LED, OUTPUT, 0);
    PS_GPIO_SetMode(PS_KEY, INPUT, 0); //设置 PS_KEY(MIO47)方向为输入

    while(1)
    {

        //读取 PS_KEY 的电平值并存储到 State_PS_KEY 变量里
      //  State_PS_KEY = PS_GPIO_GetPort(PS_KEY);

        while(!PS_GPIO_GetPort(PS_KEY))
        {

        //将 State 变量的值取非赋予 PS_LED 来输出
        PS_GPIO_SetPort(PS_LED,1);
        usleep(500000);
        PS_GPIO_SetPort(PS_LED,0);
        usleep(500000);
        }
        PS_GPIO_SetPort(PS_LED,0);
    }
    return 0;
}

 while(!PS_GPIO_GetPort(PS_KEY))

嘎嘎~这个是调试出来的小问题:

    while(State_PS_KEY )
        {

        //将 State 变量的值取非赋予 PS_LED 来输出
        PS_GPIO_SetPort(PS_LED,1);
        usleep(500000);
        PS_GPIO_SetPort(PS_LED,0);
        usleep(500000);

          State_PS_KEY = PS_GPIO_GetPort(PS_KEY);
        }

这个小问题,自己调试一下就可以发现啦~

好久没写C,还是要好好熟练一下~

或者是:

#include "xgpiops.h"
#include "unistd.h"

XGpioPs Gpio;
XGpioPs_Config *ConfigPtr;

int main(void)
{
    ConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
    XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);

    //设置MIO7为输出
    XGpioPs_SetDirectionPin(&Gpio, 7, 1);
    XGpioPs_SetOutputEnablePin(&Gpio, 7, 1);

    //设置MIO47为输入
    XGpioPs_SetDirectionPin(&Gpio, 47, 0);
    XGpioPs_SetOutputEnablePin(&Gpio, 47, 0);

    while(1)
    {
        while(!XGpioPs_ReadPin(&Gpio, 47))
        {
            //设置bit7输出1
            XGpioPs_WritePin(&Gpio, 7, 0x1);
            usleep(500000);

            //设置bit7输出0
            XGpioPs_WritePin(&Gpio, 7, 0x0);
            usleep(500000);
        }

        //设置bit7输出0
        XGpioPs_WritePin(&Gpio, 7, 0x0);
    }

    return 0;
}
 

②GPIO_EMIO  PL按键控制PS_LED、PL_LED交替闪烁

#include "xgpiops.h"
#include "unistd.h"

XGpioPs Gpio;
XGpioPs_Config *ConfigPtr;

int main(void)
{

    ConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
    XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);


    /*设置MIO7为输出*/
    XGpioPs_SetDirectionPin(&Gpio,  7, 1);
    XGpioPs_SetOutputEnablePin(&Gpio,  7, 1);


    /*设置EMIO0为输出,MIO有54个,EMIO0=54+0=54*/
    XGpioPs_SetDirectionPin(&Gpio, 54, 1);
    XGpioPs_SetOutputEnablePin(&Gpio, 54, 1);

    /*设置EMIO1为输入*/
    XGpioPs_SetDirectionPin(&Gpio, 55, 0);
    XGpioPs_SetOutputEnablePin(&Gpio, 55, 0);

    while(1)
    {
        while(!XGpioPs_ReadPin(&Gpio, 55))
        {
            //设置bit54输出1
            XGpioPs_WritePin(&Gpio, 54, 0x1);
            XGpioPs_WritePin(&Gpio, 7, 0x0);
            usleep(500000);

            //设置bit54输出0
            XGpioPs_WritePin(&Gpio, 54, 0x0);
            XGpioPs_WritePin(&Gpio, 7, 0x1);
            usleep(500000);
        }

        //设置bit54输出0
        XGpioPs_WritePin(&Gpio, 54, 0x0);
        XGpioPs_WritePin(&Gpio, 7, 0x0);
    }

    return 0;
}
 

//啦啦啦,摸鱼结束~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/693148.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

eNSP学习——配置RIP路由附加度量值

目录 主要命令 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本配置 2、搭建RIP网络 3、配置RIP Metricin 4、配置RIP Metricout 需要eNSP各种配置命令的点击链接自取&#xff1a;华为&#xff45;NSP各种设备配置命令大全PDF版_ensp配置命令大全资…

Vyper重入漏洞解析

什么是重入攻击 Reentrancy攻击是以太坊智能合约中最具破坏性的攻击之一。当一个函数对另一个不可信合约进行外部调用时&#xff0c;就会发生重入攻击。然后&#xff0c;不可信合约会递归调用原始函数&#xff0c;试图耗尽资金。 当合约在发送资金之前未能更新其状态时&#…

计算机网络-数制转换与子网划分

目录 一、了解数制 1、计算机的数制 2、二进制 3、八进制 4、十进制 5、十六进制 二、数制转换 1、二进制转十进制 2、八进制转十进制 3、十六进制转十进制 4、十进制转二进制 5、十进制转八进制 6、十进制转十六进制 三、子网划分 1、IP地址定义 2、IP的两种协…

Linux之进程信号详解【上】

&#x1f30e; Linux信号详解 文章目录&#xff1a; Linux信号详解 信号入门 技术应用角度的信号 信号及信号的产生       信号的概念       信号的处理方式 信号的产生方式         键盘产生信号         系统调用产生信号         软件…

Nvidia/算能 +FPGA+AI大算力边缘计算盒子:隧道和矿井绘图设备

RockMass 正在努力打入采矿业和隧道工程利基市场。 这家位于多伦多的初创公司正在利用 NVIDIA AI 开发一款绘图平台&#xff0c;帮助工程师评估矿井和施工中的隧道稳定性。 目前&#xff0c;作为安全预防措施&#xff0c;地质学家和工程师会站在离岩石五米远的地方&#xff0…

Llama模型家族之Stanford NLP ReFT源代码探索 (二)Intervention Layers层

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…

【Java 百“练”成钢】Java 基础:类和对象

Java 基础&#xff1a;类和对象 01.打印信息02.打印类的简单名称03.打印类的 ClassLoader04.获取类的方法05.获取类的Package06.创建一个对象数组07.计算圆的面积08.计算圆的周长09.创建具有私有访问修饰符的成员10.创建带访问修饰符的成员11.将对象作为参数传递12.通过类对象获…

开源多平台AI音乐生成器本地安装结合cpolar内网穿透实现远程访问

文章目录 前言1. 本地部署2. 使用方法介绍3. 内网穿透工具下载安装4. 配置公网地址5. 配置固定公网地址 前言 本文主要介绍如何在Windows系统电脑上快速本地部署一个文字生成音乐的AI创作工具MusicGPT&#xff0c;并结合cpolar内网穿透工具实现随时随地远程访问使用。 MusicG…

Linux 35.5 + JetPack v5.1.3@ ego-planner编译安装

Linux 35.5 JetPack v5.1.3 ego-planner编译安装 1. 源由2. 编译&安装Step 1&#xff1a;依赖库安装Step 2&#xff1a;建立工程Step 3&#xff1a;编译工程Step 4&#xff1a;安装工程 3. 问题汇总3.1 planner/plan_env - OpenCV3.2 uav_simulator/local_sensing - CUDA优…

基于非下采样小波包分析的滚动轴承故障诊断(MATLAB R2021B)

小波变换具有良好的时频局部化特性和多分辨率特性&#xff0c;可准确定位信号的突变点并可在不同尺度上描述信号的局部细节特征&#xff0c;被广泛应用于信号降噪。但标准正交小波变换不具有平移不变性&#xff0c;采用标准正交小波对信号消噪后&#xff0c;会在脉冲尖峰处产生…

进口电动防爆调节阀的性能-美国品牌

进口电动防爆调节阀以其卓越的防爆性能、安全可靠、精确控制以及广泛的技术规格和应用场合&#xff0c;成为工业领域中不可或缺的重要设备。 进口电动防爆调节阀的性能可以归纳如下&#xff1a; 一、防爆性能 防爆设计&#xff1a;进口电动防爆调节阀采用专门的防爆设计和制…

使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理

教程简述 在本教程中&#xff0c;您将学习在阿里云交互式建模平台PAI-DSW x Free Prompt Editing&#xff08;CVPR2024中选论文算法&#xff09;图像编辑算法&#xff0c;开发个人AIGC绘图小助理&#xff0c;实现文本驱动的图像编辑功能单卡即可完成AIGC图片风格变化、背景变化…

5. 刷题

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/868 题目描述 小爱需要完成 𝑛n 道题目…

算法训练营day04

一、24. 两两交换链表中的节点 题目链接&#xff1a;https://leetcode.cn/problems/swap-nodes-in-pairs/description/ 文章讲解&#xff1a;https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.h…

经典文献阅读之--P2O-Calib(利用点对空间遮挡关系的相机-激光雷达标定)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…

Android 13.0 Launcher3单层模式workspace中app列表页排序功能实现

1.概述 在13.0的定制化开发中,对于Launcher3的功能定制也是好多的,而对于单层app列表页来说排序功能的开发,也是常有的功能这就需要了解加载app数据的流程,然后根据需要进行排序就可以了,接下来就来实现这个功能 如图: 2. Launcher3单层模式workspace中app列表页排序功能…

[AI Google] 在 Android 上以更多方式体验 Google AI

总结 通过将 AI 直接构建到 Android 操作系统中&#xff0c;Google 正在重新想象用户与手机的互动方式。最新的更新包括用于家庭作业帮助的 Circle to Search、增强的 Gemini 助手功能以及通话期间的实时诈骗检测。Circle to Search 现在通过逐步指导帮助学生解决数学和物理问…

ChatTTS 开源文本转语音模型本地部署、API使用和搭建WebUI界面(建议收藏)

ChatTTS&#xff08;Chat Text To Speech&#xff09;是专为对话场景设计的文本生成语音(TTS)模型&#xff0c;特别适用于大型语言模型(LLM)助手的对话任务&#xff0c;以及诸如对话式音频和视频介绍等应用。它支持中文和英文&#xff0c;还可以穿插笑声、说话间的停顿、以及语…

Boom 3D软件最新版下载及详细安装教程

值得肯定的是Boom 3D最新版新增的Boom音量控制器和Controlled Boost功能为使用者提供了一个完美的控制&#xff0c;通过一个整齐的设计切换栏的系统音频输出&#xff0c;帮助他们轻松调整音量&#xff0c;从而让他们实现理想的音频输出&#xff0c;有需要的欢迎来开心电玩下载使…

如何从清空的回收站恢复照片

担心如何从清空的回收站中恢复已删除的照片&#xff1f;您删除的文件和文件夹暂时存储在 Windows 回收站中。它使 Windows 用户能够快速恢复意外或故意丢失的项目。但是&#xff0c;为了释放计算机驱动器上的某些空间&#xff0c;有时可能需要清理回收站。 然而&#xff0c;有…