ARM基础--基于Exynos4412的UART和WDT实验

目录

一.UART实验

UART介绍

并行通信和串行通信介绍

波特率介绍

UART编程

WDT实验

WDT简介

WDT实验步骤


一.UART实验

UART介绍

UART是串行通信的一种协议和接口标准,全称是Universal Asynchronous Receiver/Transmitter,即通用异步收发器。UART分为发送器和接收器两部分,它们共用同一条数据线和时钟线,通过串行传输方式来实现数据的发送和接收。

UART的工作原理是将传输的数据分成一段段的数据包,每个数据包由一个起始位、8个数据位和一个或多个停止位组成。在发送端,将数据包转化为电信号信号发送出去,接收端将接收到的电信号转化为数据包。

UART的特点是数据传输速度较慢,但具有较高的可靠性和兼容性,因此在许多应用场景中仍被广泛使用。其中,常见的应用场景包括串口通信、UART通信、模拟信号转数字信号以及嵌入式系统等领域。同时,UART的实现也比较简单,可以使用各种现成的芯片和模块进行集成和开发。

并行通信和串行通信介绍

并行通信和串行通信是两种传输数据的方式。

并行通信是指同时传输多个数据位,每个数据位占用一个信号线,这些信号线在传输过程中保持同步。并行通信速度快,但需要很多信号线,对于长距离传输,信号失真和噪声等问题较为严重。常见的并行通信技术包括并行接口、总线接口、VME总线、PCI总线等。

串行通信是指逐位传输数据,每个数据位通过单个信号线传输,信号线之间不需要同步。串行通信速度相对较慢,但只需要较少的信号线,传输距离远时信号失真和噪声问题也较少。常见的串行通信技术包括RS-232、RS-422、RS-485、Ethernet、USB、HDMI等。其中,Ethernet和USB是目前使用最广泛的串行通信技术。

波特率介绍

波特率指的是每秒钟传输的比特数,也就是数据传输速率的一种度量单位。常见的波特率有1200、2400、4800、9600、19200、38400、57600、115200等,它们代表着每秒钟传输的比特数。

例如:波特率为9600,意味着每秒钟可以传输9600个比特。如果传输的数据是8位的ASCII码,每个字符需要8个比特表示,那么9600波特率每秒钟就能传输9600/8=1200个字符。

计算波特率的方法:波特率可以通过串行通信设备的配置参数设置,也可以通过以下公式计算:

波特率=数据传输速率/每个数据包中的比特数

例如:每个数据包中有8位比特,且数据传输速率为19200,那么波特率为19200/8=2400。

UART编程

#include "exynos_4412.h"
 
int main()
{
	//设置GPA端口为uart端口TX和RX
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
    // 设置uart的格式为帧格式,8位数据位 1位停止位无效验位 正常模式
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
    // 设置UATR2 的接受和发送为轮询模式
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
    // 设置UART2 的波特率为115200
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;

	while(1)
	{
		UART2.UTXH2 = 'A';
	} 
	return 0;
}
#include "exynos_4412.h"
 
void UART_Init(void)
{
    //设置GPA端口为uart端口TX和RX
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
    // 设置uart的格式为帧格式,8位数据位 1位停止位无效验位 正常模式
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
    // 设置UATR2 的接受和发送为轮询模式
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
    // 设置UART2 的波特率为115200
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}
 
void uart_send_byte(char Dat)
{	
	while(!(UART2.UTRSTAT2 & (1 << 1)));
	UART2.UTXH2 = Dat;
}
 
char uart_recv_byte(void)
{
	char Dat = 0;
	if(UART2.UTRSTAT2 & 1)
	{
		Dat = UART2.URXH2;
		return Dat;
	}
	else
    {
		return 0;
    }
}
 
void uart_send_str(char * pstr)
{
    while(*pstr != '\0')
        uart_send_byte(*pstr++);
}
 
int main()
{
    char RecDat = 0;
	UART_Init();
#if 0
    while(1)
	{
        RecDat = uart_recv_byte();
        if(RecDat == 0)
        {
        
        }
        else
        {
            RecDat = RecDat + 1;
            uart_send_byte(RecDat);
        }
	}
#endif
    while(1)
    {
        uart_send_str("Hello World\n");
    }
	return 0;
}

WDT实验

WDT简介

WDT 全称为 Watchdog Timer(看门狗定时器)。它是一种硬件定时器,在嵌入式系统中被广泛应用。WDT 的主要作用是在系统出现故障时进行恢复,防止系统崩溃或死锁。通俗来说,就像一只会定时“汪汪叫”的狗,如果系统持续工作而未出现异常,那么定时器就会被“喂狗”,定时又从头开始;如果系统出现故障或死锁,定时器就不会被“喂狗”,超时后会触发复位信号,使系统恢复到初始状态。

WDT 的工作流程通常分为以下四个步骤:

  1. 配置 WDT 定时器,确定定时时间。
  2. 启动 WDT 定时器,开始计时。
  3. 在程序的适当位置定时“喂狗”,重置 WDT 定时器的计时器。
  4. 如果 WDT 定时器超时,触发复位信号,将系统恢复到初始状态。

在实际使用 WDT 时,需要根据具体的应用场景选择适当的定时时间和定时器的重置位置,以保证系统在正常工作时不会误触发复位信号,同时在系统故障时能够及时恢复。需要注意的是,WDT 定时器的配置和使用具有一定的安全性风险,在使用 WDT 时应该慎重考虑,确保系统稳定性和安全性。

WDT实验步骤

ARM Cortex-A9处理器的WDT寄存器与其他处理器类似,但寄存器的名称和位域定义可能略有不同。下面是一个基于ARM Cortex-A9的WDT寄存器编程的示例:

首先,需要选择WDT的时钟源和定时器的计数周期。这可以通过配置WDT_MR寄存器实现。假设我们要选用CPU主时钟作为WDT的时钟源,而WDT的计数周期为2^16,那么可以这样设置:

#define WDT_MR  (*((volatile uint32_t*)0x400E1454))

WDT_MR &= 0xF0FFFFFF; // 清除时钟源和定时器周期位
WDT_MR |= 0x05000000; // 使用主时钟作为WDT时钟源
WDT_MR |= 0x00010000; // 设置WDT定时器的计数周期为2^16

接下来,需要启用WDT,并设置定时器的工作模式。这可以通过WDT_CR寄存器实现。假设我们要启用WDT,并设置定时器在超时后立即重启系统,那么可以这样设置:

#define WDT_CR  (*((volatile uint32_t*)0x400E1450))

WDT_CR |= 0x00000001; // 启用WDT
WDT_CR &= 0xFFFFFFFE; // 设置WDT定时器在超时后立即重启系统

最后,需要在程序中定时喂狗,防止WDT计时器超时。可以通过在代码中周期性地对WDT_SR寄存器写入0xA5000000,来清除计时器。这样可以使WDT定时器重新开始计时。下面是示例代码:

#define WDT_SR  (*((volatile uint32_t*)0x400E1458))

while (1) {
    WDT_SR = 0xA5000000; // 喂狗,防止WDT计时器超时
    
    // TODO: 程序正常运行的代码
}

综上所述,一个基于ARM Cortex-A9处理器的WDT寄存器编程示例的完整代码如下:

#include <stdint.h>

#define WDT_MR  (*((volatile uint32_t*)0x400E1454))
#define WDT_CR  (*((volatile uint32_t*)0x400E1450))
#define WDT_SR  (*((volatile uint32_t*)0x400E1458))

void main() {
    WDT_MR &= 0xF0FFFFFF; // 清除时钟源和定时器周期位
    WDT_MR |= 0x05000000; // 使用主时钟作为WDT时钟源
    WDT_MR |= 0x00010000; // 设置WDT定时器的计数周期为2^16
    
    WDT_CR |= 0x00000001; // 启用WDT
    WDT_CR &= 0xFFFFFFFE; // 设置WDT定时器在超时后立即重启系统
    
    while (1) {
        WDT_SR = 0xA5000000; // 喂狗,防止WDT计时器超时
        
        // TODO: 程序正常运行的代码
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值