• Main.C中 IO口,中断及串口初始化


    void Port_Init(void)
    {
        //CAUTION:Follow the configuration order for setting the ports. 
        // 1) setting value(GPnDAT) 
        // 2) setting control register  (GPnCON)
        // 3) configure pull-up resistor(GPnUP)  
        rGPACON = 0x7fffff; 
        rGPBCON = 0x015550;
        rGPBUP  = 0x7ff;  // The pull up function is disabled GPB[10:0]
        rGPCCON = 0xaaa956aa;       
        rGPCUP  = 0xffff; // The pull up function is disabled GPC[15:0] 
        rGPDCON = 0xaaaaaaaa;       
        rGPDUP  = 0xffff; // The pull up function is disabled GP[15:0]     
        rGPECON = 0xa02aa800; // For added AC97 setting      
        rGPEUP  = 0xffff;   
        rGPFCON = 0x55aa;
        rGPFUP  = 0xff;     // The pull up function is disabled GPF[7:0]
        rGPGCON = 0x00a2aaaa;// GPG9 input without pull-up
        rGPGUP  = 0xffff;    // The pull up function is disabled GPG[15:0]
        rGPHCON = 0x00faaa;
        rGPHUP  = 0x7ff;    // The pull up function is disabled GPH[10:0]
        rGPJCON = 0x02aaaaaa;
        rGPJUP  = 0x1fff;    // The pull up function is disabled GPH[10:0]
        //External interrupt will be falling edge triggered. 
        rEXTINT0 = 0x22222222;    // EINT[7:0]
        rEXTINT1 = 0x22222222;    // EINT[15:8]
        rEXTINT2 = 0x22222222;    // EINT[23:16]
    }

    A口:有23个引脚,GPA0到GPA11地址信号;GPA12到GPA16为nGCS[1-5];GPA17(CLE)、GPA18(ALE)、GPA19(nFWE)、GPA20(nFRE)、GPA21(nRSTOUT)、GPA22(nFCE) 一个位控制一个引脚的状态。0表示输出,1表示地址位或者状态引脚。(23根A口引脚全为输入)

     B口:有11根引脚,输入输出口配置:两位控制一根引脚状态:00 00 00 01 01 01 01 01 01 01 00 00  (B口0,1为输入;2、3、4、5、6、7、8为输出;9、10为输入)

             上拉与否:0111 1111 1111

    GPB10  [21:20]  00 = 输入  01 = 输出  10 = nXDREQ0  11 = 保留  0
    GPB9    [19:18]  00 = 输入  01 = 输出  10 = nXDACK0  11 = 保留  0
    GPB8    [17:16]  00 = 输入  01 = 输出  10 = nXDREQ1  11 = 保留  0
    GPB7    [15:14]  00 = 输入  01 = 输出  10 = nXDACK1  11 = 保留  0
    GPB6    [13:12]  00 = 输入  01 = 输出  10 = nXBREQ  11 = 保留  0
    GPB5    [11:10]  00 = 输入  01 = 输出  10 = nXBACK  11 = 保留  0
    GPB4    [9:8]      00 = 输入  01 = 输出  10 = TCLK [0]  11 = 保留  0
    GPB3    [7:6]      00 = 输入  01 = 输出  10 = TOUT3     11 = 保留  0
    GPB2    [5:4]      00 = 输入  01 = 输出  10 = TOUT2     11 = 保留  0
    GPB1    [3:2]      00 = 输入  01 = 输出  10 = TOUT1     11 = 保留  0
    GPB0    [1:0]      00 = 输入  01 = 输出  10 = TOUT0     11 = 保留  0

    C口引脚:16根引脚 1010 1010 1010 1001 0101 0110 1010 1010

    GPC15  [31:30]  00 = 输入  01 = 输出  10 = VD[7]  11 = 保留  0
    GPC14  [29:28]  00 = 输入  01 = 输出  10 = VD[6]  11 = 保留  0
    GPC13  [27:26]  00= 输入  01 = 输出  10 = VD[5]   11 = 保留  0
    GPC12  [25:24]  00 = 输入  01 = 输出  10 = VD[4]  11 = 保留  0
    GPC11  [23:22]  00 = 输入  01 = 输出  10 = VD[3]  11 = 保留  0
    GPC10  [21:20]  00 = 输入  01 = 输出  10 = VD[2]  11 = 保留  0
    GPC9  [19:18]  00 = 输入  01 = 输出  10 = VD[1]    11 = 保留  0
    GPC8  [17:16]  00 = 输入  01 = 输出  10 = VD[0]    11 = 保留  0
    GPC7  [15:14]  00 = 输入  01 = 输出  10 = LCD_LPCREVB  11 = 保留  0
    GPC6  [13:12]  00 = 输入  01 = 输出  10 = LCD_LPCREV    11 = 保留  0
    GPC5  [11:10]  00 = 输入  01 = 输出  10 = LCD_LPCOE      11 = 保留  0
    GPC4  [9:8]  00 = 输入  01 = 输出  10 = VM  11 = 保留  0
    GPC3  [7:6]  00 = 输入  01 = 输出  10 = VFRAME  11 = 保留  0
    GPC2  [5:4]  00 = 输入  01 = 输出  10 = VLINE  11 = 保留  0
    GPC1  [3:2]  00 = 输入  01 = 输出  10 = VCLK  11 = 保留  0
    GPC0  [1:0]  00 = 输入  01 = 输出  10 = LEND  11 = 保留  0

    //16根Binary : 10    10  , 10    10  , 10    10  , 10   10 , 10   10 , 10   10 , 10   10 ,10   10

    rGPDCON = 0xaaaaaaaa;      
    rGPDUP  = 0xffff;     // The pull up function is disabled GPD[15:0]

    //16根Binary :1010 0000 0010 1010 1010 1000 0000 0000

    rGPECON = 0xa02aa800; // For added AC97 setting      0、1、2、3、4、11、12、13 输入,其他功能角10

     rGPEUP  = 0xffff;    

    //8根Binary :  01      01 ,  01     01  ,     10       10  , 10     10
     rGPFCON = 0x55aa;
     rGPFUP  = 0xff;     // The pull up function is disabled GPF[7:0]

     //Ports  :  GPH10    GPH9  GPH8 GPH7  GPH6  GPH5 GPH4 GPH3 GPH2 GPH1  GPH0
    //Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0
    //Binary :   10   ,  10     10 , 11    11  , 10   10 , 10   10 , 10    10
    rGPHCON = 0x00faaa;
    rGPHUP  = 0x7ff;    // The pull up function is disabled GPH[10:0]

    //Ports  : GPJ12   GPJ11       GPJ10    GPJ9    GPJ8      GPJ7      GPJ6      GPJ5      GPJ4      GPJ3      GPJ2      GPJ1     GPJ0
    //Signal : CAMRESET CAMPCLKOUT CAMHREF CAMVSYNC CAMPCLKIN CAMDAT[7] CAMDAT[6] CAMDAT[5] CAMDAT[4] CAMDAT[3] CAMDAT[2] CAMDAT[1] CAMDAT[0]
    //Binary :   10      10       10        10       10        10        10        10       10         10        10        10      10
     rGPJCON = 0x02aaaaaa;
     rGPJUP  = 0x1fff;    // The pull up function is disabled GPH[10:0]

    //External interrupt will be falling edge triggered. 
    rEXTINT0 = 0x22222222;    // EINT[7:0]
    rEXTINT1 = 0x22222222;    // EINT[15:8]
    rEXTINT2 = 0x22222222;    // EINT[23:16]

     1 void Isr_Init(void)
     2 {
     3     pISR_UNDEF=(unsigned)HaltUndef;
     4     pISR_SWI  =(unsigned)HaltSwi;
     5     pISR_PABORT=(unsigned)HaltPabort;
     6     pISR_DABORT=(unsigned)HaltDabort;
     7     rINTMOD=0x0;      // All=IRQ mode
     8     rINTMSK=BIT_ALLMSK;      // All interrupt is masked.
     9 
    10     //pISR_URXD0=(unsigned)Uart0_RxInt;    
    11     //rINTMSK=~(BIT_URXD0);   //enable UART0 RX Default value=0xffffffff
    12 
    13 //#if 1
    14 //    pISR_USBD =(unsigned)IsrUsbd;
    15 //    pISR_DMA2 =(unsigned)IsrDma2;
    16 //#else
    17 //    pISR_IRQ =(unsigned)IsrUsbd;    
    18         //Why doesn't it receive the big file if use this. (???)
    19         //It always stops when 327680 bytes are received.
    20 //#endif    
    21 //    ClearPending(BIT_DMA2);
    22 //    ClearPending(BIT_USBD);
    23     //rINTMSK&=~(BIT_USBD);  
    24    
    25     //pISR_FIQ,pISR_IRQ must be initialized
    26 }

         ARM C中中断程序和其他的c的中断程序一样,就是有中断向量表,入口地址,中断应用程序三部分组成

         pISR_UNDEF=(unsigned)HaltUndef;   就是将函数HaltUndef的地址强制转换为unsigned类型,赋给指针pISR_UNDEF。由pISR_UNDEF定义知,

    #define pISR_UNDEF        (*(unsigned *)(_ISR_STARTADDRESS+0x4))

    pISR_UNDEF为相应的异常中断地址。 函数名称代表函数的地址,即将HaltUndef函数的地址赋值到_ISR_STARTADDRESS+0x4中。 当发生中断时,系统会去pISR_UNDEF定义的地址里取出中断函数的地址也就是HaltUndef的地址,然后执行. 就相当于当发生中断时,执行HaltUndef函数.

    void HaltUndef(void)
            {
                Uart_Printf("Undefined instruction exception!!! ");
                while(1);
            }
          表示处理相应中断。
     //中断向量表:7个中断地址:

    #define _ISR_STARTADDRESS  0x33ffff00

    #define pISR_RESET  (*(unsigned *)(_ISR_STARTADDRESS+0x0))
    #define pISR_UNDEF  (*(unsigned *)(_ISR_STARTADDRESS+0x4))
    #define pISR_SWI  (*(unsigned *)(_ISR_STARTADDRESS+0x8))
    #define pISR_PABORT  (*(unsigned *)(_ISR_STARTADDRESS+0xc))
    #define pISR_DABORT  (*(unsigned *)(_ISR_STARTADDRESS+0x10))
    #define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14))
    #define pISR_IRQ  (*(unsigned *)(_ISR_STARTADDRESS+0x18))
    #define pISR_FIQ  (*(unsigned *)(_ISR_STARTADDRESS+0x1c))

    1 pISR_UNDEF=(unsigned)HaltUndef;   就是将函数HaltUndef的地址强制转换为unsigned类型,赋给指针pISR_UNDEF。由pISR_UNDEF定义知,
    2 #define pISR_UNDEF        (*(unsigned *)(_ISR_STARTADDRESS+0x4))
    3 pISR_UNDEF为相应的异常中断地址。 函数名称代表函数的地址,即将HaltUndef函数的地址赋值到_ISR_STARTADDRESS+0x4中。 当发生中断时,
    
    4、系统会去pISR_UNDEF定义的地址里取出中断函数的地址也就是HaltUndef的地址,然后执行. 就相当于当发生中断时,执行HaltUndef函数.

    S3C2440A的UART 0和UART 1支持nRTS和nCTS信号的自动流控制。UART 2不支持AFC接口,因为S3C2440A没有nRTS2和nCTS2。

    非自动流控制的例子(软件控制nRTS和nCTS)
    带FIFO的Rx操作
    1.  选择接收模式(中断或DMA模式)。
    2.  检查UFSTATn寄存器中Rx FIFO的计数。如果该值小于32,用户必须设置UMCONn[0]的值为'1' (激活nRTS),
    并且如果该值大于等于32用户必须设置UMCONn[0]的值为'0'(取消激活nRTS)。
    3.  重复步骤2。
    带FIFO的Tx操作
    1.  选择发送模式(中断或DMA模式)。
    2.  检查UMSTATn[0]的值。如果值为'1'(激活nCTS),用户写入数据到Tx FIFO寄存器中。

    如果用户希望连接UART到调制解调接口(代替零调制解调模式),则需要nRTS,nCTS,nDSR,nDTR,DCD和nRI信号。在此情况下,由于AFC不支持RS-232C接口,用户可以通过软件使用通用I/O 口控制这些信号。

     1 void Uart_Init(int pclk,int baud)
     2 {
     3     int i;
     4     if(pclk == 0)
     5     pclk    = PCLK;
     6     rUFCON0 = 0x0;   //UART channel 0 FIFO control register, FIFO disable
     7     rUFCON1 = 0x0;   //UART channel 1 FIFO control register, FIFO disable
     8     rUFCON2 = 0x0;   //UART channel 2 FIFO control register, FIFO disable
     9     rUMCON0 = 0x0;   //UART chaneel 0 MODEM control register, AFC disable
    10     rUMCON1 = 0x0;   //UART chaneel 1 MODEM control register, AFC disable
    11 //UART0
    12     rULCON0 = 0x3;   //Line control register : Normal,No parity,1 stop,8 bits
    13      //    [10]       [9]     [8]        [7]        [6]      [5]         [4]           [3:2]        [1:0]
    14      // Clock Sel,  Tx Int,  Rx Int, Rx Time Out, Rx err, Loop-back, Send break,  Transmit Mode, Receive Mode
    15      //     0          1       0    ,     0          1        0           0     ,       01          01
    16      //   PCLK       Level    Pulse    Disable    Generate  Normal      Normal        Interrupt or Polling
    17     rUCON0  = 0x245;   // Control register
    18     rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 );   //Baud rate divisior register 0
    19 //UART1
    20     rULCON1 = 0x3;
    21     rUCON1  = 0x245;
    22     rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 );
    23 //UART2
    24     rULCON2 = 0x3;
    25     rUCON2  = 0x245;
    26     rUBRDIV2=( (int)(pclk/16./baud+0.5) -1 );    
    27 
    28     for(i=0;i<100;i++);
    29 }

     Uart_Printf()函数分析 

    ARM与PC机通信,常通过Uart_Printf()这个函数在上位机里输出信息。下面来详细分析这个函数功能。

    原形:

    //-----------------------------------------------------------------

    void Uart_Printf(char *fmt,...) //...表示可变参数(多个可变参数组成一 个列表,后面有专门的指针指向他),不限定个数和类型,
    {
        va_list ap;                 //
    初始化指向可变参数列表的指针
        char string[256];

        va_start(ap,fmt);        //将第一个可变参数的地址付给ap,即ap指向可变参数列表的开始
        vsprintf(string,fmt,ap);//
    将参数fmtap指向的可变参数一起转换成格式化字符串,放string数组中,其作用同sprintf(),只是参数类型不同
        Uart_SendString(string); //
    把格式化字符串从开发板串口送出去
        va_end(ap);                    //ap
    付值为0,没什么实际用处,主要是为程序健壮性
    }//-----------------------------

    va_list 在这个宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个文件。

    1)格式化字符串

    printf(“%s, %-19s: %6.2,lastname,firstname,prize;

    打印结果:BechrTeddy               2000.00

    我们说“ BechrTeddy               2000.00 就是一个格式化字符串printf的作用就是把(“%s, %-19s: 6.2,lastname,firstname,prize)翻译成电脑认识的字符串,而对于“%s, %-19s: 6.2,lastname,firstname,prize电脑根部不认识,故需要printf翻译。

    2vsprintf

    函数名: vsprintf
     送格式化输出串到指定数组中
     int vsprintf(char *string, char *format, va_list param); 

    vsprintfsprintf功能是一样的,即把格式化字符串输出到指定数组中,sprintf(char *string, char *farmat [,argument,...])函数的参数从第二个参数开始与printf是一样的,只是sprintf是输出到指定数组中,printf是输出到屏幕(一个标准输出文件),因而sprintf多了char *string这参数。

    Uart_Printf()这个函数在三星提供的库函数44blib.c中,其中的va_start,vsprintf,va_end等都是在stdarg.h中宏定义的,这个文件在linux内核中,这里不多加分析了,先掌握怎么用它。

    总之,这个函数可以简单的理解为将你C语言里的输出习惯转化为硬件底层能认识的字符串。调用这个函数是可以按照标准C里面向终端输出的方法,输出自己的要输出内容。

  • 相关阅读:
    装饰器的用法——用装饰器来记录函数被调用的次数
    类和对象(上) C++
    数据结构—树(二叉树)
    数据结构—顺序表
    c++入门

    Cypress博客
    自动化测试框架总结2
    前端测试框架Jest总结
    关于redux和react书籍源码系列代码
  • 原文地址:https://www.cnblogs.com/wangh0802PositiveANDupward/p/3427786.html
Copyright © 2020-2023  润新知