zoukankan      html  css  js  c++  java
  • (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 == '
    ')
         {
             while(!(UTRSTAT0 & 0x2));
             UTXH0 = '
    '; 
             
         }
         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
    ");
        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);
    }
  • 相关阅读:
    华为实习日记——第二十三天
    华为实习日记——第二十二天
    华为实习日记——第二十一天
    华为实习日记——第二十天
    HDU 5102 The K-th Distance(模拟)
    HDU 4113 Construct the Great Wall(插头dp)
    UVALive 4849 String Phone(2-sat、01染色)
    HDU 4859 海岸线(最大流最小割)
    HDU 3879 Base Station(最大权闭合子图)
    POJ 3155 Hard Life(最大密度子图)
  • 原文地址:https://www.cnblogs.com/hebaichuanyeah/p/3467304.html
Copyright © 2011-2022 走看看