ARM裸機(jī)串口UART
異步通信:傳輸單位是一個(gè)字符,兩個(gè)字符之間時(shí)間間隔不固定,時(shí)間固定為同步。
本文引用地址:http://m.butianyuan.cn/article/201611/318271.htm通信協(xié)議:通信雙方共同制定的規(guī)則,有數(shù)據(jù)格式:奇偶校驗(yàn)位、停止位.....,通信流程上的規(guī)格.
UART(universal asynchronous receivertransmitter):通用異步收發(fā)器,用來串行傳輸數(shù)據(jù),發(fā)送時(shí),CPU將數(shù)據(jù)并行寫入U(xiǎn)ART,UART按照一定格式在一位的數(shù)據(jù)線上串行發(fā)送,接受時(shí),從一位數(shù)據(jù)線接受串行的數(shù)據(jù)。
S3c2440有三個(gè)獨(dú)立的uart接口,并且每個(gè)uart包括64字節(jié)的接受和發(fā)送fifo。
串口基本工作原理:分為發(fā)送和接收部分,發(fā)送部分:1接口用來接收數(shù)據(jù),數(shù)據(jù)由CPU通過BUS送到uart,首先進(jìn)入transmitbuffer,然后會(huì)自動(dòng)的把每字節(jié)送入transmitshift把8位數(shù)據(jù)依位移出發(fā)送,發(fā)送過程受波特率控制每秒發(fā)送位數(shù)。接收:從數(shù)據(jù)依位收到放入 receive shift形成一個(gè)字節(jié),放入buffer,通過機(jī)制(中斷)告訴CPU,完成接受。
串口UART程序設(shè)計(jì)
UART初始化:設(shè)置波特率-->設(shè)置串口數(shù)據(jù)傳輸格式-->選擇通道工作模式(DMA,中斷......)。
1:通過UART Baud Rate Divisor Register即UBRDIV可以設(shè)置UART波特率,波特率的設(shè)置依賴一個(gè)公式 UBRDIV=(int)(uartclock / (baud rate * 16) ) -1
(uart clock :PCLK orFCLK /n or UEXTCLK)
CPU一工作clock就定下來,設(shè)置波特率就是設(shè)置UBRDIV。
2:設(shè)置傳輸格式,通過UART LINE CONTROL REGISTER即ULCON,可以設(shè)置傳輸格式。
3:設(shè)置通道工作模式:通過UART CONTROL REGISTER,即UCON。
完成初始化后發(fā)送數(shù)據(jù)
把要發(fā)送的數(shù)據(jù)寫入U(xiǎn)TXHn(4個(gè)字節(jié)),UART會(huì)把它保存到緩沖區(qū),并自動(dòng)發(fā)送。
接收數(shù)據(jù):一旦接收到數(shù)據(jù)之后,如果沒有DMA和中斷,可以查詢UTRSTATn寄存器的第0位,從URXHn寄存器拿數(shù)據(jù)。
串口發(fā)送數(shù)據(jù)程序:static void cal_cpu_bus_clk(void);void Set_Clk(void);void beep_init(void);void beep_run(void);void delay(int times) {int i,j;for(i=0;i串口通信選擇for(i=0;i<10;i++) //串口發(fā)送數(shù)據(jù)Uart_Printf("nHello World!n");//串口輸出的數(shù)據(jù)} void Set_Clk(void){int i;U8 key;U32 mpll_val = 0 ;i = 2 ; //dont use 100M!//boot_params.cpu_clk.val = 3;switch ( i ) {case 0: //200key = 12;mpll_val = (92<<12)|(4<<4)|(1);break;case 1: //300key = 13;mpll_val = (67<<12)|(1<<4)|(1);break;case 2: //400key = 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 firstChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //set the register--rMPLLCONChangeClockDivider(key, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bitcal_cpu_bus_clk(); //HCLK=100M PCLK=50M}/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位數(shù)!FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1< >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;elseHCLK = FCLK>>2;break;case 3:if(s&1)HCLK = FCLK/6;elseHCLK = FCLK/3;break;}if(p)PCLK = HCLK>>1;elsePCLK = HCLK;if(s&0x10)cpu_freq = HCLK;elsecpu_freq = FCLK;val = rUPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;UPLL = ((m+8)*FIN)/((p+2)*(1<>1):UPLL;}void beep_init(void){rGPBCON &= ~(0x3<<0);rGPBCON |= (0x1<<0);}void beep_run(void){rGPBDAT |= (0x1<<0);delay(5000);rGPBDAT &= (0x0<<0);delay(5000);}void Uart_Init(int pclk,int baud){int i;if(pclk == 0)pclk = PCLK; //串口使用PCLKrUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disablerUFCON1 = 0x0; //UART channel 1 FIFO control register, FIFO disablerUFCON2 = 0x0; //UART channel 2 FIFO control register, FIFO disable//關(guān)掉fiforUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disablerUMCON1 = 0x0; //UART chaneel 1 MODEM control register, AFC disable rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bitsrUCON0 = 0x245; // Control registerrUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0//UART1rULCON1 = 0x3;rUCON1 = 0x245;rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 );//UART2rULCON2 = 0x3;rUCON2 = 0x245;rUBRDIV2=( (int)(pclk/16./baud+0.5) -1 ); for(i=0;i<100;i++);}
評(píng)論