标签:des style blog http io ar color os 使用
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寄存器中读取数据
pasting
- Main.c
-
- <span style="color:#000000;">#define GLOBAL_CLK 1
-
- #include <stdlib.h>
-
- #include <string.h>
-
- #include "def.h"
-
- #include "option.h"
-
- #include "2440addr.h"
-
- #include "2440lib.h"
-
- #include "2440slib.h"
-
- #include "mmu.h"
-
- #include "profile.h"
-
- #include "memtest.h"
-
-
-
- static void cal_cpu_bus_clk(void);
-
- void Set_Clk(void);
-
- /*************************************************
-
- Function name: delay
-
- Parameter : times
-
- Description :延时函数
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- void delay(int times)
-
- {
-
- int i,j;
-
- for(i=0;i<times;i++)
-
- for(j=0;j<400;j++);
-
- }
-
- /*************************************************
-
- Function name: Main
-
- Parameter : void
-
- Description : 主功能函数,实现了串口的收发功能
-
- 首先想串口发送十次“hello world”,
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- void Main(void)
-
- {
-
- int i;
-
- int Scom=0;
-
- Set_Clk();
-
- beep_init();
-
-
-
- /*设置波特率、数据位、停止位、校验位*/
-
- Uart_Init(0,115200);
-
- Uart_Select(Scom);
-
- for(i=0;i<10;i++)
-
- Uart_Printf("\nHello World!\n");
-
-
-
- while(1)
-
- {
-
- while(Uart_GetKey()==‘r‘)
-
- {
-
- for(i=0;i<10;i++)
-
- beep_run();
-
- Uart_Printf("\nBeep Quit!\n");
-
- }
-
- }
-
-
-
- }
-
-
-
- /*************************************************
-
- Function name: Set_Clk()
-
- Parameter : void
-
- Description : 设置CPU的时钟频率
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- void Set_Clk(void)
-
- {
-
- int i;
-
- U8 key;
-
- U32 mpll_val = 0 ;
-
- i = 2 ; //don‘t use 100M!
-
- //boot_params.cpu_clk.val = 3;
-
- switch ( i ) {
-
- case 0: //200
-
- key = 12;
-
- mpll_val = (92<<12)|(4<<4)|(1);
-
- break;
-
- case 1: //300
-
- key = 13;
-
- mpll_val = (67<<12)|(1<<4)|(1);
-
- break;
-
- case 2: //400
-
- key = 14;
-
- mpll_val = (92<<12)|(1<<4)|(1);
-
- break;
-
- case 3: //440!!!
-
- key = 14;
-
- mpll_val = (102<<12)|(1<<4)|(1);
-
- break;
-
- default:
-
- key = 14;
-
- mpll_val = (92<<12)|(1<<4)|(1);
-
- break;
-
- }
-
-
-
- //init FCLK=400M, so change MPLL first
-
- ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //set the register--rMPLLCON
-
- ChangeClockDivider(key, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit
-
- cal_cpu_bus_clk(); //HCLK=100M PCLK=50M
-
- }
-
- /*************************************************
-
- Function name: cal_cpu_bus_clk
-
- Parameter : void
-
- Description : 设置PCLK\HCLK\FCLK的频率
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- static void cal_cpu_bus_clk(void)
-
- {
-
- static U32 cpu_freq;
-
- static U32 UPLL;
-
-
-
- U32 val;
-
- U8 m, p, s;
-
-
-
- val = rMPLLCON;
-
- m = (val>>12)&0xff;
-
- p = (val>>4)&0x3f;
-
- s = val&3;
-
-
-
- //(m+8)*FIN*2不要超出32位数!
-
- FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100; //FCLK=400M FIN=12000000
-
-
-
- val = rCLKDIVN;
-
- m = (val>>1)&3;
-
- p = val&1;
-
- val = rCAMDIVN;
-
- s = val>>8;
-
-
-
- switch (m) {
-
- case 0:
-
- HCLK = FCLK;
-
- break;
-
- case 1:
-
- HCLK = FCLK>>1;
-
- break;
-
- case 2:
-
- if(s&2)
-
- HCLK = FCLK>>3;
-
- else
-
- HCLK = FCLK>>2;
-
- break;
-
- case 3:
-
- if(s&1)
-
- HCLK = FCLK/6;
-
- else
-
- HCLK = FCLK/3;
-
- break;
-
- }
-
-
-
- if(p)
-
- PCLK = HCLK>>1;
-
- else
-
- PCLK = HCLK;
-
-
-
- if(s&0x10)
-
- cpu_freq = HCLK;
-
- else
-
- cpu_freq = FCLK;
-
-
-
- val = rUPLLCON;
-
- m = (val>>12)&0xff;
-
- p = (val>>4)&0x3f;
-
- s = val&3;
-
- UPLL = ((m+8)*FIN)/((p+2)*(1<<s));
-
- UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;
-
- }
-
- </span>
2440lib.c
pasting
- #include "def.h"
-
- #include "option.h"
-
- #include "2440addr.h"
-
- #include "2440lib.h"
-
- #include "2440slib.h"
-
-
-
- #include <stdarg.h>
-
- #include <string.h>
-
- #include <stdlib.h>
-
- #include <stdio.h>
-
- #include <ctype.h>
-
- static int whichUart=0;
-
-
-
- void Port_Init0(void) //IO端口初始化
-
- {
-
- //*** PORT H GROUP
-
- //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]
-
- }
-
-
-
- void Uart_Init(int pclk,int baud)
-
- {
-
- int i;
-
- if(pclk == 0)
-
- pclk = PCLK;
-
- rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable
-
- rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable(AFC:流量控制)
-
- //UART0
-
- rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits
-
- // [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0]
-
- // Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit Mode, Receive Mode
-
- // 0 1 0 , 0 1 0 0 , 01 01
-
- // PCLK Level Pulse Disable Generate Normal Normal Interrupt or Polling
-
- rUCON0 = 0x245; // Control register
-
- rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0
-
- for(i=0;i<100;i++);
-
- }
-
-
-
- //===================================================================
-
- void Uart_Select(int ch)
-
- {
-
- whichUart = ch;
-
- }
-
- //=====================================================================
-
- void Uart_SendByte(int data)
-
- {
-
- if(whichUart==0)
-
- {
-
- if(data==‘\n‘)
-
- {
-
- while(!(rUTRSTAT0 & 0x2));
-
- // Delay(1); //because the slow response of hyper_terminal
-
- WrUTXH0(‘\r‘);
-
- }
-
- while(!(rUTRSTAT0 & 0x2)); //不为换行符时,Wait until THR is empty.
-
- // Delay(1);
-
- WrUTXH0(data);//往寄存器写数据
-
- }
-
- else if(whichUart==1)
-
- {
-
- if(data==‘\n‘)
-
- {
-
- while(!(rUTRSTAT1 & 0x2));
-
- //Delay(1); //because the slow response of hyper_terminal
-
- rUTXH1 = ‘\r‘;
-
- }
-
- while(!(rUTRSTAT1 & 0x2)); //Wait until THR is empty.
-
- //Delay(1);
-
- rUTXH1 = data;
-
- }
-
- else if(whichUart==2)
-
- {
-
- if(data==‘\n‘)
-
- {
-
- while(!(rUTRSTAT2 & 0x2));
-
- //Delay(1); //because the slow response of hyper_terminal
-
- rUTXH2 = ‘\r‘;
-
- }
-
- while(!(rUTRSTAT2 & 0x2)); //Wait until THR is empty.
-
- //Delay(1);
-
- rUTXH2 = data;
-
- }
-
- }
-
-
-
- //====================================================================
-
- void Uart_SendString(char *pt)
-
- {
-
- while(*pt)
-
- Uart_SendByte(*pt++);
-
- }
-
- //=====================================================================
-
- //If you don‘t use vsprintf(), the code size is reduced very much.
-
- void Uart_Printf(char *fmt,...)
-
- {
-
- va_list ap;
-
- char string[256];
-
-
-
- va_start(ap,fmt);//va_start、 va_end成对出现,ap指向fmt之后的参数
-
- vsprintf(string,fmt,ap);//把ap之后的参数拷贝进string
-
- Uart_SendString(string);
-
- va_end(ap);
-
- }
中断方式,串口发送:
pasting
- #define GLOBAL_CLK 1
-
- #include <stdlib.h>
-
- #include <string.h>
-
- #include "def.h"
-
- #include "option.h"
-
- #include "2440addr.h"
-
- #include "2440lib.h"
-
- #include "2440slib.h"
-
- #include "mmu.h"
-
- #include "profile.h"
-
- #include "memtest.h"
-
-
-
-
-
- void Uart0INT_init(void);
-
- static void __irq IRQ_ISR_UART0(void);
-
- void Set_Clk(void);
-
- static void cal_cpu_bus_clk(void);
-
- /*************************************************
-
- Function name: delay
-
- Parameter : times
-
- Description : 延时函数
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- void delay(int times)
-
- {
-
- int i,j;
-
- for(i=0;i<times;i++)
-
- for(j=0;j<400;j++);
-
- }
-
- /*************************************************
-
- Function name: Main
-
- Parameter : void
-
- Description : 主功能函数
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- int Main(void)
-
- {
-
- Set_Clk();
-
- MMU_Init();
-
- Uart0INT_init();
-
- return 0 ;
-
- }
-
- /*************************************************
-
- Function name: Uart0INT_init()
-
- Parameter : void
-
- Description : 中断初始化函数,用于配置中断所需要的
-
- 几个寄存器
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- void Uart0INT_init(void)
-
- {
-
-
-
- Uart_Init( 0,115200);
-
- Uart_Select(0);
-
-
-
- rPRIORITY = 0x00000000; /*默认优先级*/
-
- rINTMOD = 0x00000000; /*默认IRQ中断*/
-
-
-
- /*清中断*/
-
- ClearSubPending(BIT_SUB_RXD0);
-
- ClearPending(BIT_UART0);
-
-
-
- /*设置UART的ISR*/
-
- pISR_UART0 = (U32)IRQ_ISR_UART0;
-
- EnableIrq(BIT_UART0);
-
- EnableSubIrq(BIT_SUB_RXD0);
-
-
-
- }
-
- /*************************************************
-
- Function name: IRQ_ISR_UART0()
-
- Parameter : void
-
- Description : 中断服务子程序,该子程序的作用就是把
-
- 串口收到的数据发送到超级终端。
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- static void __irq IRQ_ISR_UART0(void)
-
- {
-
- if(rSUBSRCPND & 0x1)
-
- {
-
- rUTXH0 = rURXH0; /*这里没考虑回车*/
-
- ClearSubPending(BIT_SUB_RXD0);
-
- }
-
- ClearPending(BIT_UART0);
-
- }
-
-
-
- /*************************************************
-
- Function name: Set_Clk()
-
- Parameter : void
-
- Description : 设置CPU的时钟频率
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- void Set_Clk(void)
-
- {
-
- int i;
-
- U8 key;
-
- U32 mpll_val = 0 ;
-
- i = 2 ; //don‘t use 100M!
-
- //boot_params.cpu_clk.val = 3;
-
- switch ( i ) {
-
- case 0: //200
-
- key = 12;
-
- mpll_val = (92<<12)|(4<<4)|(1);
-
- break;
-
- case 1: //300
-
- key = 13;
-
- mpll_val = (67<<12)|(1<<4)|(1);
-
- break;
-
- case 2: //400
-
- key = 14;
-
- mpll_val = (92<<12)|(1<<4)|(1);
-
- break;
-
- case 3: //440!!!
-
- key = 14;
-
- mpll_val = (102<<12)|(1<<4)|(1);
-
- break;
-
- default:
-
- key = 14;
-
- mpll_val = (92<<12)|(1<<4)|(1);
-
- break;
-
- }
-
-
-
- //init FCLK=400M, so change MPLL first
-
- ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //set the register--rMPLLCON
-
- ChangeClockDivider(key, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit
-
- cal_cpu_bus_clk(); //HCLK=100M PCLK=50M
-
- }
-
- /*************************************************
-
- Function name: cal_cpu_bus_clk
-
- Parameter : void
-
- Description : 设置PCLK\HCLK\FCLK的频率
-
- Return : void
-
- Argument : void
-
- Autor & date : Daniel
-
- **************************************************/
-
- static void cal_cpu_bus_clk(void)
-
- {
-
- static U32 cpu_freq;
-
- static U32 UPLL;
-
-
-
- U32 val;
-
- U8 m, p, s;
-
-
-
- val = rMPLLCON;
-
- m = (val>>12)&0xff;
-
- p = (val>>4)&0x3f;
-
- s = val&3;
-
-
-
- //(m+8)*FIN*2不要超出32位数!
-
- FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100; //FCLK=400M FIN=12000000
-
-
-
- val = rCLKDIVN;
-
- m = (val>>1)&3;
-
- p = val&1;
-
- val = rCAMDIVN;
-
- s = val>>8;
-
-
-
- switch (m) {
-
- case 0:
-
- HCLK = FCLK;
-
- break;
-
- case 1:
-
- HCLK = FCLK>>1;
-
- break;
-
- case 2:
-
- if(s&2)
-
- HCLK = FCLK>>3;
-
- else
-
- HCLK = FCLK>>2;
-
- break;
-
- case 3:
-
- if(s&1)
-
- HCLK = FCLK/6;
-
- else
-
- HCLK = FCLK/3;
-
- break;
-
- }
-
-
-
- if(p)
-
- PCLK = HCLK>>1;
-
- else
-
- PCLK = HCLK;
-
-
-
- if(s&0x10)
-
- cpu_freq = HCLK;
-
- else
-
- cpu_freq = FCLK;
-
-
-
- val = rUPLLCON;
-
- m = (val>>12)&0xff;
-
- p = (val>>4)&0x3f;
-
- s = val&3;
-
- UPLL = ((m+8)*FIN)/((p+2)*(1<<s));
-
- UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;
-
- }
起始位:先发一个逻辑“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串口发送---那些年我们一起玩mini2440(arm9)裸机
标签:des style blog http io ar color os 使用
原文地址:http://www.cnblogs.com/liuchengchuxiao/p/4150596.html