基于ARM内核的智能手环(day3)

2024-04-01 06:12
文章标签 智能 day3 内核 arm 手环

本文主要是介绍基于ARM内核的智能手环(day3),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

回顾

延时(delay)与时钟频率

延时(delay)操作与系统的时钟频率有关,通过nop()指令等待一定数量的时钟周期以实现延时功能。

定时器

定时器是一种用于在特定时间间隔内执行任务或触发事件的设备或模块。

按键检测

按键检测的流程包括:

  1. 查看原理图,确定按键连接到哪个IO口;
  2. 找到对应的IO口在硬件中的位置;
  3. 分析原理图,了解按键的接线和电路连接情况。

按键抖动

按键抖动是指在按下或释放按键时,由于机械结构或电路原因而导致按键信号出现短暂波动。解决按键抖动的方法包括:

  1. 添加适当的延时,以忽略短暂的抖动信号;
  2. 在按键电路中添加电容,使抖动信号得到滤波和稳定。

时间片轮询

定时器:内核定时器(滴答定时器)

image-20240331182206988

image-20240331182212779

  1. 中断函数: 中断函数是由硬件中断触发时执行的特殊函数。当系统中发生某些事件(例如按键按下、定时器溢出等)时,中断会打断当前的执行流程,转而执行与该中断相关的中断服务程序(ISR),执行完成后再返回到原来的执行点。

  2. 时间片轮询: 这是一种基于时间片的调度算法,用于多任务系统中。系统按照一定的时间片分配给每个任务,任务依次执行。在时间片轮询中,通常会定期检查每个任务是否需要执行,然后根据优先级和调度策略来确定下一个执行的任务。

滴答定时器:

滴答定时器(Tick Timer)是一种特殊类型的定时器,通常用于在嵌入式系统中生成精确的时间间隔。它的基本原理是在每个固定时间间隔内产生一个“滴答”信号,通过计数这些滴答信号,可以实现精确的时间测量和延时操作。

滴答定时器通常由硬件支持,它可以在芯片内部以固定的时钟频率运行。当滴答定时器启动时,它会以固定的时间间隔(通常是毫秒或微秒级别)产生一个滴答信号。这个时间间隔由定时器的时钟频率和预设的计数器值决定。

也就是说,滴答定时器是一直在执行的,不受程序影响

时间片轮询基本步骤:

  1. 定义变量: 首先,在程序中定义一个变量,用于记录时间片的状态或计数器。这个变量通常是一个全局变量。

  2. 变量在对应中断服务函数里增加: 如果使用定时器中断来实现时间片轮询,那么在定时器中断服务函数(ISR)里会对时间片计数器进行增加操作。

  3. 变量外部声明: 这个变量需要在全局范围内声明,以便在各个函数中都可以访问到它。

  4. 在主函数里判断: 在主函数(或其他需要执行轮询的地方)里,通过判断时间片计数器的值来确定是否需要执行某个任务。如果时间片计数器达到了设定的阈值,就执行相应的任务。

  5. 变量清零: 在执行完一轮时间片轮询后,需要将时间片计数器清零,以便开始下一轮的时间片计数。

实现逻辑

那么我们只需要载滴答定时器里面声明一个变量,然后滴答定时器没执行一次变量+1

执行到特定的次数后就开始执行相应的函数 ,并清零函数

即可完成时间片轮询

//滴答定时器的中断函数
void SysTick_Handler(void)
{LED1_TIME++;
}

主函数中:

if(LED1_TIME >= 500){LED1_TURN;LED1_TIME = 0;//USART1_SendStr(arr);}

这样子在我们就成功设置了状态指示灯

即在程序正常执行过程中led灯闪烁


串口通信

通信的类型可以根据通信的范围和介质来分类:

1. 根据通信的范围:
  • 局域网(LAN): 一种覆盖范围较小的网络,通常用于连接同一建筑物或校园内的设备。例如校园网、办公室内部网等。
  • 广域网(WAN): 覆盖范围更广,可以连接不同地区甚至不同国家的网络,最典型的例子就是因特网。
2. 根据通信的介质:
  • 有线通信: 通过物理连接来传输数据的通信方式。
    • 网线(Ethernet):使用以太网协议进行数据传输的有线连接。
    • USB(Universal Serial Bus):通过USB接口进行数据传输的通信方式,例如U盘。
  • 无线通信: 不需要物理连接即可传输数据的通信方式。
    • WiFi:使用无线局域网技术进行数据传输的无线连接方式。
    • 蓝牙(Bluetooth):用于短距离数据传输的无线技术,通常用于连接手机、耳机等设备。

这些通信类型都在不同的场景下发挥作用,满足了人们在信息交流和数据传输方面的需求。


通信方式:

串行通信:
  • 使用单根数据线进行数据传输。
  • 特点:速率相对较慢,但抗干扰能力强。
并行通信:
  • 使用多根数据线同时传输数据。
  • 特点:速率相对较快,但抗干扰能力较弱。

2. 工作方式:

通信方式特点举例
单工通信只能单向传递数据,不能同时发送和接收数据。麦克风和喇叭之间的通信
半双工通信设备可以发送和接收数据,但同一时间只能执行其中一种操作。对讲机可以让用户交替地发送和接收信息
全双工通信可以同时进行数据的发送和接收。微信、打电话等通信方式

3. 同步与异步通信:

通信方式特点举例
同步通信设备之间有一根同步时钟线,用于同步数据传输。数据传输的时机和速率由时钟信号控制,数据按照时钟信号进行同步传输。以太网、USB
异步通信设备之间没有共享的同步时钟线,数据按照起始位和停止位的规则进行传输。数据传输的时机不依赖于时钟信号,而是通过起始位和停止位来确定数据的传输时序。RS-232串口、UART

4. 传输速率:

传输速率通常用波特率(bps)来表示,表示每秒传输的位数。

常见的波特率包括:
  • 115200 bps:用于高速数据传输,例如串口通信。
  • 9600 bps:用于一般数据传输,例如早期的调制解调器通信。

这些通信方式和特点在不同的应用场景中具有不同的优势和适用性。


RS232协议

  • 起始位:数据传输开始的信号,由逻辑1变为逻辑0。

  • 数据位:通常为8位,表示一个字节的数据。

  • 校验位

    :可选的奇偶校验,用于检验数据位中1的个数,以确保传输的数据正确性。

    • 奇校验:校验位补充一个1,使数据位中1的个数为奇数。
    • 偶校验:校验位补充一个1,使数据位中1的个数为偶数。
  • 停止位:数据传输结束的信号,由逻辑0变为逻辑1。

    image-20240331184858996

串口

串口是一种用于串行通信的端口,常用于连接计算机与外部设备。其中:

  • TX:发送端,负责将数据发送给外部设备。
  • RX:接收端,负责接收外部设备发送的数据。
  • GND:地线,用于建立电气连接并确保信号的准确传输。

串口通常用于连接设备,如串口打印机、调制解调器等,通过串行传输数据。


串口连接可以分为直接连接和间接连接两种方法:

1. 直接连接

直接连接是指将两个设备通过串口线直接相连,其中一端的发送端(TX)连接到另一端的接收端(RX),同时地线(GND)也需要连接起来。这种连接方式通常用于连接两台设备之间进行数据传输,例如连接两台计算机或者计算机与外部设备的串口连接。

image-20240331184952319

2. 间接连接

间接连接是指通过中间设备或者线路进行连接,而不是直接连接两台设备。例如,可以通过串口转USB转换器将串口设备连接到计算机的USB端口,或者通过串口服务器将串口设备连接到局域网中的计算机,然后通过网络进行数据传输。这种连接方式可以扩展串口设备的连接距离,并且可以实现远程访问和控制。

一键下载电路:image-20240331185009218

image-20240331191212119

我们这里使用的是USART1

原因也很简单 —— 功能强大

我们来看收发器的原理图和引脚图

image-20240331191109047

image-20240331191112777

image-20240331191129448

代码实现

那第一步一定是先初始化

void USART1_Config(u32 brr)
{//step1.初始化IO口 PA9,PA10RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOA,&GPIO_InitStruct);//step2.初始化USART1//1.开时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//2.配置模式USART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate = brr;//波特率USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//失能硬件流控制USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位1位USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据位8位//3.初始化USART_Init(USART1,&USART_InitStruct);//4.使能USART_Cmd(USART1,ENABLE);//开启接收中断USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//NVICNVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStruct);}

那么如何写一个函数用来发送数据呢

void USART1_SendCh(char data)
{//判断上次发送是否完成while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == 0);USART_SendData(USART1,data);
}

测试完成后只能发送单个数据,那么我们再写一个发送字符串的函数

void USART1_SendStr(char *p)
{while(*p != '\0'){USART1_SendCh(*p);p++;}
}

好的,那么可以发送了,我们怎么才能直到自己成功发送了呢

我们只需要在发送之后让单片机返回我们发送的内容即可

那么我们再写一个中断函数

void USART1_IRQHandler()
{//判断是什么中断if(USART_GetITStatus(USART1,USART_IT_RXNE) == 1){recv = USART1->DR;USART1->DR = recv;}
}

如此我们便实现了串口的通信


次回预告:lcd屏幕是如何显示画面的呢?我们下次将会讲解

这篇关于基于ARM内核的智能手环(day3)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/866408

相关文章

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

智能交通(二)——Spinger特刊推荐

特刊征稿 01  期刊名称: Autonomous Intelligent Systems  特刊名称: Understanding the Policy Shift  with the Digital Twins in Smart  Transportation and Mobility 截止时间: 开放提交:2024年1月20日 提交截止日

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

【C++】作用域指针、智能指针、共享指针、弱指针

十、智能指针、共享指针 从上篇文章 【C++】如何用C++创建对象,理解作用域、堆栈、内存分配-CSDN博客 中我们知道,你的对象是创建在栈上还是在堆上,最大的区别就是对象的作用域不一样。所以在C++中,一旦程序进入另外一个作用域,那其他作用域的对象就自动销毁了。这种机制有好有坏。我们可以利用这个机制,比如可以自动化我们的代码,像智能指针、作用域锁(scoped_lock)等都是利用了这种机制。