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

我要成为嵌入式高手之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);//分频值为4

	TCON |= (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)
{
	//设置蜂鸣器GPIO
	GPBCON |= (2 << 0);

	TCFG0 |= (9 << 0);//预分频值为10 = 5M
	TCFG1 |= (1 << 0);//分频值为4 = 1.25M

	TCON |= (1 << 22);
	TCNTB0 = 3125;//设置计数的值 = 400HZ
	TCNTB0 = 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;
		}
	}
}	

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

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

相关文章

【无标题】系统思考—智慧共赢座谈会

第432期JSTO—“智慧共赢座谈会”精彩回顾 我们身处一个快速变化的世界&#xff0c;其中培训和咨询行业也不断面临新的挑战和机遇。为了紧跟这些变革&#xff0c;我们邀请了行业专家与合作伙伴深入探讨在培训、交付和销售过程中遇到的难题。 本次座谈会的亮点之一是我们科学上…

rhce day1

一 . 在系统中设定延迟任务要求如下 在系统中建立 easylee 用户&#xff0c;设定其密码为 easylee 延迟任务由 root 用户建立 要求在 5 小时后备份系统中的用户信息文件到 /backup 中 确保延迟任务是使用非交互模式建立 确保系统中只有 root 用户和 easylee 用户可以执行延…

LeetCode 热题 100 Day02

滑动窗口模块 滑动窗口类问题&#xff1a;总能找到一个窗口&#xff0c;从前往后移动来查找结果值。 这个窗口的大小可能是固定的&#xff0c;也可能是变化的。但窗口的大小一定是有限的。 https://www.cnblogs.com/huansky/p/13488234.html Leetcode 3. 无重复字符的最长子串 …

什么是分组分析法

调查数据显示&#xff0c;2019 年年末中国大陆总人口 140005 万人。从年龄构成看&#xff0c;16 至 59 周岁年末人数为 89640 万&#xff0c;占总人口的比重为 64.0%&#xff1b;60 周岁及以上人口 25388 万人&#xff0c;占总人口的 18.1%&#xff0c;其中 65 周岁及以上人口 …

leetcode-链表中间节点

876. 链表的中间结点 题目 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间…

【办公类-21-16】 20240410三级育婴师 344多选题(题目与答案合并word)

作品展示 背景需求&#xff1a; 前文将APP题库里的育婴师题目下载到EXCEL&#xff0c;并进行手动整理【办公类-21-14】 20240406三级育婴师 344道多选题 UIBOT下载整理-CSDN博客文章浏览阅读287次&#xff0c;点赞8次&#xff0c;收藏9次。【办公类-21-14】 20240406三级育婴师…

银河麒麟高级服务器操作系统adb读写缓慢问题分析

1.问题环境 处理器&#xff1a; HUAWEI Kunpeng 920 5251K 内存&#xff1a; 512 GiB 整机类型/架构&#xff1a; TaiShan 200K (Model 2280K) BIOS版本&#xff1a; Byosoft Corp. 1.81.K 内核版本 4.19.90-23.15.v2101.ky10.aarch64 第三方应用 数据库 2.问题…

基于直方图的图像阈值计算和分割算法FPGA实现,包含tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 VIVADO2019.2 matlab2022a 3.部分核心程序 timescale 1ns / 1ps // // Company: // Engineer: // // Design Name: // …

【浪漫 罗盘时钟 Js、css实现(附源代码) 美化版本】,前端面试必问的HashMap

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

vue简单使用三(class样式绑定)

目录 对象的形式绑定&#xff1a; 数组的形式绑定&#xff1a; 内联样式Style 对象的形式绑定&#xff1a; 可以看到class中有两个值 数组的形式绑定&#xff1a; 可以看到也有两个值 内联样式Style style样式设置成功 完整代码&#xff1a; <!DOCTYPE html> <html…

EasyImage2.0 简单图床开源 多功能 简单易用图床系统源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 支持API 支持仅登录后上传 支持设置图片质量 支持压缩图片大小 支持文字/图片水印 支持设置图片指定宽/高 支持上传图片转换为指定格式 支持限制最低宽度/高度上传 支持上传其他文件格…

攻防世界---misc---适合作为桌面

1.下载附件&#xff0c;是一张图片 2.用Stegsolve打开&#xff0c;打开图片一直点击下面的“>”&#xff0c;知道看到二维码 3.用QR Research解码&#xff0c;得到一串十六进制 4.用winhex转为pyc文件&#xff0c;先把十六进制内容存放在.txt文本中&#xff0c;然后用winhex…

(处理流)转换流与对象流

1.字符编码与解码. (1). 字符编码 : 将字符&#xff0c;字符串&#xff0c;字符数组------&#xff1e; 字节&#xff0c;字节数组. (2). 字节&#xff0c;字节数组------&#xff1e;字符&#xff0c;字符串&#xff0c;字符数组. 如果希望程序在读取文件时(也就是解码)不…

OpenHarmony开发实例:【分布式游戏鉴权应用】

1.介绍 本文将介绍分布式游戏鉴权应用。操作过程为&#xff1a; 设备A点击“开始游戏”按钮&#xff0c;开始搜索周边设备。 设备A显示周边设备&#xff0c;点击设备B并发起连接请求&#xff0c;远程拉起设备B的FA。 设备B收到请求后&#xff0c;选择是否允许“开启游戏”。…

《R语言与农业数据统计分析及建模》学习——数据读入

一、工作目录 # 获取当前工作目录 getwd()# 改变工作目录为指定路径下的文件夹 # 注意工作目录的表达方式 setwd(D:/R_class) setwd(D:\\R_class) 二、文件路径 读取文件中的数据首先要确定文件路径&#xff0c;如果文件不在工作目录下&#xff0c;则必须使用绝对路径 1、文…

STL —— stack、queue

博主首页&#xff1a; 有趣的中国人 专栏首页&#xff1a; C专栏 目录 1. 容器适配器 2. 栈的模拟实现 3. 队列的模拟实现 4. 双端队列deque 4.1 deque的原理介绍 4.2 deque的缺陷 4.3 为什么选择deque作为stack和queue的底层默认容器 本篇文章主要讲解 stack 和 queue …

MDK-ARM Keil5.38 下载安装环境搭建

一、keil软件介绍 KEIL是公司的名称&#xff0c;有时候也指KEIL公司的所有软件开发工具&#xff0c;目前2005年Keil由ARM公司收购&#xff0c;成为ARM的公司之一。 MDK&#xff08;Microcontroller Development Kit&#xff09; 也称MDK-ARM、KEIL MDK、RealView MDK、KEIL For…

IDEA 设置类注释模板作者、日期、描述等信息(推荐标准!)

idea注释模版配置 idea作为越来越多程序员使用的开发工具&#xff0c;平时的代码注释也非常的关键&#xff0c;类上注释和方法上注释每次换电脑或者新同事入职都要统一修改&#xff0c;找了网上好多教程都写的乱七八糟的啥都有&#xff0c;为方便统一就自己写一个操作方法&…

【yolov5小技巧(2)】---将yolov5中的特征图以热力图的方式进行可视化

文章目录 &#x1f680;&#x1f680;&#x1f680;前言一、1️⃣ 将特征图可视化的文章CFPNet二、2️⃣yolov5自带的特征图可视化工具三、3️⃣如何将特征图转换成热力图 &#x1f440;&#x1f389;&#x1f4dc;系列文章目录 【yolov5小技巧(1)】—可视化并统计目标检测中的…

Leetcode二叉树刷题

给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true public boolean isSymmetric(TreeNode root) {if(rootnull)return true;return compare(root.left,root.right);}public boole…