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

server/2024/9/23 11:19:29/

我要成为嵌入式高手之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.ppmy.cn/server/8838.html

相关文章

WP-AutoPostPro 汉化版: WordPress自动采集发布插件 WordPress文章采集

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 WP-AutoPostPro 是目前最好用的WordPress自动采集发布插件&#xff0c;最大的特点是可以采集来自于任何网站的内容并自动发布到你的WordPress站点。真正做到可以采集任何网站的内容并…

C语言 | Leetcode C语言题解之第44题通配符匹配

题目&#xff1a; 题解&#xff1a; bool allStars(char* str, int left, int right) {for (int i left; i < right; i) {if (str[i] ! *) {return false;}}return true; } bool charMatch(char u, char v) { return u v || v ?; };bool isMatch(char* s, char* p) {in…

element UI 走马灯 initial-index动态赋值 不生效问题

图片列表点击展示大图&#xff0c;点开不是当前的图片 initial-index属性动态赋值不生效 解决方法&#xff1a; 1.设置initial-index初始值为null initialIndex:null2.设置走马灯轮播数组初始化为[] imgList:[]3.点击图片获取图片的索引&#xff0c;赋值给initialIndex&#x…

HarmonyOS-静态库(SDK)的创建和使用

文章目录 一、静态库&#xff08;SDK&#xff09;二、创建静态库1.新建静态库模块2. 开发静态库内容3. 编译静态库 三、使用静态库1. 配置项目依赖2. 在应用中使用静态库3. 注意事项 四、打包错误1. library引用本地har包错误 一、静态库&#xff08;SDK&#xff09; 在Harmon…

Java27

FileOutputStream类 文件字节输出流FileOutputStream类是OutputStream类的子类write()方法顺序地向输出流写入字节&#xff0c;直到关闭输出流。 使用FileOutputStream类&#xff0c;操作本地文件地字节输出流&#xff0c;可以把程序中的数据写到本地文件中&#xff0c;其中写…

Python设计模式

1.工厂模式 工厂模式实现了创建者和调用者的分离&#xff0c;使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制。 class CarFactory:def createCar(self,brand):if brand "奔驰":return Benz()elif brand "宝马":return BMW()elif brand …

Leetcode 225:用队列实现栈

请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。int pop() 移除并返回栈顶元素。int to…

Linux下SPI设备驱动实验:实现SPI发送/接收数据的函数

一. 简介 前面文章介绍了SPI设备数据收发处理流程&#xff0c;后面几篇文章实现了SPI设备驱动框架&#xff0c;加入了字符设备驱动框架代码。文章如下&#xff1a; SPI 设备驱动编写流程&#xff1a;SPI 设备数据收发处理流程中涉及的结构体与函数-CSDN博客 SPI 设备驱动编写…