當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀] 實(shí)驗(yàn)的目的:設(shè)置系統(tǒng)時(shí)鐘,并在串口上輸入一個(gè)字符,單板接收后將它的ASCII值加1后,從串口輸出。實(shí)驗(yàn)的源程序:/*************************************************************************s3c24xx

實(shí)驗(yàn)的目的:
設(shè)置系統(tǒng)時(shí)鐘,并在串口上輸入一個(gè)字符,單板接收后將它的ASCII值加1后,從串口輸出。

實(shí)驗(yàn)的源程序:
/*************************************************************************
s3c24xx.h
*************************************************************************/
/* WOTCH DOG register */
#define WTCON (*(volatile unsigned long *)0x53000000)


/* SDRAM regisers */
#define MEM_CTL_BASE 0x48000000
#define SDRAM_BASE 0x30000000


/* NAND Flash registers */
#define NFCONF (*(volatile unsigned int *)0x4e000000)
#define NFCMD (*(volatile unsigned char *)0x4e000004)
#define NFADDR (*(volatile unsigned char *)0x4e000008)
#define NFDATA (*(volatile unsigned char *)0x4e00000c)
#define NFSTAT (*(volatile unsigned char *)0x4e000010)


/*GPIO registers*/
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)


#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPFUP (*(volatile unsigned long *)0x56000058)


#define GPGCON (*(volatile unsigned long *)0x56000060)
#define GPGDAT (*(volatile unsigned long *)0x56000064)
#define GPGUP (*(volatile unsigned long *)0x56000068)


#define GPHCON (*(volatile unsigned long *)0x56000070)
#define GPHDAT (*(volatile unsigned long *)0x56000074)
#define GPHUP (*(volatile unsigned long *)0x56000078)


/*UART registers*/
#define ULCON0 (*(volatile unsigned long *)0x50000000)
#define UCON0 (*(volatile unsigned long *)0x50000004)
#define UFCON0 (*(volatile unsigned long *)0x50000008)
#define UMCON0 (*(volatile unsigned long *)0x5000000c)
#define UTRSTAT0 (*(volatile unsigned long *)0x50000010)
#define UTXH0 (*(volatile unsigned char *)0x50000020)
#define URXH0 (*(volatile unsigned char *)0x50000024)
#define UBRDIV0 (*(volatile unsigned long *)0x50000028)


/*interrupt registes*/
#define SRCPND (*(volatile unsigned long *)0x4A000000)
#define INTMOD (*(volatile unsigned long *)0x4A000004)
#define INTMSK (*(volatile unsigned long *)0x4A000008)
#define PRIORITY (*(volatile unsigned long *)0x4A00000c)
#define INTPND (*(volatile unsigned long *)0x4A000010)
#define INTOFFSET (*(volatile unsigned long *)0x4A000014)
#define SUBSRCPND (*(volatile unsigned long *)0x4A000018)
#define INTSUBMSK (*(volatile unsigned long *)0x4A00001c)


/*external interrupt registers*/
#define EINTMASK (*(volatile unsigned long *)0x560000a4)
#define EINTPEND (*(volatile unsigned long *)0x560000a8)


/*clock registers*/
#define LOCKTIME (*(volatile unsigned long *)0x4c000000)
#define MPLLCON (*(volatile unsigned long *)0x4c000004)
#define UPLLCON (*(volatile unsigned long *)0x4c000008)
#define CLKCON (*(volatile unsigned long *)0x4c00000c)
#define CLKSLOW (*(volatile unsigned long *)0x4c000010)
#define CLKDIVN (*(volatile unsigned long *)0x4c000014)


/*PWM & Timer registers*/
#define TCFG0 (*(volatile unsigned long *)0x51000000)
#define TCFG1 (*(volatile unsigned long *)0x51000004)
#define TCON (*(volatile unsigned long *)0x51000008)
#define TCNTB0 (*(volatile unsigned long *)0x5100000c)
#define TCMPB0 (*(volatile unsigned long *)0x51000010)
#define TCNTO0 (*(volatile unsigned long *)0x51000014)


#define GSTATUS1 (*(volatile unsigned long *)0x560000B0)



/********************************************************************************
serial.c
********************************************************************************/

#include "s3c24xx.h"
#include "serial.h"


#define TXD0READY (1<<2)
#define RXD0READY (1)


#define PCLK 50000000 // init.c中的clock_init函數(shù)設(shè)置PCLK為50MHz
#define UART_CLK PCLK // UART0的時(shí)鐘源設(shè)為PCLK
#define UART_BAUD_RATE 115200 // 波特率
#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)


/*
* 初始化UART0
* 115200,8N1,無(wú)流控
*/
void uart0_init(void)
{
GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0
GPHUP = 0x0c; // GPH2,GPH3內(nèi)部上拉


ULCON0 = 0x03; // 8N1(8個(gè)數(shù)據(jù)位,無(wú)較驗(yàn),1個(gè)停止位)
UCON0 = 0x05; // 查詢(xún)方式,UART時(shí)鐘源為PCLK
UFCON0 = 0x00; // 不使用FIFO
UMCON0 = 0x00; // 不使用流控
UBRDIV0 = UART_BRD; // 波特率為115200
}


/*
* 發(fā)送一個(gè)字符
*/
void putc(unsigned char c)
{
/* 等待,直到發(fā)送緩沖區(qū)中的數(shù)據(jù)已經(jīng)全部發(fā)送出去 */
while (!(UTRSTAT0 & TXD0READY));

/* 向UTXH0寄存器中寫(xiě)入數(shù)據(jù),UART即自動(dòng)將它發(fā)送出去 */
UTXH0 = c;
}


/*
* 接收字符
*/
unsigned char getc(void)
{
/* 等待,直到接收緩沖區(qū)中的有數(shù)據(jù) */
while (!(UTRSTAT0 & RXD0READY));

/* 直接讀取URXH0寄存器,即可獲得接收到的數(shù)據(jù) */
return URXH0;
}


/*
* 判斷一個(gè)字符是否數(shù)字
*/
int isDigit(unsigned char c)
{
if (c >= '0' && c <= '9')
return 1;
else
return 0;
}


/*
* 判斷一個(gè)字符是否英文字母
*/
int isLetter(unsigned char c)
{
if (c >= 'a' && c <= 'z')
return 1;
else if (c >= 'A' && c <= 'Z')
return 1;
else
return 0;
}

/************************************************************************************
serial.h
************************************************************************************/
void uart0_init(void);
void putc(unsigned char c);
unsigned char getc(void);
int isDigit(unsigned char c);
int isLetter(unsigned char c);

/***********************************************************************************
init.c
***********************************************************************************/
/*
* init.c: 進(jìn)行一些初始化
*/


#include "s3c24xx.h"

void disable_watch_dog(void);
void clock_init(void);
void memsetup(void);
void copy_steppingstone_to_sdram(void);


/*
* 關(guān)閉WATCHDOG,否則CPU會(huì)不斷重啟
*/
void disable_watch_dog(void)
{
WTCON = 0; // 關(guān)閉WATCHDOG很簡(jiǎn)單,往這個(gè)寄存器寫(xiě)0即可
}


#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))
#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
/*
* 對(duì)于MPLLCON寄存器,[19:12]為MDIV,[9:4]為PDIV,[1:0]為SDIV
* 有如下計(jì)算公式:
* S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
* S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)
* 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
* 對(duì)于本開(kāi)發(fā)板,F(xiàn)in = 12MHz
* 設(shè)置CLKDIVN,令分頻比為:FCLK:HCLK:PCLK=1:2:4,
* FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
*/
void clock_init(void)
{
// LOCKTIME = 0x00ffffff; // 使用默認(rèn)值即可
CLKDIVN = 0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1


/* 如果HDIVN非0,CPU的總線模式應(yīng)該從“fast bus mode”變?yōu)椤癮synchronous bus mode” */
__asm__(
"mrc p15, 0, r1, c1, c0, 0n" /* 讀出控制寄存器 */
"orr r1, r1, #0xc0000000n" /* 設(shè)置為“asynchronous bus mode” */
"mcr p15, 0, r1, c1, c0, 0n" /* 寫(xiě)入控制寄存器 */
);


/* 判斷是S3C2410還是S3C2440 */
if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
{
MPLLCON = S3C2410_MPLL_200MHZ; /* 現(xiàn)在,F(xiàn)CLK=200MHz,HCLK=100MHz,PCLK=50MHz */
}
else
{
MPLLCON = S3C2440_MPLL_200MHZ; /* 現(xiàn)在,F(xiàn)CLK=200MHz,HCLK=100MHz,PCLK=50MHz */
}
}


/*
* 設(shè)置存儲(chǔ)控制器以使用SDRAM
*/
void memsetup(void)
{
volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;


/* 這個(gè)函數(shù)之所以這樣賦值,而不是像前面的實(shí)驗(yàn)(比如mmu實(shí)驗(yàn))那樣將配置值
* 寫(xiě)在數(shù)組中,是因?yàn)橐伞蔽恢脽o(wú)關(guān)的代碼”,使得這個(gè)函數(shù)可以在被復(fù)制到
* SDRAM之前就可以在steppingstone中運(yùn)行
*/
/* 存儲(chǔ)控制器13個(gè)寄存器的值 */
p[0] = 0x22011110; //BWSCON
p[1] = 0x00000700; //BANKCON0
p[2] = 0x00000700; //BANKCON1
p[3] = 0x00000700; //BANKCON2
p[4] = 0x00000700; //BANKCON3
p[5] = 0x00000700; //BANKCON4
p[6] = 0x00000700; //BANKCON5
p[7] = 0x00018005; //BANKCON6
p[8] = 0x00018005; //BANKCON7

/* REFRESH,
* HCLK=12MHz: 0x008C07A3,
* HCLK=100MHz: 0x008C04F4
*/
p[9] = 0x008C04F4;
p[10] = 0x000000B1; //BANKSIZE
p[11] = 0x00000030; //MRSRB6
p[12] = 0x00000030; //MRSRB7
}


void copy_steppingstone_to_sdram(void)
{
unsigned int *pdwSrc = (unsigned int *)0;
unsigned int *pdwDest = (unsigned int *)0x30000000;

while (pdwSrc < (unsigned int *)4096)
{
*pdwDest = *pdwSrc;
pdwDest++;
pdwSrc++;
}
}

/**********************************************************************************
head.S
**********************************************************************************/
@******************************************************************************
@ File:head.S
@ 功能:設(shè)置SDRAM,將程序復(fù)制到SDRAM,然后跳到SDRAM繼續(xù)執(zhí)行
@******************************************************************************

.extern main
.text
.global _start
_start:
Reset:
ldr sp, =4096 @ 設(shè)置棧指針,以下都是C函數(shù),調(diào)用前需要設(shè)好棧
bl disable_watch_dog @ 關(guān)閉WATCHDOG,否則CPU會(huì)不斷重啟
// bl是位置無(wú)關(guān)碼,相當(dāng)于:PCnew = PC + 偏移
// PCnew = (4+8) + 0x28 = 0x34

//ldr pc, =disable_watch_dog /* 這樣寫(xiě)將出錯(cuò) */

bl clock_init @ 設(shè)置MPLL,改變FCLK、HCLK、PCLK
bl memsetup @ 設(shè)置存儲(chǔ)控制器以使用SDRAM
bl copy_steppingstone_to_sdram @ 復(fù)制代碼到SDRAM中
ldr pc, =on_sdram @ 跳到SDRAM中繼續(xù)執(zhí)行
on_sdram:
ldr sp, =0x34000000 @ 設(shè)置棧指針
ldr lr, =halt_loop @ 設(shè)置返回地址
ldr pc, =main @ 調(diào)用main函數(shù)
halt_loop:
b halt_loop

/**************************************************************************
main.c
**************************************************************************/
#include "serial.h"


int main()
{
unsigned char c;
uart0_init(); // 波特率115200,8N1(8個(gè)數(shù)據(jù)位,無(wú)校驗(yàn)位,1個(gè)停止位)


putc('T');
putc('e');
putc('s');
putc('t');
putc(':');
putc('n');
putc('r');


while(1)
{
// 從串口接收數(shù)據(jù)后,判斷其是否數(shù)字或字母,若是則加1后輸出
c = getc();
if (isDigit(c) || isLetter(c))
putc(c+1);
}


return 0;
}

/***********************************************************************
uart.lds
************************************************************************/
SECTIONS {
. = 0x30000000;
.text : { *(.text) }
.rodata ALIGN(4) : {*(.rodata)}
.data ALIGN(4) : { *(.data) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}


/********************************************************************************
Makefile
********************************************************************************/
objs := head.o init.o serial.o main.o


uart.bin: $(objs)
arm-linux-ld -Tuart.lds -o uart_elf $^
arm-linux-objcopy -O binary -S uart_elf $@
arm-linux-objdump -D -m arm uart_elf > uart.dis

%.o:%.c
arm-linux-gcc -Wall -O2 -c -o $@ $<


%.o:%.S
arm-linux-gcc -Wall -O2 -c -o $@ $<


clean:
rm -f uart.bin uart_elf uart.dis *.o


實(shí)驗(yàn)的問(wèn)題總結(jié):
I.關(guān)于系統(tǒng)時(shí)鐘的設(shè)置,我們主要看clock_init()函數(shù)。
1>
/* 如果HDIVN非0,CPU的總線模式應(yīng)該從“fast bus mode”變?yōu)椤癮synchronous bus mode” */
__asm__( //C語(yǔ)言?xún)?nèi)嵌匯編,這段話(huà)是根據(jù)s3c2440用戶(hù)手冊(cè)上的說(shuō)明來(lái)寫(xiě)的
"mrc p15, 0, r1, c1, c0, 0n" /* 讀出控制寄存器 */
"orr r1, r1, #0xc0000000n" /* 設(shè)置為“asynchronous bus mode” */
"mcr p15, 0, r1, c1, c0, 0n" /* 寫(xiě)入控制寄存器 */
);

2>
GSTATUS1寄存器為芯片序列信號(hào),可查看s3c2440用戶(hù)手冊(cè)

3>
MPLLCON的目的是設(shè)置FCLK和Fin的倍數(shù),關(guān)于其值的設(shè)置,可以參考s3c2440用戶(hù)手冊(cè)關(guān)于PLL值選擇表

II.關(guān)于UART,我們主要分析如下:
我們主要分析serial.c文件,我們主要使用的方式是:非流控 + 非FIFO + 查詢(xún)方式。
在uart0_init()函數(shù)中,關(guān)于這幾個(gè)寄存器的配置,你可以對(duì)照s3c2440手冊(cè)進(jìn)行一一配置即可
其中,UTRSTAT0寄存器是判斷發(fā)送緩沖器或接收緩沖器中是否有數(shù)據(jù)
UTXH0為發(fā)送緩沖寄存器,我們?nèi)粝氚l(fā)送數(shù)據(jù),直接往UTXH0寄存器里邊賦值即可。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉