iTOP4412裸机 UART编程

一、串口通信的基本原理
串口通信的基本原理编辑
串口在嵌入式系统当中是一类重要的数据通信接口,其本质功能是作为 CPU 和串行设备间的编码转换器。当数据从 CPU 经过串行端口发送出去时,字节数据转换为串行的位;在接收数据时,串行的位被转换为字节数据。应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。典型地,串口用于 ASCII 码字符的传输。通信使用3根线完成:(1)地线,(2)发送数据线,(3)接收数据线。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通行的端口,这些参数必须匹配:波特率是一个衡量通信速度的参数,它表示每秒钟传送的 bit 的个数;数据位是衡量通信中实际数据位的参数,当计算机发送一个信息包,标准的值是 5,7 和 8 位。如何设置取决于你的需求;停止位用于表示单个包的最后一位,典型的值为 1,1.5和 2 位,停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会;奇偶校验位是串口通信中一种简单的检错方式,有四种检错方式——偶、奇、高和低,也可以没有校验位。

二、iTOP4412串口的原理图
在这里插入图片描述
在这里插入图片描述
配置串口之前首先应配置时钟树 因为波特率的计算需要知道时钟频率

三、UART时钟配置
在这里插入图片描述
在这里插入图片描述
从上图可知UART在PERI-L模块中 如果要PERI-L则需要先配置DMC时钟然后在配置左总线时钟
在这里插入图片描述
由上图可知PERIL时钟频率的来源为SCKLmpll,但是SCKLmpll的时钟频率又是来自哪里呢?在这里插入图片描述
根据该图可知SCLKmpll的时钟频率来自MPLL那么我们还需要配置MPLL MPLL时钟频率为800HZ

DRAM, system bus clocks, and other peripheral clocks like audio IPs, and SPI use MPLL and EPLL
DRAM,系统总线时钟以及其他外围设备时钟(如音频IP和SPI)使用MPLL和EPLL
根据这个描述 可以知道 UART使用的是MPLL和EPLL作为时钟输入源
We recommend using 24 MHz input clock source for APLL, MPLL, EPLL, and VPLL
我们建议为APLL,MPLL,EPLL和VPLL使用24 MHz输入时钟源。
而MPLL的时钟输入源为24MHZ源晶振 这显然是不足的
根据这个表中的信息 设置 P M S 便可以 将MPLL调频至指定值
根据这个表中的信息 设置 P M S 便可以 将MPLL调频至指定值

找到相关相关寄存器
接下来就是要找到需要配置的寄存器即可
因为需要配置的是UART 先从最下游开始依次找到上游 然后再由上游向下游依次配置
在这里插入图片描述
需要配置各个串口需要设置 PERIL中的分频器 UART的时钟频率来自 SCLKMPLL_UAER_T
在这里插入图片描述
而SCLKMPLL_UAER_T 的时钟源来自SCLKMPLL
在这里插入图片描述

配置寄存器

1、首先是将MPLL升频至800MHz 需要配置的寄存器

在这里插入图片描述
在这里插入图片描述
下面是计算方法 我们只需要根据上面的表中配置手册中推荐的值即可 即将MPLL_CON0 (0x10040108) =
0x80640300
即可

2、接下来是配置SCLKmpll
在这里插入图片描述
由于SCLKmpll的时钟源来自 DMC时钟树下 则需要配置的寄存器为
在这里插入图片描述
在这里插入图片描述
即 将 CLK_SRC_DMC 0x10040200 = 0x00000100 即可
在这里插入图片描述

接下来便是选定SCLKMPLL作为PERIL的时钟源 该模块在TOP时钟树下
需要配置的寄存器为在这里插入图片描述
CLK_SRC_TOP1 0x1003C214 = 0x00001000 选定SCLKMPLL作为时钟源
在这里插入图片描述
配置 UART 时钟 UART时钟源为 SCLKMPLL_USER-T 和 SCLKMPLL时钟频率相同都为800MHz 再经过DIVuart 分频器 将800MHz的时钟频率8分频为100MHz
涉及到的寄存器为
在这里插入图片描述
设置UATR的时钟源
0x1003C250 = 0x66666
在这里插入图片描述
设置分频器为8分频 分别作用于UART
0x1003C550 = 0x77777
在这里插入图片描述
设置SCL_SRC_PERIL0 0x1003C250 = 0x66666
在这里插入图片描述
设置分频比为8
CLK_DIV_PERIL0 0x1003C550 = 0x77777
时钟配置完毕

接下来进行UART配置
UART初始化

  1. 数据格式控制

     ULCON:8bit、停止位、奇偶校验  
    
  2. 整个uart控制器的控制

       UCON:
    
  3. 配置波特率

    UBRDIV 
    UDIVSLOT
    

UART接收

  1. 数据收发缓存器

    UTXH
    URXH
    
  2. 数据收发的状态

UTRSTAT   specifies Tx/Rx status  指定transmit/receive的状态

串口配置相对简单查看芯片手册即可

源码
UART.h

#ifndef __UART_H
#define __UART_H

union br_rest {
	unsigned short	slot;		/* udivslot */
	unsigned char	value;		/* ufracval */
};

struct s5p_uart {
	unsigned int ulcon;
	unsigned int ucon;
	unsigned int ufcon;
	unsigned int umcon;
	unsigned int utrstat;
	unsigned int uerstat;
	unsigned int ufstat;
	unsigned int umstat;
	unsigned char utxh;
	unsigned char res1[3];
	unsigned char urxh;
	unsigned char res2[3];
	unsigned int ubrdiv;
	union br_rest rest; 
	unsigned char res3[0xffd0];
};
/*GPIO*/
#define GPA1CON					(*(volatile int *) 0x11400020)
#define GPADAT					(*(volatile int *) 0x11400024)
/*uart*/
#define UART1_BASE				(*(volatile int *) 0x13820000)
#define UART1_ULCON				(*(volatile int *) 0x13820000)
#define UART1_UCON				(*(volatile int *) 0x13820004)
#define UART1_DIV				(*(volatile int *) 0x13820028)
#define UART1_UFRACVAL			(*(volatile int *) 0x1382002C)
#define UTXH					(*(volatile int *) 0x13820020)
#define URXH					(*(volatile int *) 0x13820024)
#define UTRSTAT					(*(volatile int *) 0x13820010)
/*MPLL*/
#define CLK_SRC_DMC				(*(volatile int *) 0x10040200)
#define MPLL_CON0				(*(volatile int *) 0x10040108)
#define CLK_SRC_TOP1			(*(volatile int *) 0x1003C214)
//uart clock 
#define CLK_DIV_PERIL0			(*(volatile int *) 0x1003C550)
#define CLK_SRC_PERIL0			(*(volatile int *) 0x1003C250)

void clock(void);
void uart(void);
void myput(char c);
void mystring(char *str);
#endif


start.S

.global _start
.global main
_start:
	bl		main
	.end

uart.c

#include"UART.h"
#include"cpu_io.h"
#include"led.h"

void clock(void)
{
	
	// 设置MPLL 
	CLK_SRC_DMC = 0x01000; //配置MUXMPLL 使用FOUT
	MPLL_CON0 =	0x80640300; // M 100 P 3 S 0;
	CLK_SRC_TOP1 = 0x01000; 
	CLK_SRC_PERIL0 = 0x66666;
	CLK_DIV_PERIL0 = 0x77777;
}
void uart(void)
{
	GPA1CON = 0x00000022; //设置GPIO 
	/*	串口初始化 */
	UART1_ULCON = 0x00000003;
	UART1_UCON = 0x00000005;// 设置接收和发送模式为中断或轮询 
	UART1_DIV = 53;
	UART1_UFRACVAL = 4;

}
/*设置receive transmits buff*/

void myput(char c)
{
	/*
		等待当前发送完成
		然后再发送下次的数据
	*/
	while (!((UTRSTAT) & (0x1<<2))); //第二位为1的时候表示为空  为0 表示非空 
	UTXH = c;
}
void mystring(char *str)
{
	while(*str)
	{
		myput(*str);
		str++;
	}
}

led.c

/*************************************************************************
    > File Name: led.c
    > 作者:YJK 
    > Mail: 745506980@qq.com 
    > Created Time: 2020年09月19日 星期六 18时28分16秒
 ************************************************************************/

#include"led.h"

void desplay(void)
{
	volatile int x = 0xFFFF;
	while (x--);
}
void led(void)
{
		GPL2CON = 0x1;
		GPK1CON = 0x10;  /*设置为输出模式*/
/*		while(1)
		{
			GPL2DAT = 0x1;
			GPK1DAT = 0x2;
			desplay();	
			GPL2DAT = 0;
			GPK1DAT = 0;		
			desplay();
		}	*/
		GPL2DAT = 0x1;
		GPK1DAT = 0x2;
}

main.c

/*************************************************************************
    > File Name: main.c
    > 作者:YJK 
    > Mail: 745506980@qq.com 
    > Created Time: 2020年09月04日 星期五 17时53分51秒
 ************************************************************************/

#include"UART.h"
#include"led.h"
int main(int argc,char *argv[])
{
	clock();
	uart();
	myput('h');
	myput('h');
	mystring("hello world\n");	
	led();
	return 0;
}

map.lds

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)

SECTIONS
{
	. = 0x0;

	. = ALIGN(4); 
	.text	:
	{
		start.o
		*(.text)
	}
	. = ALIGN(4);
	.rodata	:
	{
		*(.rodata)
	}
	. = ALIGN(4);
	.data	:
	{
		*(.data)
	}
	. = ALIGN(4);
	.bss	:
	{
		*(.bss)
	}
	

}

mk4412.c

/*************************************************************************
    > File Name: mk4412.c
    > 作者:YJK 
    > Mail: 745506980@qq.com 
    > Created Time: 2020年09月21日 星期一 09时24分15秒
 ************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUFFER_SIZE (8 * 1024)
#define HEADER_SIZE (16)

int main(int argc, char *argv[])
{
	FILE *fp;
	unsigned char buffer[BUFFER_SIZE];
	unsigned char header[HEADER_SIZE];
	unsigned int checksum, count;
	int i, len;

	if (argc != 2) {
		printf("Usage: mk4412 <file>\n");
		return -1;
	}

	fp = fopen(argv[1], "r+b");
	if (fp == NULL) {
		printf("Can not open file '%s'\n", argv[1]);
		return -1;
	}

	fseek(fp, 0L, SEEK_END);
	len = ftell(fp);
	count = (len < BUFFER_SIZE) ? len : BUFFER_SIZE;

	fseek(fp, 0L, SEEK_SET);
	memset(buffer, 0, sizeof(buffer));
	if (fread(buffer, 1, count, fp) != count) {
		printf("Can't read %s\n", argv[1]);
		fclose(fp);
		return -1;
	}

	for (i = 16, checksum = 0; i < count; i++) {
		checksum += buffer[i] & 0xff;
	}

	memset(header, 0, sizeof(header));

	header[3] = (0x1f >> 24) & 0xff;
	header[2] = (0x1f >> 16) & 0xff;
	header[1] = (0x1f >> 8) & 0xff;
	header[0] = (0x1f >> 0) & 0xff;

	header[7] = (checksum >> 24) & 0xff;
	header[6] = (checksum >> 16) & 0xff;
	header[5] = (checksum >> 8) & 0xff;
	header[4] = (checksum >> 0) & 0xff;

	header[0] ^= 0xbc;
	header[1] ^= 0xca;
	header[2] ^= 0xba;
	header[3] ^= 0xcb;
	header[4] ^= 0xcb;
	header[5] ^= 0xce;
	header[6] ^= 0xcd;
	header[7] ^= 0xdf;
	header[8] ^= 0xb7;
	header[9] ^= 0xba;
	header[10] ^= 0xbe;
	header[11] ^= 0xbb;
	header[12] ^= 0xba;
	header[13] ^= 0xad;
	header[14] ^= 0xdf;
	header[15] ^= 0xdf;

	for (i = 1; i < HEADER_SIZE; i++) {
		header[i] ^= header[i - 1];
	}

	fseek(fp, 0L, SEEK_SET);
	if (fwrite(header, 1, sizeof(header), fp) != sizeof(header)) {
		printf("Write header error %s\n", argv[1]);
		fclose(fp);
		return -1;
	}

	fclose(fp);

	printf("The checksum is 0x%08x for %ld bytes [0x%lx ~ 0x%x]\n",
	       checksum, (count - sizeof(header)), sizeof(header), (count - 1));
	return 0;
}

Makefile

#######################################################################
# File Name: Makefile
# 作者:YJK 
# mail: 745506980@qq.comc
# Created Time: 20200917日 星期四 142310秒
#########################################################################
#    $^ 当前规则中的所有依赖
#    $< 当前规则中的第一个依赖
#    $@ 当前规则中触发命令生成的目标
#    @ 不把执行的信息打印到显示屏上
#工程Makefile  



#define var 定义变量 
#.c ---- .o ------ build(elf文件)------build.bin 
TARGET := uart.bin
BUILD  := uart
ENV_ 	?= SD#?=如果不指定 则按默认方式  
COBJS	+= main.o#+=    累加 
COBJS	+= uart.o led.o
COBJS	+= start.o 
CROSS_COMPILE := arm-none-linux-gnueabi-
#工具集 
CC	:= $(CROSS_COMPILE)gcc
LD	:= $(CROSS_COMPILE)ld#链接器
OBJCOPY	:= $(CROSS_COMPILE)objcopy#文件格式的转换工具  
SDTOOLS := ./mk4412 
#编译选项 

CFLAGS 	+= -Wall  #编译时的选项 
#CFLAGS	+= -I/usr/local/arm/opt/FriendlyARM/toolschain/4.4.3/include/     #寻找include 头文件的选项  -I/include路径 

#查看启动方式  
LDFLAGS += -Tmap.lds
#LDFLAGS += $(call lmZ-option, --no-dynamic-linker)
ifeq ($(ENV_),SD)
LDFLAGS += -Ttext=0x02021400
else 
LDFLAGS += -Ttext=0x20000000
endif 

#链接脚本 
#1、概念   告诉链接器如何工作的一个文本文档  
#1.o 2.o 3.o ---->build  
#2 、要素
 	# 1、哪一个.o放到代码段的起始位置
	#连接器没有指定的方式   需要使用连接脚本

	# 2、所有的.o放到哪个基地址上 
	#方式  ld -Ttext=xxxx   简单链接指定了代码段的基地址 代码段 数据段等是连续的
	#代码段、数据段不连续的方式   使用 .lds文件

#  	

#Way  方法  

all:$(TARGET)
ifeq ($(ENV_), RAM)
$(TARGET):$(BUILD)
	$(OBJCOPY) -O binary $^ $@
else 
$(TARGET):$(BUILD)
	$(OBJCOPY) -O binary $^ $@
#生成一个临时文件  因为以SD卡启动需要在头部增加一个四字节的检测位  i
	$(SDTOOLS) $@ 
endif 
$(BUILD):$(COBJS)
	$(LD) $(LDFLAGS) $^ -o $@ 

%.o:%.c   #任意的.c 想生成任意的.o  使用的是下面的规则   其中.o 文件名是相应的.c文件名 
	$(CC) -c $< -o $@ $(CFLAGS)
%.o:%.S
	$(CC) -c $< -o $@ $(CFLAGS)

clean:
	rm $(BUILD) *.o $(TARGET)  

flash:
	dd if=/dev/zero of=/dev/sdb bs=512 seek=1 iflag=dsync oflag=dsync count=2048
#	dd if=./E4412_N.bl1.SCP2G.bin of=/dev/sdb bs=512 seek=1 iflag=dsync oflag=dsync
	dd if=./$(TARGET) of=/dev/sdb bs=512 seek=1 iflag=dsync oflag=dsync



install:


编译–烧录
make
在这里插入图片描述
make flash 烧录到SD卡
在这里插入图片描述
上电
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
itop4412上移植SSH,你可以按照以下步骤进行操作: 1. 首先,将SSH源代码拷贝到itop4412的开发环境中。你可以使用SCP命令将源代码从本地计算机复制到itop4412上的指定目录。例如,将源代码复制到itop4412的`/home/project/ssh-arm/openssh-4.6p1`目录下: ```shell scp /path/to/openssh-4.6p1.tar.gz root@itop4412:/home/project/ssh-arm/ ``` 2. 解压源代码文件。在itop4412上的开发环境中,使用以下命令解压源代码文件: ```shell tar -zxvf openssh-4.6p1.tar.gz ``` 3. 进入解压后的源代码目录: ```shell cd openssh-4.6p1 ``` 4. 配置编译选项。运行以下命令以配置SSH的编译选项: ```shell ./configure --host=arm-linux-gnueabihf --prefix=/usr/local/ssh ``` 这里的`--host`选项指定了目标平台为arm-linux-gnueabihf,`--prefix`选项指定了安装目录为`/usr/local/ssh`。 5. 编译源代码。运行以下命令以编译SSH源代码: ```shell make ``` 6. 安装SSH。运行以下命令以将编译后的SSH安装到指定目录: ```shell make install ``` 这将把SSH安装到`/usr/local/ssh`目录下。 7. 配置SSH服务器。在itop4412上的开发环境中,编辑SSH服务器的配置文件`/usr/local/ssh/etc/sshd_config`,根据你的需求进行配置。 8. 启动SSH服务器。运行以下命令以启动SSH服务器: ```shell /usr/local/ssh/sbin/sshd ``` 现在,你已经成功在itop4412上移植了SSH,并启动了SSH服务器。你可以使用SSH客户端连接到itop4412并进行远程操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值