S3C2440裸机之串口


前言

基于JZ2440开发板


一、思维导图

在这里插入图片描述

二、代码

1.uart.c

代码如下(示例):

/************************************************************************
*
* 文件名:uart.c
*
* 功能:  键盘输入字符,信息会通过串口打印在界面上
		 
		 
*
* 创建人:LiZhenhao
*
* 时间:2021年10月10日15:51:49
*
* 版本号:1.0
*
* 修改记录:无
*
************************************************************************/
#include "S3C2440.h"
#include "uart.h"

void Uart_Init() {

	/* 1、UART0的发送引脚是TXD0/GPH2,接收引脚RXD0/GPH3 */
	GPHCON &= ~( ( 3 << 4 ) | ( 3 << 6 ) );		//GPHCON的bit7~bit6 和 bit5~bit4 清零
	GPHCON |= ( ( 2 << 4 ) | ( 2 << 6) );		//GPHCON的bit7~bit6 和 bit5~bit4 都置为10

	/* 2、空闲时收发引脚为高电平,可通过给GPHUP设置为0,使能内部上拉 */
	GPHUP &= ~( 3 << 2 );						//对应的bit3~bit2位设置为0

	/*   3、设置用PCLK时钟,收发引脚为查询方式 (UCON0) */
	UCON0 = 0x05;								//UCON0的bit1~bit0 和 bit3~bit2 都设置为01 其余位为0


	/* 4、设置波特率  UBRDIV0(0x5000 0028) */
	UBRDIV0 = 26;								//UBRDIV0 = 50000000 / 115200 –1 ≈ 26

	/* 5、设置数据格式 ULCON0(0x5000 0000) */
	ULCON0 = 0x03;								//8N1:8个数据位,无校验位,1个停止位

}

//先收后发
/* 接收数据 */
unsigned char Receive_Data(void) {
	 while( !(UTRSTAT0 & ( 1 << 0 ) ) );  //等待UTRSTAT0的bit0变为1(判断是否有数据,有数据才读数据)
	return(URXH0);
}


/* 发送数据 */
void Send_Data(unsigned char data) {
	while( !(UTRSTAT0 & ( 1 << 2 ) ) );		//等待UTRSTAT0的bit2变为1的时候,表明前面已经发送完。
	UTXH0 = data;
}


void Send_Message(unsigned char* s) {
	while(*s) {
		Send_Data(*s);
		s++;
	}
}


2.main.c

代码如下(示例):

#include "main.h"


int main(int argc, char const *argv[])
{	
	unsigned char buffer;
	unsigned char s[] = "hello world!\n\r";
	Uart_Init();
	Send_Message(s);

	while(1) {
		
		buffer = Receive_Data();
		if( buffer == '\n') {
			Send_Data('\r');
		} else if( buffer == '\r') {
			Send_Data('\n');
		}
		Send_Data(buffer);
	}
	return 0;
}


3.main.h

代码如下(示例):

#ifndef __MAIN_H__
#define __MAIN_H__

#include "S3C2440.h"
#include "uart.h"

#endif


4.S3C2440.h

代码如下(示例):

#ifndef __S3C2440_H__
#define __S3C2440_H__

#define GPFCON (*(volatile unsigned int*)0x56000050)
#define GPFDAT (*(volatile unsigned int*)0X56000054)
#define GPGCON (*(volatile unsigned int*)0x56000060)
#define GPGDAT (*(volatile unsigned int*)0x56000064)

#define GPHCON (*(volatile unsigned int*)0x56000070)
#define GPHUP (*(volatile unsigned int*)0x56000078)
#define UCON0 (*(volatile unsigned int*)0x50000004)
#define UBRDIV0 (*(volatile unsigned int*)0x50000028)
#define ULCON0 (*(volatile unsigned int*)0x50000000)
#define UTRSTAT0 (*(volatile unsigned int*)0x50000010)

#define URXH0 (*(volatile unsigned char*)0x50000024)
#define UTXH0 (*(volatile unsigned char*)0x50000020)


#endif

5.uart.h

代码如下(示例):

#ifndef __UART_H__
#define __UART_H__

void Uart_Init();
unsigned char Receive_Data();
void Send_Data(unsigned char data);
void Send_Message(unsigned char* s);

#endif


6.start.S

代码如下(示例):


.text
.global _start

_start:

	/* 关闭看门狗 */
	ldr r0, =0x53000000
	ldr r1, =0
	str r1, [r0]

	/* 设置MPLL, FCLK : HCLK : PCLK = 400m : 100m : 50m */
	/* LOCKTIME(0x4C000000) = 0xFFFFFFFF */
	ldr r0, =0x4C000000
	ldr r1, =0xFFFFFFFF
	str r1, [r0]

	/* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8  */
	ldr r0, =0x4C000014
	ldr r1, =0x5
	str r1, [r0]

	/* 设置CPU工作于异步模式 */
	mrc p15,0,r0,c1,c0,0
	orr r0,r0,#0xc0000000   //R1_nF:OR:R1_iA
	mcr p15,0,r0,c1,c0,0

	/* 设置MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0) 
	 *  m = MDIV+8 = 92+8=100
	 *  p = PDIV+2 = 1+2 = 3
	 *  s = SDIV = 1
	 *  FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M
	 */
	ldr r0, =0x4C000004
	ldr r1, =(92<<12)|(1<<4)|(1<<0)
	str r1, [r0]

	/* 一旦设置PLL, 就会锁定lock time直到PLL输出稳定
	 * 然后CPU工作于新的频率FCLK
	 */
	
	

	/* 设置内存: sp 栈 */
	/* 分辨是nor/nand启动
	 * 写0到0地址, 再读出来
	 * 如果得到0, 表示0地址上的内容被修改了, 它对应ram, 这就是nand启动
	 * 否则就是nor启动
	 */
	mov r1, #0
	ldr r0, [r1] /* 读出原来的值备份 */
	str r1, [r1] /* 0->[0] */ 
	ldr r2, [r1] /* r2=[0] */
	cmp r1, r2   /* r1==r2? 如果相等表示是NAND启动 */
	ldr sp, =0x40000000+4096 /* 先假设是nor启动 */
	moveq sp, #4096  /* nand启动 */
	streq r0, [r1]   /* 恢复原来的值 */
	

	bl main

halt:
	b halt
	

效果演示

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

free(me)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值