打印

三 ARM9(S3C2440)的串口UART——程序实例讲解

[复制链接]
2541|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mizhongqin|  楼主 | 2011-9-13 00:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
串口通信程序编写步骤
UART通信程序可以采用查询、中断和DMA模式。我们通过使用较多的中断方式来介UART通信程序的编写。简单做法是,UART通信程序的编写参照例子程序。
选通道,通过函数Uart_Select();选UART0~UART2;
  选波特率和波特率发生器时钟,选波特率通过函数Uart_Pclk_En(int ch, int baud)或Uart_Pclk_En(int ch, int baud)来进行。时钟选UCLK ,rUCON0|=0x400;时钟选PCLK ,rUCON0&=0x3ff。
通信协议(rULCON0)设定,如果正常通信,一位停止位,8位数据位,无奇偶效验: rULCON0=(0<<6)|(0<<3)|(0<<2)|(3);      
通信控制字(rUCON0)设定,如时钟选ULK做波特率发生器;Tx中断脉冲触发,Rx中断脉冲触发;接收超时中断允许;产生接收错误中断;正常模式发送:
        rUCON0|=(TX_INTTYPE<<9)|(RX_INTTYPE<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1);
        I/O口初始化,因为UART通信使用H口的第二功能,所以H口要上拉禁止:rGPHUP|=0x1ff。H口控制寄存器nRTS1,nCTS1功能使能,rGPHCON&=0x3c0000,rGPHCON|=0x2faaa;
设中断服务函数入口地址,把中断服务函数入口地址赋函数指针PISR_UARTn, 注意,接收中断服务函数入口地址和发送中断服务函数入口地址是一个,在中断服务函数中根据
UTRSTATn [1]和UTRSTATn [0]状态决定是发送中断还是接收中断。
打开总中断屏蔽和子中断屏蔽等待中断:
rINTMSK=~(BIT_UART0);
rINTSUBMSK=~(BIT_SUB_TXD0);
        进入中断后,先屏蔽发送和接收中断,防止新来中断干扰我们的正常发送和接收,正常发送和接收结束后,清中断挂起和中断源挂起寄存器:ClearPending(BIT_UART0),rSUBSRCPND=(BIT_SUB_TXD0(发送),rSUBSRCPND=(BIT_SUB_RXD0|BIT_SUB_ERR0)(接收);
        取消中断屏蔽,等下一次中断。
下面是利用查询方式的串口通信程序(FL2440开发板)
#include"2440addr.h"//该程序是PC机通过串口工具向开发板发送1234这四个数字来控制四个LED的亮灭
int TSmain()
{
char buf,i;

rULCON0 &=0XFFFFFF00;
rULCON0 |=0X03;           //1位起始位,8位数据位
rUCON0  =0x05;//0X0805;          //串口时钟PCLK,查询方式 东:PCLK为50M
rUBRDIV0 =325;//0X1A;           //波特率115200****325时设置为9600
rGPBCON = 0x1dd7fc;//GPB5,6,8,10设置为输出
rGPBDAT|=0x560;//4个LED全灭
while(1)
{
  if(rUTRSTAT0 & 0X01)  //接收是否完毕 =1结束
  {
   
   buf=rURXH0;       //读取数据
   while(!(rUTRSTAT0 & 0X04));//是否允许发送 =1允许
   rUTXH0=buf;
   if(buf=='1')//判断接收到的是哪一个数字
    i=1;
   else if(buf=='2')
    i=2;
   else if(buf=='3')
    i=3;
   else if(buf=='4')
    i=4;
   switch(i){      //使相应的LED亮灭
      
      case 1:
        rGPBDAT^=(1<<5);
        i=0;//将i清零防止下次收到其他数据时干扰
        break;
      case 2:
        rGPBDAT^=(1<<6);
        i=0;
        break;
      case 3:
        rGPBDAT^=(1<<8);
        i=0;
        break;
      case 4:
        rGPBDAT^=(1<<10);
        i=0;
        break;
      default:break;
      }
   
  }
}

return 0;
}
下面是利用中断的串口通信程序

#include"2440addr.h"
void __irq UART0RX_isr()
{
  char buf,i;
  rINTMSK=0xffffffff;
  ClearPending(BIT_UART0);
  
  if(rUTRSTAT0 & 0X01)  //接收是否完毕 =1结束
  {
   ClearSubPending(BIT_SUB_RXD0);
   buf=rURXH0;       //读取数据
   while(!(rUTRSTAT0 & 0X04));//是否允许发送 =1允许
   rUTXH0=buf;
   if(buf=='1')
    i=1;
   else if(buf=='2')
    i=2;
   else if(buf=='3')
    i=3;
   else if(buf=='4')
    i=4;
   switch(i){
      
      case 1:
        rGPBDAT^=(1<<5);
        i=0;//将i清零防止下次收到其他数据时干扰
        break;
      case 2:
        rGPBDAT^=(1<<6);
        i=0;
        break;
      case 3:
        rGPBDAT^=(1<<8);
        i=0;
        break;
      case 4:
        rGPBDAT^=(1<<10);
        i=0;
        break;
      default:break;
      }
   
  }
  EnableIrq(BIT_UART0);
  EnableSubIrq(BIT_SUB_RXD0);
  EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT3|BIT_EINT4_7);
}
static void __irq Key_ISR()
{
char key;//用来标识是哪一个按键按下
//EnterCritical(&r);
rINTMSK=0xffffffff;
if(rINTPND==BIT_EINT0) {
  ClearPending(BIT_EINT0);
  key=1;
}
  else if(rINTPND==BIT_EINT2) {
   ClearPending(BIT_EINT2);
   key=2;
  }
   else if(rINTPND==BIT_EINT3) {
    ClearPending(BIT_EINT3);
    key=3;
   }
    else if(rINTPND==BIT_EINT4_7){
     rEINTPEND=(1<<4);
     ClearPending(BIT_EINT4_7);
     key=4;
    }
switch(key){
  case 1:
    rGPBDAT^=(1<<5);
    break;
  case 2:
    rGPBDAT^=(1<<6);
    break;
  case 3:
    rGPBDAT^=(1<<8);
    break;
  case 4:
    rGPBDAT^=(1<<10);
    break;
}

//ExitCritical(&r);
EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT3|BIT_EINT4_7);
EnableIrq(BIT_UART0);
EnableSubIrq(BIT_SUB_RXD0);
   
  
  
}
int TSmain()
{


rULCON0 &=0XFFFFFF00;
rULCON0 |=0X03;           //1位起始位,8位数据位
rUCON0  =0x05;//0X0805;          //串口时钟PCLK,查询方式 东:PCLK为50M
rUBRDIV0 =325;//0X1A;           //波特率115200****325时设置为9600
rGPHUP=0x1ff;//H口上拉禁止
rGPHCON&=0x3c0000;
rGPHCON|=0x2faaa;
rGPBCON = 0x1dd7fc;//GPB5,6,8,10设置为输出
rGPBDAT|=0x560;//4个LED全灭
rGPFCON &=~((3<<0)|(3<<4)|(3<<6)|(3<<8)) ;
rGPFCON |= ((2<<0)|(2<<4)|(2<<6)|(2<<8)) ;//GPF0,GPF2,GPF3,GPF4工作在第二功能状态,即中断
rEINTPEND=(1<<4);
ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT3|BIT_EINT4_7);
ClearSubPending(BIT_SUB_RXD0);
ClearPending(BIT_UART0);
pISR_EINT0= pISR_EINT2 =pISR_EINT3 = pISR_EINT4_7=(int)Key_ISR;
EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT3|BIT_EINT4_7);
EnableIrq(BIT_UART0);
EnableSubIrq(BIT_SUB_RXD0);
rEINTMASK=~(1<<4);
pISR_UART0=(unsigned) UART0RX_isr;

while(1)
{
  
}

return 0;
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

67

帖子

1

粉丝