当前位置: 首页 > news >正文

郑州优化网站公司有哪些家装设计师排名

郑州优化网站公司有哪些,家装设计师排名,汕头网站seo外包,青岛网页制作案例#x1f431;作者#xff1a;一只大喵咪1201 #x1f431;专栏#xff1a;《理解ARM架构》 #x1f525;格言#xff1a;你只管努力#xff0c;剩下的交给时间#xff01; 目录 #x1f360;操作寄存器实现UART#x1f35f;UART原理#x1f35f;编程 #x1f360;… 作者一只大喵咪1201 专栏《理解ARM架构》 格言你只管努力剩下的交给时间 目录 操作寄存器实现UARTUART原理编程 段的概念IDE背后的命令总结 操作寄存器实现UART UART原理 UART的全称是Universal Asynchronous Receiver and Transmitter即异步发送和接收。 串口在嵌入式中用途非常的广泛主要的用途有 打印调试信息外接各种模块GPS、蓝牙 串口因为结构简单、稳定可靠广受欢迎。 如上图所示串口通信只需要三根线发送(TXD)、接收(RXD)、地线(GND)。 通信双方的TXD与对方的RXD相连。 串口发送数据是以帧格式一帧一帧来发的帧格式由1bit起始位8或9bit数据位1或1.5或2bit校验位1bit停止位组成。 通常情况下都使用8bit数据位不适用校验位这样的一帧数据有10个bit。 校验位又叫奇偶校验位如果8个数据位加校验位中比特为位1的个数是奇数校验位就是1否则就是0。 由于现在电子技术的逐渐成熟串口通信很少出错所以校验位使用的不多。 如上图所示是一帧数据传送时的逻辑电平示意图。 发送方将自己的TXD线从高电平拉到低电平保持一段时间接收方读取到自己的RXD线由高到底以后就知道要接收数据了。发送方按照自己发送的这个字节从低位开始改变TXD线的电平每改变一次保持一段时间如此反复8次完成一字节数据的发送。接收方在自己RXD线上的电平保持期间的中间时刻根据电平状态记录该比特位的值最后组合成一字节数据。发送方将一字节数据发送完毕后将自己的TXD线拉高方便下次发送数据接收方在接收到8bit数据以后并且检测到自己RXD线是高电平就知道这一帧数据传送完毕了。 上面描述数据发送过程中电平维持的时间就是根据波特率来确定的一般选波特率都会有9600,19200,115200等选项。 波特率可以简单理解为串口通信过程中1秒钟能发送的比特位个数。波特率是通信双方约定好的一个按照这个速度发送数据另一个按照这个速度接收数据。 逻辑电平 如上图所示是本喵使用的ARM开发板串口发出的电平信号在xV至5V之间就认为是逻辑1在0V至yV之间就为逻辑0这叫做TTL/CMOS逻辑电平。 如上图所示是RS-232逻辑电平在-12V至-3V之间就认为是逻辑1在3V至12V之间就为逻辑0RS-232的电平比TTL/CMOS高能传输更远的距离在工业上用得比较多。 可以看到RS-232与TTL/CMOS相同逻辑电平对应的真实电压正负是相反的。 如上图所示ARM芯片上的串口都是TTL电平的通过板子上或者外接的电平转换芯片转成RS232接口连接到电脑的RS232串口上实现两者的数据传输。 如上图所示现在的电脑越来越少有RS232串口的接口但USB是几乎都有的。因此使用USB串口芯片将ARM芯片上的TTL电平转换成USB串口协议即可通过USB与电脑数据传输。 无论那种接口板子上的芯片IO口输出的都是TTL/CMOS电平我们在写程序时仅需要关心输出的逻辑电平即可。 编程 一款ARM芯片上会有多个USART串口一般UART1用来输出调试信息这里本喵也使用USART1。 确定引脚 如上图本喵使用的STMF103ZET6芯片上USART1的USART1_RX、USART1_TX接到了PA10、PA9。 将引脚配置为UART功能 使能GPIOA/USART1模块 如上图是RCC_APB2ENR寄存器GPIOA模块、USART1模块的使能都是在这一个寄存器里实现。 如上图从芯片手册中查看Reset and clock control RCC寄存器的基地址是0x40021000再根据RCC_APB2ENR的偏移地址0x18得到该寄存器的绝对地址是0x40021000 0x18。 将该寄存器的bit2和bit14写一此时就使能了GPIOA和USART1模块。 配置引脚功能 从上面的芯片原理图可以知道PA9、PA10有三种功能GPIO、USART1、TIMER1所以这里要将其配置为USAT1功能。 如上图所示GPIOx_CRH寄存器该寄存器的绝对地址是0x40010800 0x04PA9配置为输出所以将MODE9代表的bit4和bit5配置成01将CNF9代表的bit6和bit7配置为10。 PA10配置为输入将MODE10代表的bit8和bit9配置为00再将CNF10代表的bit10和bit11配置成01。 由于这里仅使能了USART1没有使能定时器所以PA9和PA10的默认复用功能就是USART1使用默认值即可。 设置串口参数 设置波特率 如上图所示是波特率的计算公式USARTDIV由整数部分、小数部分组成USARTDIV DIV_Mantissa (DIV_Fraction / 16) 。fck是内部时钟频率这里就使用默认值是8MHZ。 如上图USART_BRR寄存器DIV_Mantissa表示整数部分占用该寄存器的bit4~bit15DIV_Fraction表示小数部分占用该寄存器的bit0~bit3。 以常用的波特率115200为例来计算该寄存器的值 设置波特率* 115200 8000000/16/USARTDIV* USARTDIV 4.34* DIV_Mantissa 4* DIV_Fraction / 16 0.34* DIV_Fraction 16*0.34 5所以给USART_BRR寄存器的bit4~bit15赋值4bit0~bit3赋值5根据这两个值再来倒推一下真实的波特率 真实波特率:* DIV_Fraction / 16 5/160.3125* USARTDIV DIV_Mantissa DIV_Fraction / 16 4.3125* baudrate 8000000/16/4.3125 115942可以看到虽然和115200有点差距但是并不影响。 设置数据格式 如上图所示USART1_CR1寄存器本喵将帧格式设置为1个起始位8个数据位无校验位1个停止位所以将bit13设置1bit12设置为0bit10设置为0bit3设置为1bit2设置为1。 但是此时并没有设置几个停止位还需要设置另一个寄存器 如上图所示USART_CR2寄存器将bit12~bit13设置为00表示1个停止位。 根据状态寄存器读写数据 如上图所示串口模块结构图发送有一个发送数据寄存器和发送移位寄存器接收有一个接收数据寄存器和接收移位寄存器。 发送数据时CPU将数据写入到发送数据寄存器然后由发送移位寄存器一位一位将数据通过TXD线发送出去。 接收数据时RXD线上的数据一位一位放入接收移位寄存器该寄存器接收完毕后将整个字节数据放入到接收数据寄存器CPU从接收数据寄存器中可以直接读取数据。 状态寄存器 如上图所示USART_SR状态寄存器TXE表示发送数据寄存器是否为空该位并不能说明数据已经发送完了因为真正发送数据的是移位寄存器只能说发送数据寄存器将数据给了移位寄存器CPU可以再向数据寄存器中写数据了。 TC表示发送数据完成即发送数据寄存器和移位寄存器中的数据都发送完毕了。RXNE表示接收数据寄存器中有数据了说明已经接收到了数据CPU可以来读取了。 数据寄存器 如上图所示USART_DR寄存器写、读这个寄存器就可以发送、读取串口数据。 在配置完引脚和功能选择以后本喵在介绍USART_XXX寄存器的时候并没有说它的地址因为无论是设置波特率的USART_BRR还是设置数据格式的USART_CR1再或者状态寄存器USART_SR以及数据寄存器USART_DR这些都是以USART为基地址的。 如上图所示USART1的基地址是0x40013800上面本喵提到的这些寄存器都是在这个基地址的基础上进行偏移也就是说它们都属于USART1模块中的寄存器。 typedef unsigned int uint32_t; typedef struct {volatile uint32_t SR; /*! USART Status register, Address offset: 0x00 */volatile uint32_t DR; /*! USART Data register, Address offset: 0x04 */volatile uint32_t BRR; /*! USART Baud rate register, Address offset: 0x08 */volatile uint32_t CR1; /*! USART Control register 1, Address offset: 0x0C */volatile uint32_t CR2; /*! USART Control register 2, Address offset: 0x10 */volatile uint32_t CR3; /*! USART Control register 3, Address offset: 0x14 */volatile uint32_t GTPR; /*! USART Guard time and prescaler register, Address offset: 0x18 */ } USART_TypeDef;如上面代码所示用一个结构体来表示USART模块里面的成员变量表示各个寄存器让它们在结构体中的偏移量和寄存器相对于USART模块的偏移量相对应此时就可以通过访问这个结构体访问到各个寄存器。 如上图所示是整个串口的初始化代码其中配置波特率等参数使用的是结构体访问的寄存器串口结构体是一个局部变量。 如上图所示定义发送一个字符和接收一个字符的函数通过判断状态寄存器的值进而读写DR寄存器也是通过结构体访问的寄存器结构体是一个局部变量。 如上图此时将程序烧录到开发板以后会通过串口发送Hello字符串在PC端发送一个字符板子接收到以后返回该字符及下一个字符此时我们的串口是配置好了。 问题为什么每个函数中都得创建一个uart1结构体局部变量而不是创建全局变量供这些函数使用呢 段的概念 如上图所示增加三个函数用来打印字符串及变量的地址。 如上图所示创建四个全局变量g_ConstChar被const修饰然后在mymain中分别打印四个变量的地址及它们的值。 将程序编译后烧录到开发板中通过串口工具来观察输出的内容。 如上图所示来看这四个变量的地址只有g_ConstChar这个被const修饰的变量地址是位于Flash中的其他几个变量都是位于RAM中。 如上图keil中只能了Flash和RAM的起始地址根据这两个参数很容易判断出这四个变量所处的位置。 如上图再来看输出的这四个变量的值可以看到只有const修饰的g_ConstChar变量输出了B其他几个变量都没有输出对应的则而是奇怪的东西。 其他变量输出的奇怪值表明这几个变量地址处的值是乱码。 g_ConstChar变量位于Flash也就是ROMROM是只读的不能写而其他三个变量位于RAMRAM是可读可写的。 在编译的时候编译器进行了判断处理g_ConstChar是只读的不会写所以把它放在Flash就可以。 Flash上存放这种只读数据的区域叫做只读数据段。 其他三个变量会进行读和写的操作所以编译器给了它们一个链接地址这个地址对应在RAM上方便CPU进行读写。 RAM上存放这种可读可写全局变量的区域叫做可读可写数据段。 无论有没有被const修饰的变量它们都有初始值A或者B这个两个数值是不会变的只是用来使用的所以编译器将这两个值放在这两个变量位于Flash上的地址处(加载地址)。 有几个有初始值的全局变量Flash中就会保存几个初始值。Flash以及内存中并没有变量名只会在变量的地址处直接存放数值。 像char g_A 0这种初始值为0的全局变量以及char g_B这种没有初始值的全局变量Flash上就没有必要存放它们的初始值。 假设初始值为0的变量有一万个Flash中难道要存放1万个0吗肯定不会的这样浪费内存不说还没有任何意义。对于没有初始值的全局变量Flash中更不会存放它的初始值了。 所以编译器在编译的时候直接给这种初始值为0或者没有初始值的全局变量分配一个链接地址位于RAM中CPU直接去链接地址读写就可以了。 这种存放初始值为0或者没有初始值所在的RAM区域被叫做BSS段或者ZI段。 我们写的代码经过编译链接以后会生成一个二进制可执行文件里面全部都是机器码这部分代码并不会改变所以也存放到Flash上。 存放代码的Flash区域被叫做代码段。 至于栈以及堆本喵在前面的文章中就详细讲解过这里就不再说了有兴趣的小伙伴可以移步单片机中的C语言。 所以程序分为这几个段 代码段(RO-CODE)就是程序本身不会被修改可读可写的数据段(RW-DATA)有初始值的全局变量、静态变量需要从ROM上复制到内存只读的数据段(RO-DATA)可以放在ROM上不需要复制到内存BSS段或ZI段 初始值为0的全局变量或静态变量没必要放在ROM上使用之前清零就可以未初始化的全局变量或静态变量没必要放在ROM上使用之前清零就可以 局部变量保存在栈中运行时生成堆一块空闲空间使用malloc函数来管理它malloc函数可以自己写 IDE背后的命令 IDE指集成开发环境(Integrated Development Environment)。我们开发STM32F103等单片机程序时使用是keil5就是一种IDE。 使用IDE很容易操作点点鼠标就可完成添加文件指定文件路径(头文件路径、库文件路径)指定链接库编译、链接下载、调试等功能。 其实在我们点下某一个按钮以后IDE的背后会执行一系列指令 如上图在keil5的Output选择中勾选Create Batch File然后重新全部编译。 如上图此时在当前工程的Objects目录下会多出上面红色框中的四个文件。 如上图所示分别是这几个文件中的内容都是一系列的命令行指令用来编译和链接文件的指令具体怎么用不用管只需要知道有这些东西。 start._ia中的命令行就是在让start.s汇编文件编译成start.o目标文件。main._i中的命令行就是在让main,c源文件编译成main.o目标文件。uart._i中的命令行就是在让uart.c源文件编译成uart.o目标文件。led.linp中的命令行就是把这几个.o目标文件链接在一起形成一个二进制可执行文件led.axf我们烧录的就是这个文件。 当我们点下IDE上的编译选项时IDE会自动执行上面四个文件中的内容最后生成我们需要的东西。 总结 虽然配置串口已经是一个老生常谈的问题了但是相信大家很少直接使用寄存器地址来配置吧这个过程中可以加深对ARM架构的理解。 串口配好后通过打印数据过程中出现的问题介绍了段的概念编译器不同类型的变量放在内存中不同的位置。 要意识到编译一个工程的背后没有那么简单。
http://www.fuzeviewer.com/news/19934/

相关文章:

  • 企业注册app下载seoul是什么意思中文
  • 文化产业协会网站源码WordPress QQ 微
  • 做英语听力音频的网站货运 东莞网站建设
  • 网站的类型主要有wordpress怎么缩进
  • cocos2d-js可以做网站吗高定网站
  • 网站设计公司电话海门做网站
  • 网站制作 火星科技网络规划设计师一本通
  • 设一个网站链接为安全怎么做网站一般多少钱一年
  • 苏州网站建设招聘吉林网站建设哪家好
  • 做ppt兼职的网站有哪些icp备案号怎么填写
  • 网站建设宣传册内容wordpress产品筛选
  • 网站建设要注意些什么深圳网站建设公司联
  • 网站定制设计价目表安阳企业网站优化外包
  • 趴比库的网站是谁建设的wordpress页面怎么编辑
  • 用KEGG网站做KEGG富集分析建筑资料免费下载网站
  • 做展示网站wordpress 页面目录
  • 福州市建设管理处网站怎么让wordpress挂掉
  • 小程序游戏破解seo技术优化整站
  • 全功能电子商务网站建设网站资讯板块的搭建
  • 使用他人商标做网站搜索词wordpress下边音乐
  • 典型的企业网站上饶市建设局网站百代
  • 随州网站建设价格下载的网站模板怎么进入后台
  • 网站建设的职位网站建设及维护价钱
  • 福田网站建设-信科网络wordpress php 模板修改
  • 可以做公众号的网站湘潭学校网站建设 磐石网络第一
  • 中国风网站设计沈阳设计网站
  • 公司营销策划方案案例北京百度推广优化排名
  • 自己的网站做弹出广告营销型制作网站公司
  • 中国风html5网站模板免费下载东莞齐诺做网站
  • 外贸培训常德网站建设优化