ITOP4412裸機程式設計-串列埠驅動
阿新 • • 發佈:2018-11-07
文章目錄
前言:
看過我文章的小夥伴有的可能會有疑問,為什麼用匯編,用C語言不好嗎?我在這裡說明一下,因為後面可能要移植UBoot最新的程式,而UBoot的程式在最初的一段是用匯編寫的,所以我們這裡也用匯編寫,後期移植UBoot就很方便了。燒錄SD的指令碼和第一章點亮LED燈的一樣,這裡不再貼出來了,而是直接用了。
原理分析:
在STM32微控制器裡,在編寫驅動前做的一件很重要的事情就是時鐘樹配置,這裡串列埠驅動也是,要先配置時鐘樹才能配置串列埠,不然波特率無法計算。
從上面圖可以看出,配置時鐘樹要先配置DMC的時鐘,之後在選擇左右匯流排。
從上面的圖片可以看出,UART掛載在PERI-L時鐘分支下面。
由上面圖可以看出,先配置SCLKmpll時鐘來源,經過鎖相環電路,分頻電路最終到達PERIL,而UART就掛載在這個時鐘分支下面,有的小夥伴會問,那幹嘛配置DMC,請看下圖。
核心的時鐘樹下面藍色部分有個鎖相環,這個鎖相環決定了SCLKmpll時鐘的來源,而前面還有一個MPLL配置電路,不屬於該核心。而鎖相環和DMC在一個時鐘樹中,所以後面需要配置這個鎖相環在DMC相關的暫存器中。這裡還有一個問題,就是FOUTmpll怎麼會配置成的800Mhz,外部時鐘來源是24Mhz的有源晶振。
從上述圖片可以看出來,MPLL_CON0暫存器可以配置FOUT的值,它的值決定於下面的FOUT公式,而這個公式和MPS的設定有關,而從上面MPS表可以查得,P=3,M=100,S=0時FOUT的值就是800了。
OK!總結一下配置的流程:
先配置MPLL_CON0暫存器讓FOUT的值為800,在配置CLK_SRC_DMC暫存器使鎖相環選定FOUTmpll為時鐘來源,再配置CLK_SRC_TOP1暫存器使MUXmpll_ctrl_user_T鎖相環選定SCLKmpll為時鐘來源,再配置CLK_SRC_PERIL0暫存器使時鐘作用於想用的UART,再配置CLK_DIV_PERIL0暫存器使DIVACLK_100把MPLL的8分頻後作用於對應的UART,時鐘配置到這裡就結束了。之後再設定UART的觸發方式,資料格式,波特率等就簡單了。這裡不再敘述UART的配置方法,根據原始碼去三星的手冊中查暫存器即可。
原始碼:
新建資料夾及檔案
mkdir uart
cd uart
touch main.S exynos4412.h uart.lds Makefile
修改main.S
#include "exynos4412.h"
.global _start
.word 0x2000
.word 0x0
.word 0x0
.word 0x0
_start:
ldr r10, =0x1002330c
ldr r11, [r10]
orr r11, r11,#0x300
str r11, [r10]
ldr r10, =0x11000c08
ldr r11, =0x0
str r11, [r10]
ldr r10, =GPA1CON
ldr r11, =0x222222
str r11, [r10]
ldr r10, =MPLL_CON0
ldr r11, =0x80640300
str r11, [r10]
ldr r10, =CLK_SRC_DMC
ldr r11, =0x00011000
str r11, [r10]
ldr r10, =CLK_SRC_TOP1
ldr r11, =0x01111000
str r11, [r10]
ldr r10, =CLK_SRC_PERIL0
ldr r11, =0x66666
str r11, [r10]
ldr r10, =CLK_DIV_PERIL0
ldr r11, =0x777777
str r11, [r10]
ldr r10, =UFCON2
ldr r11, =0x111
str r11, [r10]
ldr r10, =ULCON2
ldr r11, =0x3
str r11, [r10]
ldr r10, =UCON2
ldr r11, =0x3c5
str r11, [r10]
ldr r10, =UBRDIV2
ldr r11, =0x35
str r11, [r10]
ldr r10, =UFRACVAL2
ldr r11, =0x4
str r11, [r10]
ldr r10, =UTXH2
ldr r11, =0x55
str r11, [r10]
ldr r11, =0x61
str r11, [r10]
ldr r11, =0x72
str r11, [r10]
ldr r11, =0x74
str r11, [r10]
ldr r11, =0xA
str r11, [r10]
ldr r11, =0xD
str r11, [r10]
loop:
ldr r10, =GPL2CON
mov r11, #(0x01<<0)
str r11, [r10]
ldr r10, =GPL2DAT
mov r11, #0x01
str r11, [r10]
b loop
修改exynos4412.h
#ifndef EXYNOS4412_H
#define EXYNOS4412_H
#define GPX1CON (0x11000000+0x0c20)
#define GPX1DAT (0x11000000+0x0c24)
#define GPX1PUD (0x11000000+0x0c28)
#define GPX1DRV (0x11000000+0x0c2c)
#define GPK1CON (0x11000000+0x0060)
#define GPK1DAT (0x11000000+0x0064)
#define GPK1PUD (0x11000000+0x0068)
#define GPK1DRV (0x11000000+0x006c)
#define GPL2CON (0x11000000+0x0100)
#define GPL2DAT (0x11000000+0x0104)
#define GPL2PUD (0x11000000+0x0108)
#define GPL2DRV (0x11000000+0x010c)
//uart
// GPIO
#define GPA1CON (0x11400020)
// MPLL
#define MPLL_CON0 (0x10040108)
#define CLK_SRC_DMC (0x10040200)
#define CLK_SRC_TOP1 (0x1003C214)
// system clock
#define CLK_SRC_PERIL0 (0x1003C250)
#define CLK_DIV_PERIL0 (0x1003C550)
// UART
#define UFCON2 (0x13820008)
#define ULCON2 (0x13820000)
#define UCON2 (0x13820004)
#define UBRDIV2 (0x13820028)
#define UFRACVAL2 (0x1382002c)
#define UTXH2 (0x13820020)
#define URXH2 (0x13820024)
#define UTRSTAT2 (0x13820010)
#endif
修改Makefile
CROSS_COMPILE = arm-linux-gnueabihf-
%.o : %.S
$(CROSS_COMPILE)gcc -o [email protected] $< -c
%.o : %.c
$(CROSS_COMPILE)gcc -o [email protected] $< -c
.PHONY: all
all : uart.elf
uart.elf : main.o uart.lds
$(CROSS_COMPILE)ld -T uart.lds -o uart.elf $^
$(CROSS_COMPILE)objcopy -O binary uart.elf uart.bin
$(CROSS_COMPILE)objdump -D uart.elf > uart.dis
.PHONY : clean
clean:
rm -rf *.o *.elf *.bin *.dis
修改uart.lds
SECTIONS
{
. = 0x02023400;
.text : {
main.o
* (.text)
}
.rodata ALIGN(4) : {
* (.rodata*)
}
.data ALIGN(4) : {
* (.data*)
}
.bss ALIGN(4) : {
* (.bss)
* (COMMON)
}
}
修改完上訴檔案使用指令make生成uart.bin下面要用到
燒錄SD卡:
我這裡的SD卡的裝置節點是sdb,請根據自己的實際情況改正後燒錄
cd sd_fuse/itop4412
./sd_fusing.sh /dev/sdb ../../uart.bin
現象:
這裡現象就不發圖片了,現象就是連線串列埠之後,串列埠助手會顯示Uart四個字母,開發板有一個LED燈亮。如果有疑問,請加群討論。
原始碼獲取:
可以加入群聊:667039215找群主獲取
CSDN獲取:uart壓縮包
github下載:git clone https://github.com/HOU1354696096/ITOP4412.git