×
单片机 > 单片机程序设计 > 详情

uart串口发送---那些年我们一起玩mini2440(arm9)裸机

发布时间:2020-06-06 发布时间:
|

Uart工作原理:

数据通信方式为:并行通信与串行通信两种:

§并行通信:利用多条数据线将数据的各位同时传送。

它的特点是:传输速度快,是用于短距离通信;

§串行通信:利用一条数据线将数据一位位地顺序传送。

特点是通信线路简单,利用简单的线缆就实现通信,低成本,是用于远距离通信。

 

异步通信:

ª异步通信:以一个字符为传输单位,通过两个字符间的时间间隔是不固定的,然而同一字符中的两个相邻位之间的时间间隔是固定的。

ª通信协议:是指通信双方约定的一些规则。在异步通讯时,对数据格式有如下约定:规定有空闲位、起始位、资料位、奇偶校验位、停止位。

 

起始位:先发一个逻辑“0”信号,表示传输字符的开始;

数据位:紧接在起始位之后。数据位的个数可以是4、5、6、7、8等,从最低位开始传送,靠时钟定位。

奇偶校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或(奇校验),以此校验数据传送的正确性。

停止位:它是一个字符数据的结束标志。

空闲位:处于逻辑“1”状态,表示当前线路没有数据传送。

 

波特率:

是衡量数据传送率的指标:记录每秒中传送的二进制位数。例如:数据传送速率为120字符、每秒。而每一个字符为10位,则其传送的波特率为10*120=1200位/秒=1200波特率

 

UART基本原理

通用异步收发器,简称UART,即“Universal Asynchronous Receiver Transmitter”,它用来传输串行数据;

 

发送数据时:

CPU将并行数据写入UART,UART按照一定的格式在一根电线上串行发出;

接收数据时:

UART检测另一根电线上的信号,将串行数据放在缓冲区中,CPU可读取UART获得的这些数据。

 

UART驱动程序设计

UART初始化:1.发送数据;2.接收数据;

UART初始化:1.设置波特率; 2.设置数据传输格式;3.选择通道工作模式;

一.设置波特率:(UBRDIV)

在s3c2440中,通过UBRDIV(p352)寄存器可以设定UART的波特率。Uart0、Uart1、Uart2分别对应UBRDIV0,UBRDIV1、UBRDIV2

      到底UBRDIV寄存器中的值与波特率有何关系?

      UBRDIV=(int)(UART clock / (buad  rate *16))-1

(UART clock:PCLK or FCLK/ n or UEXTCLK)

如波特率为115200bps,UART时钟为40MHZ

UBRDIV =(int) (40MHZ /(115200*16))-1

 

二.设置数据传输格式(ULCON)

在s3c2440中,通过ULCON(page341),可以设置传输格式(有多少个数据位、是否使用校验位、是奇校验还是偶校验,有多少个停止位、是否使用流量控制)

Uart0、Uart1、Uart2分别对应ULCON0、ULCON1、ULCON2.

 

三.设置通道工作模式(UCON)

在s3c2440中,通过UCON(page342),可以设置UART通道的工作模式,(中断模式、查询模式、或DMA模式)

Uart0、Uart1、Uart2分别对应UCON0、UCON1、UCON2.

这三步都属于初始化:初始化完成之后à发送或/接收数据

 

发送数据:

将要发送的数据写UTXHn, UART会将保存到缓冲区中,并自动发出去。

UTXH0、UTXH1、UTXH2

 

接收数据:

当UART收到数据时(UTRSTATn寄存器bit[0]被置1),CPU读取URXHn寄存器,即可获得数据。

URXH0、URXH1、URXH2寄存器中读取数据


  1. Main.c  

  2.   

  3. #define   GLOBAL_CLK           1  

  4.   

  5. #include   

  6.   

  7. #include   

  8.   

  9. #include "def.h"  

  10.   

  11. #include "option.h"  

  12.   

  13. #include "2440addr.h"  

  14.   

  15. #include "2440lib.h"  

  16.   

  17. #include "2440slib.h"  

  18.   

  19. #include "mmu.h"  

  20.   

  21. #include "profile.h"  

  22.   

  23. #include "memtest.h"  

  24.   

  25.    

  26.   

  27. static void cal_cpu_bus_clk(void);  

  28.   

  29. void Set_Clk(void);  

  30.   

  31. /*************************************************  

  32.   

  33. Function name: delay  

  34.   

  35. Parameter    : times  

  36.   

  37. Description    :延时函数  

  38.   

  39. Return          : void  

  40.   

  41. Argument     : void  

  42.   

  43. Autor & date : Daniel  

  44.   

  45. **************************************************/  

  46.   

  47. void delay(int times)  

  48.   

  49. {  

  50.   

  51.     int i,j;  

  52.   

  53.     for(i=0;i

  54.   

  55.        for(j=0;j<400;j++);  

  56.   

  57. }  

  58.   

  59. /*************************************************  

  60.   

  61. Function name: Main  

  62.   

  63. Parameter    : void  

  64.   

  65. Description     : 主功能函数,实现了串口的收发功能  

  66.   

  67.                首先想串口发送十次“hello world”,  

  68.   

  69. Return            : void  

  70.   

  71. Argument     : void  

  72.   

  73. Autor & date : Daniel  

  74.   

  75. **************************************************/  

  76.   

  77. void Main(void)  

  78.   

  79. {       

  80.   

  81.     int i;  

  82.   

  83.     int Scom=0;  

  84.   

  85.     Set_Clk();  

  86.   

  87.     beep_init();  

  88.   

  89.       

  90.   

  91.     /*设置波特率、数据位、停止位、校验位*/  

  92.   

  93.     Uart_Init(0,115200);  

  94.   

  95.     Uart_Select(Scom);  

  96.   

  97.     for(i=0;i<10;i++)  

  98.   

  99.     Uart_Printf("\nHello World!\n");  

  100.   

  101.       

  102.   

  103.     while(1)  

  104.   

  105.     {  

  106.   

  107.       while(Uart_GetKey()=='r')  

  108.   

  109.       {  

  110.   

  111.           for(i=0;i<10;i++)  

  112.   

  113.           beep_run();  

  114.   

  115.           Uart_Printf("\nBeep Quit!\n");  

  116.   

  117.       }  

  118.   

  119.        }  

  120.   

  121.    

  122.   

  123. }       

  124.   

  125.        

  126.   

  127. /*************************************************  

  128.   

  129. Function name: Set_Clk()  

  130.   

  131. Parameter    : void  

  132.   

  133. Description     : 设置CPU的时钟频率  

  134.   

  135. Return            : void  

  136.   

  137. Argument     : void  

  138.   

  139. Autor & date : Daniel  

  140.   

  141. **************************************************/  

  142.   

  143. void Set_Clk(void)  

  144.   

  145. {  

  146.   

  147.        int i;  

  148.   

  149.        U8 key;  

  150.   

  151.        U32 mpll_val = 0 ;  

  152.   

  153.        i = 2 ;                  //don't use 100M!  

  154.   

  155.                                //boot_params.cpu_clk.val = 3;  

  156.   

  157.        switch ( i ) {  

  158.   

  159.        case 0:     //200  

  160.   

  161.               key = 12;  

  162.   

  163.               mpll_val = (92<<12)|(4<<4)|(1);  

  164.   

  165.               break;  

  166.   

  167.        case 1:     //300  

  168.   

  169.               key = 13;  

  170.   

  171.               mpll_val = (67<<12)|(1<<4)|(1);  

  172.   

  173.               break;  

  174.   

  175.        case 2:     //400  

  176.   

  177.               key = 14;  

  178.   

  179.               mpll_val = (92<<12)|(1<<4)|(1);  

  180.   

  181.               break;  

  182.   

  183.        case 3:     //440!!!  

  184.   

  185.               key = 14;  

  186.   

  187.               mpll_val = (102<<12)|(1<<4)|(1);  

  188.   

  189.               break;  

  190.   

  191.        default:  

  192.   

  193.               key = 14;  

  194.   

  195.               mpll_val = (92<<12)|(1<<4)|(1);  

  196.   

  197.               break;  

  198.   

  199.        }  

  200.   

  201.          

  202.   

  203.        //init FCLK=400M, so change MPLL first  

  204.   

  205.        ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);   //set the register--rMPLLCON  

  206.   

  207.        ChangeClockDivider(key, 12);    //the result of rCLKDIVN [0:1:0:1] 3-0 bit  

  208.   

  209.        cal_cpu_bus_clk();    //HCLK=100M   PCLK=50M  

  210.   

  211. }  

  212.   

  213. /*************************************************  

  214.   

  215. Function name: cal_cpu_bus_clk  

  216.   

  217. Parameter    : void  

  218.   

  219. Description     : 设置PCLK\HCLK\FCLK的频率  

  220.   

  221. Return            : void  

  222.   

  223. Argument     : void  

  224.   

  225. Autor & date : Daniel  

  226.   

  227. **************************************************/  

  228.   

  229. static void cal_cpu_bus_clk(void)  

  230.   

  231. {  

  232.   

  233.        static U32 cpu_freq;  

  234.   

  235.     static U32 UPLL;  

  236.   

  237.          

  238.   

  239.        U32 val;  

  240.   

  241.        U8 m, p, s;  

  242.   

  243.          

  244.   

  245.        val = rMPLLCON;  

  246.   

  247.        m = (val>>12)&0xff;  

  248.   

  249.        p = (val>>4)&0x3f;  

  250.   

  251.        s = val&3;  

  252.   

  253.    

  254.   

  255.        //(m+8)*FIN*2不要超出32位数!  

  256.   

  257.        FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<

  258.   

  259.          

  260.   

  261.        val = rCLKDIVN;  

  262.   

  263.        m = (val>>1)&3;  

  264.   

  265.        p = val&1;       

  266.   

  267.        val = rCAMDIVN;  

  268.   

  269.        s = val>>8;  

  270.   

  271.          

  272.   

  273.        switch (m) {  

  274.   

  275.        case 0:  

  276.   

  277.               HCLK = FCLK;  

  278.   

  279.               break;  

  280.   

  281.        case 1:  

  282.   

  283.               HCLK = FCLK>>1;  

  284.   

  285.               break;  

  286.   

  287.        case 2:  

  288.   

  289.               if(s&2)  

  290.   

  291.                      HCLK = FCLK>>3;  

  292.   

  293.               else  

  294.   

  295.                      HCLK = FCLK>>2;  

  296.   

  297.               break;  

  298.   

  299.        case 3:  

  300.   

  301.               if(s&1)  

  302.   

  303.                      HCLK = FCLK/6;  

  304.   

  305.               else  

  306.   

  307.                      HCLK = FCLK/3;  

  308.   

  309.               break;  

  310.   

  311.        }  

  312.   

  313.          

  314.   

  315.        if(p)  

  316.   

  317.               PCLK = HCLK>>1;  

  318.   

  319.        else  

  320.   

  321.               PCLK = HCLK;  

  322.   

  323.          

  324.   

  325.        if(s&0x10)  

  326.   

  327.               cpu_freq = HCLK;  

  328.   

  329.        else  

  330.   

  331.               cpu_freq = FCLK;  

  332.   

  333.                 

  334.   

  335.        val = rUPLLCON;  

  336.   

  337.        m = (val>>12)&0xff;  

  338.   

  339.        p = (val>>4)&0x3f;  

  340.   

  341.        s = val&3;  

  342.   

  343.        UPLL = ((m+8)*FIN)/((p+2)*(1<

  344.   

  345.        UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;  

  346.   

  347. }  

  348.   

  349.    


2440lib.c


  1. #include "def.h"  

  2.   

  3. #include "option.h"  

  4.   

  5. #include "2440addr.h"  

  6.   

  7. #include "2440lib.h"  

  8.   

  9. #include "2440slib.h"  

  10.   

  11.    

  12.   

  13. #include   

  14.   

  15. #include   

  16.   

  17. #include   

  18.   

  19. #include   

  20.   

  21. #include   

  22.   

  23. static int whichUart=0;  

  24.   

  25.    

  26.   

  27. void Port_Init0(void)  //IO端口初始化  

  28.   

  29. {  

  30.   

  31.        //*** PORT H GROUP  

  32.   

  33.   //Ports  :  GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1  GPH0 //Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0  

  34.   

  35.     //Binary :   10   ,  10     10 , 11    11  , 10   10 , 10   10 , 10    10  

  36.   

  37.      rGPHCON = 0x00faaa;  

  38.   

  39.      rGPHUP  = 0x7ff;    // The pull up function is disabled GPH[10:0]  

  40.   

  41. }  

  42.   

  43.    

  44.   

  45. void Uart_Init(int pclk,int baud)  

  46.   

  47. {  

  48.   

  49.     int i;  

  50.   

  51.     if(pclk == 0)  

  52.   

  53.     pclk    = PCLK;  

  54.   

  55.     rUFCON0 = 0x0;   //UART channel 0 FIFO control register, FIFO disable  

  56.   

  57.     rUMCON0 = 0x0;   //UART chaneel 0 MODEM control register, AFC disable(AFC:流量控制)  

  58.   

  59.    //UART0  

  60.   

  61.     rULCON0 = 0x3;   //Line control register : Normal,No parity,1 stop,8 bits  

  62.   

  63.      //    [10]       [9]     [8]        [7]        [6]      [5]         [4]           [3:2]        [1:0]  

  64.   

  65.      // Clock Sel,  Tx Int,  Rx Int, Rx Time Out, Rx err, Loop-back, Send break,  Transmit Mode, Receive Mode  

  66.   

  67.      //     0          1       0    ,     0          1        0           0     ,       01          01  

  68.   

  69.      //   PCLK       Level    Pulse    Disable    Generate  Normal      Normal        Interrupt or Polling  

  70.   

  71.     rUCON0  = 0x245;   // Control register  

  72.   

  73.     rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 );   //Baud rate divisior register 0  

  74.   

  75.     for(i=0;i<100;i++);  

  76.   

  77. }  

  78.   

  79.    

  80.   

  81. //===================================================================  

  82.   

  83. void Uart_Select(int ch)  

  84.   

  85. {  

  86.   

  87.     whichUart = ch;  

  88.   

  89. }  

  90.   

  91. //=====================================================================  

  92.   

  93. void Uart_SendByte(int data)  

  94.   

  95. {  

  96.   

  97.     if(whichUart==0)  

  98.   

  99.     {  

  100.   

  101.         if(data=='\n')  

  102.   

  103.         {  

  104.   

  105.             while(!(rUTRSTAT0 & 0x2));  

  106.   

  107.            // Delay(1);                 //because the slow response of hyper_terminal  

  108.   

  109.             WrUTXH0('\r');  

  110.   

  111.         }  

  112.   

  113.         while(!(rUTRSTAT0 & 0x2));   //不为换行符时,Wait until THR is empty.  

  114.   

  115.       //  Delay(1);  

  116.   

  117.         WrUTXH0(data);//往寄存器写数据  

  118.   

  119.     }  

  120.   

  121.     else if(whichUart==1)  

  122.   

  123.     {  

  124.   

  125.         if(data=='\n')  

  126.   

  127.         {  

  128.   

  129.             while(!(rUTRSTAT1 & 0x2));  

  130.   

  131.             //Delay(1);                 //because the slow response of hyper_terminal  

  132.   

  133.             rUTXH1 = '\r';  

  134.   

  135.         }  

  136.   

  137.         while(!(rUTRSTAT1 & 0x2));   //Wait until THR is empty.  

  138.   

  139.         //Delay(1);  

  140.   

  141.         rUTXH1 = data;  

  142.   

  143.     }     

  144.   

  145.     else if(whichUart==2)  

  146.   

  147.     {  

  148.   

  149.         if(data=='\n')  

  150.   

  151.         {  

  152.   

  153.             while(!(rUTRSTAT2 & 0x2));  

  154.   

  155.             //Delay(1);                 //because the slow response of hyper_terminal  

  156.   

  157.             rUTXH2 = '\r';  

  158.   

  159.         }  

  160.   

  161.         while(!(rUTRSTAT2 & 0x2));   //Wait until THR is empty.  

  162.   

  163.         //Delay(1);  

  164.   

  165.         rUTXH2 = data;  

  166.   

  167.     }         

  168.   

  169. }                 

  170.   

  171.    

  172.   

  173. //====================================================================  

  174.   

  175. void Uart_SendString(char *pt)  

  176.   

  177. {  

  178.   

  179.     while(*pt)  

  180.   

  181.         Uart_SendByte(*pt++);  

  182.   

  183. }  

  184.   

  185. //=====================================================================  

  186.   

  187. //If you don't use vsprintf(), the code size is reduced very much.  

  188.   

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

  190.   

  191. {  

  192.   

  193.     va_list ap;  

  194.   

  195.     char string[256];  

  196.   

  197.    

  198.   

  199.     va_start(ap,fmt);//va_start、 va_end成对出现,ap指向fmt之后的参数  

  200.   

  201.     vsprintf(string,fmt,ap);//把ap之后的参数拷贝进string  

  202.   

  203.     Uart_SendString(string);  

  204.   

  205.     va_end(ap);  

  206.   

  207. }  


中断方式,串口发送:


  1. #define    GLOBAL_CLK             1  

  2.   

  3. #include   

  4.   

  5. #include   

  6.   

  7. #include "def.h"  

  8.   

  9. #include "option.h"  

  10.   

  11. #include "2440addr.h"  

  12.   

  13. #include "2440lib.h"  

  14.   

  15. #include "2440slib.h"  

  16.   

  17. #include "mmu.h"  

  18.   

  19. #include "profile.h"  

  20.   

  21. #include "memtest.h"  

  22.   

  23.    

  24.   

  25.    

  26.   

  27. void Uart0INT_init(void);  

  28.   

  29. static void __irq IRQ_ISR_UART0(void);  

  30.   

  31. void Set_Clk(void);  

  32.   

  33. static void cal_cpu_bus_clk(void);  

  34.   

  35. /*************************************************  

  36.   

  37. Function name: delay  

  38.   

  39. Parameter    : times  

  40.   

  41. Description     : 延时函数  

  42.   

  43. Return            : void  

  44.   

  45. Argument     : void  

  46.   

  47. Autor & date : Daniel  

  48.   

  49. **************************************************/  

  50.   

  51. void delay(int times)  

  52.   

  53. {  

  54.   

  55.     int i,j;  

  56.   

  57.     for(i=0;i

  58.   

  59.        for(j=0;j<400;j++);  

  60.   

  61. }  

  62.   

  63. /*************************************************  

  64.   

  65. Function name: Main  

  66.   

  67. Parameter    : void  

  68.   

  69. Description     : 主功能函数  

  70.   

  71. Return            : void  

  72.   

  73. Argument     : void  

  74.   

  75. Autor & date : Daniel  

  76.   

  77. **************************************************/  

  78.   

  79. int Main(void)  

  80.   

  81. {       

  82.   

  83.     Set_Clk();  

  84.   

  85.     MMU_Init();  

  86.   

  87.     Uart0INT_init();  

  88.   

  89.        return 0 ;  

  90.   

  91. }       

  92.   

  93. /*************************************************  

  94.   

  95. Function name: Uart0INT_init()  

  96.   

  97. Parameter    : void  

  98.   

  99. Description     : 中断初始化函数,用于配置中断所需要的  

  100.   

  101.                几个寄存器  

  102.   

  103. Return            : void  

  104.   

  105. Argument     : void  

  106.   

  107. Autor & date : Daniel  

  108.   

  109. **************************************************/     

  110.   

  111. void Uart0INT_init(void)  

  112.   

  113. {  

  114.   

  115.     

  116.   

  117.   Uart_Init( 0,115200);  

  118.   

  119.   Uart_Select(0);  

  120.   

  121.     

  122.   

  123.   rPRIORITY = 0x00000000;     /*默认优先级*/  

  124.   

  125.   rINTMOD = 0x00000000;       /*默认IRQ中断*/  

  126.   

  127.     

  128.   

  129.   /*清中断*/  

  130.   

  131.   ClearSubPending(BIT_SUB_RXD0);  

  132.   

  133.   ClearPending(BIT_UART0);  

  134.   

  135.     

  136.   

  137.   /*设置UART的ISR*/  

  138.   

  139.   pISR_UART0 = (U32)IRQ_ISR_UART0;  

  140.   

  141.   EnableIrq(BIT_UART0);  

  142.   

  143.   EnableSubIrq(BIT_SUB_RXD0);  

  144.   

  145.    

  146.   

  147. }  

  148.   

  149. /*************************************************  

  150.   

  151. Function name: IRQ_ISR_UART0()  

  152.   

  153. Parameter    : void  

  154.   

  155. Description     : 中断服务子程序,该子程序的作用就是把  

  156.   

  157.                串口收到的数据发送到超级终端。  

  158.   

  159. Return            : void  

  160.   

  161. Argument     : void  

  162.   

  163. Autor & date : Daniel  

  164.   

  165. **************************************************/  

  166.   

  167. static void __irq IRQ_ISR_UART0(void)  

  168.   

  169. {  

  170.   

  171.         if(rSUBSRCPND & 0x1)  

  172.   

  173.            {  

  174.   

  175.                      rUTXH0 = rURXH0;  /*这里没考虑回车*/  

  176.   

  177.                      ClearSubPending(BIT_SUB_RXD0);  

  178.   

  179.               }  

  180.   

  181.            ClearPending(BIT_UART0);  

  182.   

  183. }  

  184.   

  185.    

  186.   

  187. /*************************************************  

  188.   

  189. Function name: Set_Clk()  

  190.   

  191. Parameter    : void  

  192.   

  193. Description     : 设置CPU的时钟频率  

  194.   

  195. Return            : void  

  196.   

  197. Argument     : void  

  198.   

  199. Autor & date : Daniel  

  200.   

  201. **************************************************/  

  202.   

  203. void Set_Clk(void)  

  204.   

  205. {  

  206.   

  207.        int i;  

  208.   

  209.        U8 key;  

  210.   

  211.        U32 mpll_val = 0 ;  

  212.   

  213.        i = 2 ;                  //don't use 100M!  

  214.   

  215.                                //boot_params.cpu_clk.val = 3;  

  216.   

  217.        switch ( i ) {  

  218.   

  219.        case 0:     //200  

  220.   

  221.               key = 12;  

  222.   

  223.               mpll_val = (92<<12)|(4<<4)|(1);  

  224.   

  225.               break;  

  226.   

  227.        case 1:     //300  

  228.   

  229.               key = 13;  

  230.   

  231.               mpll_val = (67<<12)|(1<<4)|(1);  

  232.   

  233.               break;  

  234.   

  235.        case 2:     //400  

  236.   

  237.               key = 14;  

  238.   

  239.               mpll_val = (92<<12)|(1<<4)|(1);  

  240.   

  241.               break;  

  242.   

  243.        case 3:     //440!!!  

  244.   

  245.               key = 14;  

  246.   

  247.               mpll_val = (102<<12)|(1<<4)|(1);  

  248.   

  249.               break;  

  250.   

  251.        default:  

  252.   

  253.               key = 14;  

  254.   

  255.               mpll_val = (92<<12)|(1<<4)|(1);  

  256.   

  257.               break;  

  258.   

  259.        }  

  260.   

  261.          

  262.   

  263.        //init FCLK=400M, so change MPLL first  

  264.   

  265.        ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);   //set the register--rMPLLCON  

  266.   

  267.        ChangeClockDivider(key, 12);    //the result of rCLKDIVN [0:1:0:1] 3-0 bit  

  268.   

  269.        cal_cpu_bus_clk();    //HCLK=100M   PCLK=50M  

  270.   

  271. }  

  272.   

  273. /*************************************************  

  274.   

  275. Function name: cal_cpu_bus_clk  

  276.   

  277. Parameter    : void  

  278.   

  279. Description     : 设置PCLK\HCLK\FCLK的频率  

  280.   

  281. Return            : void  

  282.   

  283. Argument     : void  

  284.   

  285. Autor & date : Daniel  

  286.   

  287. **************************************************/  

  288.   

  289. static void cal_cpu_bus_clk(void)  

  290.   

  291. {  

  292.   

  293.        static U32 cpu_freq;  

  294.   

  295.     static U32 UPLL;  

  296.   

  297.          

  298.   

  299.        U32 val;  

  300.   

  301.        U8 m, p, s;  

  302.   

  303.          

  304.   

  305.        val = rMPLLCON;  

  306.   

  307.        m = (val>>12)&0xff;  

  308.   

  309.        p = (val>>4)&0x3f;  

  310.   

  311.        s = val&3;  

  312.   

  313.    

  314.   

  315.        //(m+8)*FIN*2不要超出32位数!  

  316.   

  317.        FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<

  318.   

  319.          

  320.   

  321.        val = rCLKDIVN;  

  322.   

  323.        m = (val>>1)&3;  

  324.   

  325.        p = val&1;       

  326.   

  327.        val = rCAMDIVN;  

  328.   

  329.        s = val>>8;  

  330.   

  331.          

  332.   

  333.        switch (m) {  

  334.   

  335.        case 0:  

  336.   

  337.               HCLK = FCLK;  

  338.   

  339.               break;  

  340.   

  341.        case 1:  

  342.   

  343.               HCLK = FCLK>>1;  

  344.   

  345.               break;  

  346.   

  347.        case 2:  

  348.   

  349.               if(s&2)  

  350.   

  351.                      HCLK = FCLK>>3;  

  352.   

  353.               else  

  354.   

  355.                      HCLK = FCLK>>2;  

  356.   

  357.               break;  

  358.   

  359.        case 3:  

  360.   

  361.               if(s&1)  

  362.   

  363.                      HCLK = FCLK/6;  

  364.   

  365.               else  

  366.   

  367.                      HCLK = FCLK/3;  

  368.   

  369.               break;  

  370.   

  371.        }  

  372.   

  373.          

  374.   

  375.        if(p)  

  376.   

  377.               PCLK = HCLK>>1;  

  378.   

  379.        else  

  380.   

  381.               PCLK = HCLK;  

  382.   

  383.          

  384.   

  385.        if(s&0x10)  

  386.   

  387.               cpu_freq = HCLK;  

  388.   

  389.        else  

  390.   

  391.               cpu_freq = FCLK;  

  392.   

  393.                 

  394.   

  395.        val = rUPLLCON;  

  396.   

  397.        m = (val>>12)&0xff;  

  398.   

  399.        p = (val>>4)&0x3f;  

  400.   

  401.        s = val&3;  

  402.   

  403.        UPLL = ((m+8)*FIN)/((p+2)*(1<

  404.   

  405.        UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;  

  406.   

  407. }  





『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
MSP430F5529 上手小例程2