定时器、PWM定时器、UART串口通信

news/2024/5/19 4:02:39

我要成为嵌入式高手之4月15日ARM第八天!!
————————————————————————————

定时器

        S3C2440A 有 5 个 16 位定时器。其中定时器 0、1、2 和 3 具有脉宽调制(PWM)功能。定时器 4 是一个无 输出引脚的内部定时器。定时器 0 还包含用于大电流驱动的死区发生器。

使用s3c2440的时钟4实现1毫秒的定时

定时器配制寄存器 0(TCFG0)

预分频寄存器

定时器配制寄存器 1(TCFG1)

分频寄存器

定时器输入时钟频率 = PCLK / {预分频值+1} / {分频值}

                                {预分频值} = 0~255

                                {分频值} = 2, 4, 8, 16

定时器控制寄存器 1(TCON)

定时器 4 计数缓冲寄存器(TCNTB4)

对算出来的计数器值(2500)的备份

定时器 4 计数监视寄存器(TCNTO4)

很少用到

设置中断寄存器INTMOD、INTMSK

将中断寄存器设置为定时器4

void timer4_init(void)
{TCFG0 |= (19 << 8);//预分频值为4//TCFG1 |= (1 << 16);//分频值为4TCON |= (1 << 22);TCNTB4 = 2500;//设置计数的值TCON |= (1 << 21);TCON &= ~(1 << 21);//先置1再置0将计数值修改进去//打开中断INTMOD &= ~(1 << 14);INTMSK &= ~(1 << 14);TCON |= (1 << 20);//打开定时器
}

PWM定时器

多出一个比较寄存器,相当于 TCNTB 控制周期,TCMPB控制占空比

在此用蜂鸣器调制PWM

用GPB0实现周期400hz,占空比50%的方波

参数设置与定时器4差不多

此外还需要设置蜂鸣器GPIO

端口 B 控制寄存器(GPBCON)

int counter0 = 0;void timer0_init(void)
{//设置蜂鸣器GPIOGPBCON |= (2 << 0);TCFG0 |= (9 << 0);//预分频值为10 = 5MTCFG1 |= (1 << 0);//分频值为4 = 1.25MTCON |= (1 << 22);TCNTB0 = 3125;//设置计数的值 = 400HZTCNTB0 = 3125 / 2;//设置占空比为50%TCON |= (1 << 3) | (1 << 2);//(1 << 2)由高电平开始TCON |= (1 << 1);TCON &= ~(1 << 1);//先置1再置0将计数值修改进去//打开中断INTMOD &= ~(1 << 10);INTMSK &= ~(1 << 10);TCON |= (1 << 0);//打开定时器
}int timer0_handle(void)
{++counter0;if (counter0 >= 1000){ledAllNor();counter0 = 0;}		
}

UART串口通信

        S3C2440A 的每个 UART 包括 7 种状态(Tx/Rx/错误)信号:溢出错误、奇偶校验错误、帧错误、断点、接收 缓冲器数据就绪、发送缓冲器空以及发送移位器空,全部都由相应 UART 状态寄存器(UTRSTATn/UERSTATn) 标示。

我们主要用到接收缓冲区数据中断

外设总线:APB

要发送的数据先写入发送缓冲区,然后通过发送移位器一个字节一个字节发;接收亦如此


UART 方框图(带 FIFO)

        

        波特率时钟是通过 16 和由 UART 波特率分频寄存器(UBRDIVn)指定的 16 位分频系数来分频源时钟(PCLK,FCLK/n 或 UEXTCLK)产生的。 UBRDIVn 由下列表达式决定:

UBRDIVn = (int)( UART 时钟 / ( 波特率 × 16) ) - 1

端口 H 控制寄存器(GPHCON,GPHDAT,GPHUP)

在此要将GPH2和GPH3设置为串口 发送 / 接收 模式

UART 线路控制寄存器(ULCON)

UART 控制寄存器(UCON)


在此不用管FCLK,选择PCLK

Tx发送中断类型:缓冲区一变成空,就产生中断

Rx接收中断类型:设置为脉冲类型

……

UART TX/RX 状态寄存器

用来查询的

UART 发送缓冲寄存器(保持寄存器和 FIFO 寄存器)

发送数据时进行修改

UART 接收缓冲寄存器(保持寄存器和 FIFO 寄存器)

UART 波特率分频寄存器

要进行计算得出波特率

        波特率时钟是通过 16 和由 UART 波特率分频寄存器(UBRDIVn)指定的 16 位分频系数来分频源时钟(PCLK,FCLK/n 或 UEXTCLK)产生的。 UBRDIVn 由下列表达式决定:

UBRDIVn = (int)( UART 时钟 / ( 波特率 × 16) ) - 1

例如,如果波特率为 115200 bps 并且 UART 时钟为 40 MHz,UBRDIVn 为:

UBRDIVn = (int)(40000000 / (115200 x 16) ) - 1

                = (int)(21.7) - 1 [取最接近的整数]

                = 22 - 1 = 2

void uart0_init(void)
{unsigned int t;GPHCON |= (2 << 4) | (2 << 6);t = ULCON0;t &= ~(1 << 6);t &= ~(7 << 3);t &= ~(1 << 2);t |= (3 << 0);ULCON0 = t;t = UCON0;t &= ~(3 << 10);t &= ~((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4));t |= (1 << 2) | (1 << 0);UCON0 = t;UBRDIV0 = 325;
}

发送一个字符: 

void uart0_send_char(unsigned char data)
{UTXH0 = data;while ((UTRSTAT0 & (1 << 1)) == 0);//查询TX寄存器是否为0,为0表示发送完毕,非0表示还在发送,需要等待发送完毕
}

发送字符串:

void uart0_send_buffer(unsigned char *p, unsigned int len)
{int i = 0;for (i = 0; i < len; ++i){uart0_send_char(*p++);	}
}

数据接收

首先需要打开中断

中断模式(INTMOD)寄存器

中断屏蔽(INTMSK)寄存器

次级源挂起(SUBSRCPND)寄存器

中断次级屏蔽(INTSUBMSK)寄存器

对于接收放需要打开INT_RXD0

中断偏移(INTOFFSET)寄存器

接收到的数据要从接收缓存区读取

UART 接收缓冲寄存器(保持寄存器和 FIFO 寄存器)

void uart0_init(void)
{unsigned int t;//将GPIO端口设置为串口GPHCON |= (2 << 4) | (2 << 6);//设置串口线路控制寄存器t = ULCON0;t &= ~(1 << 6);t &= ~(7 << 3);t &= ~(1 << 2);t |= (3 << 0);ULCON0 = t;//设置控制寄存器t = UCON0;t &= ~(3 << 10);t &= ~((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4));t |= (1 << 2) | (1 << 0);UCON0 = t;//设置波特率UBRDIV0 = 325;//设置中断INTMOD &= ~(1 << 28);INTMSK &= ~(1 << 28);INTSUBMSK &= ~(1 << 0);
}
unsigned char rcvBuffer[256];
unsigned int pos;void uart0_handle(void)
{if ((SUBSRCPND & (1 << 0)) != 0){rcvBuffer[pos++] = URXH0;	}SUBSRCPND = SUBSRCPND;
}

main.c

int main(void)
{	wdt_init();clock_init();led_init();uart0_init();	pos = 0;while (1){if (pos != 0){delay(0x3FFFF);uart0_send_buffer(rcvBuffer, pos);pos = 0;}}
}	


http://www.mrgr.cn/p/50400081

相关文章

每日两题 / 438. 找到字符串中所有字母异位词 238. 除自身以外数组的乘积(LeetCode热题100)

438. 找到字符串中所有字母异位词 - 力扣&#xff08;LeetCode&#xff09; 记录p串每个字符出现次数 维护与p串等长的滑动窗口&#xff0c;记录其中每个字符的出现次数 每次滑动后将当前次数与p串的次数比较即可 class Solution { public:vector<int> findAnagrams(s…

Nginx第3篇-使用ngx_http_proxy_connect_module配置https正向代理

场景 我使用python爬虫&#xff0c;然后需要个代理&#xff0c;所以就用Nginx搭了一个代理服务器。对Nginx也不太熟&#xff0c;慢慢摸索&#xff0c;搭建完之后发现只能代理http的请求&#xff0c;无法穿透https。几经折腾和摸索发现一个强大的HTTP代理模块&#xff1a;ngx_h…

水资源管理系统:守护生命之源,构建和谐水生态

水资源是维系地球生态平衡和人类社会可持续发展的重要基础。然而,随着人口增长、工业化和城市化的加速,水资源短缺、水质污染和生态破坏等问题日益凸显。在这样的背景下,构建一个全面、高效、智能的水资源管理系统显得尤为迫切和必要。 项目背景 水资源的合理利用和有效保护…

Docker构建Golang项目常见问题

Docker构建Golang项目常见问题 1 Dockerfile1.1 dockerfile报错&#xff1a;failed to read expected number of bytes: unexpected EOF1.2 go mod tidy: go.mod file indicates go 1.21, but maximum supported version is 1.171.3 是否指定启动文件问题 2 构建及部署 1 Docke…

Unity3D 爆火的休闲益智游戏工程源码/3D资源 大合集

Unity3D休闲益智游戏工程源码大合集 一、关卡类游戏工程源码二、跑酷类游戏工程源码三、消除合成类游戏工程源码四、棋牌类游戏工程源码五、RPG(角色扮演)类游戏工程源码六、FPS&#xff08;射击&#xff09;类游戏工程源码十、Unity3D工艺仿真六、Unity游戏资源1、Unity3D 吃鸡…

vis.js外部自定义折线图

代码案例<!doctype html> <html> <head><title>Timeline</title><script type="text/javascript" src="https://unpkg.com/vis-timeline@latest/standalone/umd/vis-timeline-graph2d.min.js"></script><lin…

react native 安装app时报错 ”已安装了签名冲突的应用“

1. 问题描述: react native开发完app,手动安装app,报错”已安装了签名冲突的应用“。 或者执行命令安装npx react-native run-android --mode=release,报错2. 解决方法: 直接卸载原来的app发现无效,于是执行: adb uninstall "xxxxx"xxxxx换成你的app名,在这里…

SLS 查询新范式:使用 SPL 对日志进行交互式探索

在构建现代数据和业务系统的过程中,可观测性已经变得至关重要,日志服务(SLS)为 Log/Trace/Metric 数据提供了大规模、低成本、高性能的一站式平台服务,并提供数据采集、加工、投递、分析、告警、可视化等功能,从而全面提升企业在研发、运维、运营和安全等各种场景的数字化…

MySQL 基础语法(2)

文章目录 创建表查看表修改表表数据插入 本文为表结构相关的基础语言库相关的基础语句 创建表 CREATE TABLE table_name ( field1 datatype comment xxx, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎;CREATE TABLE&#xff1…

性能测试——压测工具locust——脚本初步编写

User Class 一个用户类代表一个用户(如果你愿意,也可以是一群蝗虫)。Locust 将为正在模拟的每个用户生成一个 User 类的实例。用户类可以定义一些通用属性。on_start 和 on_stop 方法 User和TaskSets可以声明一个on_start和on_stop方法, User:在该用户开始运行时调用on_st…

Qt-饼图示范

1.效果图 2.代码如下 2.1 .h文件 #ifndef PIECHARTWIDGET_H #define PIECHARTWIDGET_H#include <QWidget> #include <QChartView> #include <QPieSeries>#include<QVBoxLayout> #include<QMessageBox> #include <QtCharts>struct PieDat…

记录如何用php做一个网站访问计数器的方法

简介创建一个简单的网站访问计数器涉及到几个步骤,包括创建一个用于存储访问次数的文件或数据库表,以及编写PHP脚本来增加计数和显示当前的访问次数。方法以下是使用文件存储访问次数的基本步骤: 创建一个文本文件来存储计数:在网站的根目录下创建一个名为 counter.txt 的文…

截断堆积柱状图绘制教程

本教程原文链接&#xff1a;截断堆积柱状图绘制教程 欢迎大家转载&#xff01;&#xff01;&#xff01;&#xff01; 本期教程 写在前面 堆积柱状图是柱状图的常见类型之一&#xff0c;也是平时使用概率较高的图形之一。我们前期发布了很多个柱状图的绘制教程&#xff0c;若你…

Linux操作系统·Linux简介

1.世界上第一个完善的网络操作系统 Unix是1969年由美国电话电报公司(AT&T)贝尔实验室的两个工程师所创造的操作系统&#xff0c;它允许计算机同时处理多用户和程序。目前大型政府单位、大型企业、航空公司、金融机构多在使用&#xff0c;价钱昂贵&#xff0c;但性能和稳定性…

js逆向实战之微信公众平台pwd参数解密

网址:https://mp.weixin.qq.com/ 分析过程调出开发者工具,切换到network模块,随便输入一个账号和密码,抓包。看到pwd参数被加密了,接下来就是去找到pwd参数的加密过程。但其实这里可以进行加密方法的猜测,密码处输入123456,抓包。相信有经验的人可以很快的反应出是个md5…

[linux]进程控制——进程终止

一、main函数的返回值 我们在编写C语言的程序时&#xff0c;通常会这样写&#xff1a; int main() {return 0; } 那么我们为什么要返回&#xff08;return&#xff09;0 呢&#xff1f; 其实&#xff0c;main函数也是一个函数&#xff0c;它也会被调用&#xff0c;所以谁调…

python用循环新建多个列表

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 当我们处理数据时&#xff0c;有时候需要创建多个列表以存储不同类型或不同条件下的数据。在…

结对编程心得

结对编程心得 要求如下所示: 小学老师要每周给同学出300道四则运算练习题。 这个程序有很多种实现方式: C/C++ C#/VB.net/Java Excel Unix Shell Emacs/Powershell/Vbscript Perl Python 两个运算符,100 以内的数字,不需要写答案。 需要检查答案是否正确,并且保证答案在 0.…