(ARM11 S3C6410)关于裸机串口与定时器

发布时间: 2024-09-23
来源: 电子工程世界

调试MCU经常需要用串口。


裸机前后台系统,基本就是基于定时器中断。


init.s 启动代码


Mode_USR        EQU     0x10

Mode_FIQ        EQU     0x11

Mode_IRQ        EQU     0x12

Mode_SVC        EQU     0x13

Mode_ABT        EQU     0x17

Mode_UND        EQU     0x1B

Mode_SYS        EQU     0x1F


UND_Stack_Size  EQU     0x00000400

SVC_Stack_Size  EQU     0x00001000

ABT_Stack_Size  EQU     0x00000400

FIQ_Stack_Size  EQU     0x00000400

IRQ_Stack_Size  EQU     0x00001000

USR_Stack_Size  EQU     0x00001000

Heap_Size       EQU     0x00010000


I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled

F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled


Stack_Top       EQU     0x52000000    

    

    

    IMPORT main

    PRESERVE8

    AREA |VIC|,CODE,READONLY

    ENTRY

start

    mrc    p15,0,r0,c1,c0,0

    orr r0,r0,#(1<<24)

    mcr p15,0,r0,c1,c0,0

    

    LDR     R0, =Stack_Top


    MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit

    MOV     SP, R0

    SUB     R0, R0, #UND_Stack_Size


    MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit

    MOV     SP, R0

    SUB     R0, R0, #ABT_Stack_Size



    MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit

    MOV     SP, R0

    SUB     R0, R0, #FIQ_Stack_Size



    MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit

    MOV     SP, R0

    SUB     R0, R0, #IRQ_Stack_Size



    MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit

    MOV     SP, R0

    SUB     SL, SP, #USR_Stack_Size



    MSR     CPSR_c, #Mode_USR

    MOV     SP, R0

    SUB     SL, SP, #USR_Stack_Size


    ;使能IQR中断            

    MRS    R0,CPSR

      BIC    R0,R0,#0x80

    MSR    CPSR_c,R0

    

    bl main

    

    END    


6410_include.h  一些重定义类型 与宏定义。


#ifndef __DEF_H__

#define __DEF_H__


#define    FIN 12000000        //晶振频率


// 读/写寄存器数据

#define Outp32(addr, data)  (*(volatile u32 *)(addr) = (data))     

#define Outp16(addr, data)  (*(volatile u16 *)(addr) = (data))

#define Outp8(addr, data)   (*(volatile u8  *)(addr) = (data))

#define Inp32(addr)         (*(volatile u32 *)(addr))

#define Inp16(addr)         (*(volatile u16 *)(addr))

#define Inp8(addr)          (*(volatile u8  *)(addr))



typedef unsigned long       u32;

typedef unsigned short      u16;

typedef unsigned char       u8;


typedef signed long         s32;

typedef signed short        s16;

typedef signed char         s8;


#endif


uart.h 串口驱动头文件


#include '6410_include.h'


#ifndef __UART_H__

#define __UART_H__


#define    ULCON0       (0x7F005000)

#define    UCON0        (0x7F005004)  

#define    UFCON0       (0x7F005008)

#define    UMCON0       (0x7F00500C) 

#define    UBRDIV0      (0x7F005028)

#define    GPACON       (0X7F008000)

#define    GPAPUD       (0X7F008008)    

      

#define    UTRSTAT0     (*(volatile unsigned *)(0x7F005010))

#define    UTXH0        (*(volatile unsigned *)(0x7F005020))      



#define    UART_clock 66500000


#endif


void    Uart0_Init(u32 baud);

void    Uart_Putc(char ch);

void    Uart_Puts(char *str);

void    Uart_Printf(char *fmt,...);


uart.c 串口驱动


#include '6410_include.h'


#include

#include 'uart.h'


 //端口初始化;

static void Uart0_Port_Init(void)

{


    u32    uConValue;


    uConValue = Inp32(GPACON);

    uConValue = (uConValue & ~0xff) | 0x22; //配置为UART0功能;  

    Outp32(GPACON,uConValue);

             

    uConValue = Inp32(GPAPUD);            

    uConValue &= ~0xf; //低4位配置为0000,上下拉电阻除能;

    Outp32(GPAPUD,uConValue);

          


}

 

 //uart初始化;

void Uart0_Init(u32 baud)

{

    u32        pclk;

    u32        uConValue;

    u32        uTemp;

     

    pclk = UART_clock;

    Uart0_Port_Init();

     


    

    uConValue = Inp32(ULCON0);

    uConValue = (uConValue & ~0x3F) | 0x3;//配置为8位数据,1位停止位,0位校验位;

    Outp32(ULCON0,uConValue);

          

    uConValue = Inp32(UCON0);

    uConValue= (uConValue & ~0x405| 0x405); //配置为中断或轮询模式,使用pclk作为波特率;

    Outp32(UCON0,uConValue);

         

    uConValue = Inp32(UFCON0);

    uConValue = 0x0;//配置为非FIFO模式;

    Outp32(UFCON0,uConValue);

     

    uConValue = Inp32(UMCON0); 

    uConValue = 0x0;//配置为非中断,非流控模式;

    Outp32(UMCON0,uConValue);

         

    uTemp     = (int)(pclk/16/baud)- 1;

    Outp32(UBRDIV0,uTemp);//配置波特率;    

         

    Delay(10000);

 

}

 

 //单字符输出;

void Uart_Putc(char ch)

{

     if(ch == 'n')

     {

         while(!(UTRSTAT0 & 0x2));

         UTXH0 = 'r'; 

         

     }

     while(!(UTRSTAT0 & 0x2));

         UTXH0 = ch; 

}

 

 //字符串输出

void Uart_Puts(char *str)

{

    while(*str)

    {

        Uart_Putc(*str++);

    }

}

 

 //格式化输出;

void Uart_Printf(char *fmt,...)

{

    char str[256];

    va_list     ap;

 

    va_start(ap,fmt); //va_start() 与 va_end() 需要对称

    vsprintf(str,fmt,ap);

    Uart_Puts(str);

    va_end(ap);

}


timer0.h  定时器0头文件


#include '6410_include.h'


#ifndef __TIMER_H__

#define __TIMER_H__


#define TINT_CSTAT           (*(volatile unsigned*)(0x7F006044)) 


#define TCFG0                (*(volatile unsigned*)(0x7F006000)) 

#define TCFG1                (*(volatile unsigned*)(0x7F006004)) 


#define TCON                 (*(volatile unsigned*)(0x7F006008)) 

#define TCNTB0               (*(volatile unsigned*)(0x7F00600C)) 

#define TCMPB0               (*(volatile unsigned*)(0x7F006010)) 

#define TCNTO0               (*(volatile unsigned*)(0x7F006014)) 

#define TCNTB1               (*(volatile unsigned*)(0x7F006018)) 

#define TCMPB1               (*(volatile unsigned*)(0x7F00601c)) 

#define TCNTO1               (*(volatile unsigned*)(0x7F006020)) 

#define TCNTB2               (*(volatile unsigned*)(0x7F006024)) 

#define TCNTO2               (*(volatile unsigned*)(0x7F00602c)) 

#define TCNTB3               (*(volatile unsigned*)(0x7F006030)) 

#define TCNTO3               (*(volatile unsigned*)(0x7F006038)) 

#define TCNTB4               (*(volatile unsigned*)(0x7F00603c)) 

#define TCNTO4               (*(volatile unsigned*)(0x7F006040)) 



#define VIC0ADDRESS          (*(volatile unsigned *)(0x71200f00))

#define VIC0INTENABLE        (*(volatile unsigned *)(0x71200010))


#define VIC0VECTADDR0        0x71200100

#define NUM_TIMER0           23


#endif //__TIMER_H__

                               

void __irq Isr_TIMER0(void);

void Timer0_Init(u32 Time0_Value);


timer0.c 定时器驱动代码


#include 'timer0.h'

#include 'uart.h'

#include 'LED.h'



u8 led_sw = 1;


//中断服务函数

void __irq Isr_Timer(void)

{

    led_sw = !led_sw;

    LED1(led_sw);

文章来源于: 电子工程世界 原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。