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

调试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 <stdarg.h>
#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);
    
    Uart_Printf("timer_ISR\n");
    TINT_CSTAT |= (1<<5);  //清time0中断标志
    VIC0ADDRESS = 0;
    //貌似VIC0ADDRESS中存放着当前中断的入口地址,清除地址。
}

 //定时器初始化;
void Timer0_Init(u32 Time0_Value)
{
    TCFG0 &= 0xffffff00;
    TCFG0 |= 0x00000041;
    //设置预分频器为65
    
    TCFG1 &= ~1;                //设置定时器0的MUX为1/1
    TCNTB0 = Time0_Value;       //timer0计数器值

    TINT_CSTAT |= 0x01;         //timer0中断使能
    VIC0INTENABLE |= (1<<23);   //timer0中断使能
            

    TCON |= 0x0B;            //开始timer0,更新CNTB0,TCMPB0,自动重装模式    
    TCON &= ~0x02;           //启动定时器后要关闭手动更新位
    

    (*(volatile unsigned *)(VIC0VECTADDR0+4*NUM_TIMER0)) = (u32)Isr_Timer;
    //注册安装定时器的中断函数: 每个寄存器存有4个字节的地址所以乘以4
}

main 主函数

#include "LED.h"
#include "uart.h"
#include "time0.h"

int main(void)
{



    Uart0_Init(115200);
    LED_init();
    Timer0_Init(300000);
    while(1);
}

 

转载于:https://www.cnblogs.com/hebaichuanyeah/p/3467304.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值