您的位置:首页 > 编程语言

裸机系列——2440串口通信2程序代码

2011-04-04 21:26 253 查看
2011-04-04

关于一些串口通信的知识已经在上一篇文章中做了总结,这里主要讲程序的问题。

首先是直接通信,即不使用FIFO和中断的通信

代码

#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"
#define baud 115200
void led_port_init()
{
rGPBCON &= ~(0xff<<10) ;
rGPBCON |= 0x55<<10 ;
//rGPBCON = temp ;
}
void delay(int times)
{
int i = 1000 ;
while(times--)
{
for(; i>0; --i)
;
}
}
//set FIFO model ,no interrupt
void UART_FIFO_init()
{
//set IO port GPHCON Rx0 Tx0
rGPHCON &= ~(0xf<<4) ;
rGPHCON |=  0xa<<4 ;
rGPHUP = 0x0 ;

rULCON0 = 0x03 ; //8-bits,1 stop bit, no parity
rUCON0  = 0x05 ;
rUFCON0 = 0x00 ;
rUMCON0  = 0x00 ;
rUBRDIV0= (int)(PCLK/baud/16) -1 ;
}
void UART_send_byte(int Tx_data)
{
while(!(rUTRSTAT0&0x2))	;

if(Tx_data =='/n')
{
delay(500) ;
rUTXH0 = '/n' ;
}
else
{
delay(500) ;
rUTXH0 = Tx_data ;
}
}
void UART_send_string(char *str)
{
while(*str)
{
delay(200) ;
UART_send_byte(*str) ;
str++ ;
}
}
char UART_receive_byte(void)
{
//rGPBDAT &= ~(0xf<<5) ;
while(!(rUTRSTAT0&0x1)) ;
rGPBDAT &= ~(0xf<<5) ;
return rURXH0 ;
}
void UART_receive(char *string)
{
char ch ;
while(1)
{
if((ch=UART_receive_byte())=='/r')
{
UART_send_byte('/n'):
}
else
{
UART_send_byte(ch) ;
}
}
}
int Main(void)
{
char receive_buffer[80] ;
//char send_buffer[] = "UART0 is OK!" ;
ChangeClockDivider(13,12);        //1:3:6
ChangeMPllValue(127,2,1);		//405MHZ
led_port_init() ;
UART_FIFO_init() ;
//UART_send(send_buffer) ;
UART_send_string(" /n /n Please input a string: /n") ;
delay(500) ;
while(1)
{
UART_receive(receive_buffer) ;
//delay(500) ;
//UART_send_string(receive_buffer) ;
//delay(500) ;

}

}


代码写的有点乱,开始没有主要风格。

下面的是没有FIFO的中断代码

#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"
#define baudrate 115200
/**********************************
void delay(int times)
{
int i = 1000 ;
while(times--)
{
for(; i>0; --i)
;
}
}
************************************/
/***********************************
UART_int初始化led IO端口GPBCON5-8
初始化GPBHCON为串口通信
配置串口通信寄存器
配置中断寄存器
************************************/
void UART_int_init(void)
{
//configuration LED IO port
rGPBCON &= ~(0xff<<10) ;
rGPBCON |= 0x55<<10 ;
//configuration GPHCON to UART
rGPHCON &= ~(0xf<<4) ;
rGPHCON |=  0xa<<4 ;
//rGPHCON = 0x00faaa;
//rGPHUP = 0x7ff ;
//configuration UART0 communication register
//8-bits,1 stop bit, no parity
rULCON0 = 0x03 ;
rUCON0  = 0x05 ;
//configuration UART baudrate
rUBRDIV0= (int)(PCLK/baudrate/16) -1 ;
//clean interrupt bit
rSUBSRCPND |= 0x3 ;
rSRCPND |= 1<<28 ;
rINTPND |= 1<<28 ;
//open UART interrupt
rINTSUBMSK &= ~(0x3) ;
rINTMSK &= ~(0x1<<28) ;
}
void UART_send_byte(int Tx_data)
{
//wait Tx empty
while(!(rUTRSTAT0&0x2)) ;

rUTXH0 = Tx_data ;
}
void UART_receive_byte(void)
{
char temp ;
//wait RX ready
while(!(rUTRSTAT0&0x1)) ;

temp = rURXH0 ;
UART_send_byte(temp) ;
}
/*******************************************
中断处理函数
置1清除中断,注意顺序,先子中断后父中断
点亮led灯
********************************************/
void __irq UART0_interrupt(void)
{
rGPBDAT &= ~(0xf<<5) ;
//clean interrupt bit
rSUBSRCPND |= 0x3 ;
rSRCPND |= 1<<28 ;
rINTPND |= 1<<28 ;
//lighten led
rGPBDAT &= ~(0xf<<5) ;
UART_receive_byte();
}
/*******************************
void UART_send_string(char *str)
{
while(*str)
{
//delay(200) ;
UART_send_byte(*str) ;
str++ ;
}
}
*******************************/
/*******************************************************************
串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。
首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的
分频比,确定好PCLK时钟。
********************************************************************/
int Main(void)
{
MMU_Init();
ChangeMPllValue(127,2,1);		//405MHZ
ChangeClockDivider(13,12);        //1:3:6
UART_int_init() ;
while(1)
{
pISR_UART0 = (U32)UART0_interrupt ;
}
return 0 ;
}


最后的是使用FIFO的中断代码,一般发送没必要使用中断,我只使用了接受中断,中断处理也很简单

主要是熟悉串口通信原理。

代码如下

#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"
#define baudrate 115200
/**********************************
void delay(int times)
{
int i = 1000 ;
while(times--)
{
for(; i>0; --i)
;
}
}
************************************/
/***********************************
UART_int初始化led IO端口GPBCON5-8
初始化GPBHCON为串口通信
配置串口通信寄存器FIFOt通信
配置中断寄存器
************************************/
void UART_int_init(void)
{
//configuration LED IO port
rGPBCON &= ~(0xff<<10) ;
rGPBCON |= 0x55<<10 ;
//configuration GPHCON to UART
rGPHCON &= ~(0xf<<4) ;
rGPHCON |=  0xa<<4 ;
//configuration UART0 communication register
//8-bits,1 stop bit, no parity
rULCON0 = 0x03 ;
rUCON0  = 0x05 ;
rUFCON0 = 0x3f ;
//configuration UART baudrate
rUBRDIV0= (int)(PCLK/baudrate/16) -1 ;
//clean interrupt bit
rSUBSRCPND |= 0x1 ;
rSRCPND |= 1<<28 ;
rINTPND |= 1<<28 ;
//open UART interrupt
rINTSUBMSK &= ~(0x1) ;
rINTMSK &= ~(0x1<<28) ;
}
void UART_send_byte(int Tx_data)
{
//wait Tx empty
while(!(rUTRSTAT0&0x2)) ;

rUTXH0 = Tx_data ;
}
void UART_receive(void)
{
char temp ;
//wait RX ready
while((rUFSTAT0&0x3F))
{
temp = rURXH0 ;
UART_send_byte(temp) ;
}
}
/*******************************************
中断处理函数
置1清除中断,注意顺序,先子中断后父中断
点亮led灯
********************************************/
void __irq UART0_interrupt(void)
{
rGPBDAT &= ~(0xf<<5) ;
//clean interrupt bit
rSUBSRCPND |= 0x1 ;
rSRCPND |= 1<<28 ;
rINTPND |= 1<<28 ;
//lighten led
rGPBDAT &= ~(0xf<<5) ;
UART_receive();
}
/*******************************
void UART_send_string(char *str)
{
while(*str)
{
//delay(200) ;
UART_send_byte(*str) ;
str++ ;
}
}
*******************************/
/*******************************************************************
串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。
首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的
分频比,确定好PCLK时钟。
********************************************************************/
int Main(void)
{
MMU_Init();
ChangeMPllValue(127,2,1);		//405MHZ
ChangeClockDivider(13,12);        //1:3:6
UART_int_init() ;
while(1)
{
pISR_UART0 = (U32)UART0_interrupt ;
}
return 0 ;
}


最后总结几句关于这次的串口通信程序,引用赵老师的。

1.

对于

s3c2440

来说,接收数据是被动的,发送数据是主动的,因此一般来说,接收数据用中断方式,发送数据用查询方式较好;

2.

在中断方式下,当接收到数据时,尽管可能该数据无用,但也一定要读取它,否则下次再接收数据时,不会再引起中断,因为接收数据缓存器被上次接收到的数据所霸占,只要没有读取它,它就永远在那里;

3.

由于

UART

中断涉及到

SUBSRCPND

寄存器,因此在中断处理程序中不仅要清

SRCPND

寄存器,还要清

SUBSRCPND

寄存器,它们的顺序一定是先清

SUBSRCPND

寄存器,再清

SRCPND

寄存器,否则就会引起一个中断两次响应的问题。因为是否中断由

SRCPND

寄存器决定,而

SRCPND

寄存器的相关状态位由

SUBSRCPND

寄存器决定,如果先清

SRCPND

寄存器,而还没有清

SUBSRCPND

寄存器的话,

SRCPND

寄存器的相关位还是会被置

1

,而一旦被置

1

,则一定还会引起中断

4.使用FIFO时相应的状态寄存器应该使用UFSTAT FIFO状态寄存器来查看FIFO中的数据,不用FIFO是直接查看接收发送寄存器UTRSTAT。21:30:00
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  byte delay string buffer io input
相关文章推荐