io 模拟串口

来源:互联网 发布:查看数据库挂的命令 编辑:程序博客网 时间:2024/05/29 10:43

2脚做模拟串口的接收端,发送端用串口0就可以了, 不用模拟。

下面是模拟串口的程序,2脚是p0.22

整体思想:2脚定义为捕获输入功能,下降沿捕获,当下降沿到来的时候进入中断处理函数。在中断处理中,开启52us定时器,同时禁止捕获中断。然后等待下一次52us定时中断到来时,进入中断处理函数读取起始位的电平,如果是低电平,说明起始位有效,则开启104us的中断,准备数据位的接收。如果无效的话,则关闭定时器,重新开启捕获中断,捕获起始位。如果起始位有效的,那么在定时器的下一次中断中就开始接收数据,判断接收的bit数是否小于8,若是的话,就继续接收,若不是,就将接收到的8个bit的数据存入接收数组中。如果接收到的字符是回车/r,则将接收标志位置位,然后主程序中检测到标志位置位就开始发送数据到串口0。

#include "config.h"
#include"lpc214x.h"
#include"type.h"
#include"irq1.h"
 
/***************************************************************
功能:  模拟串口收发口定义
***************************************************************/
//#define SimuTXD   0x00000001   //p0.0作为发送口,这里发送口不需要模拟,所以不需定义
#define SimuRXD    1<<22   //模拟串口接收口p0.22  

#define baudrate  9600 
#define SimuRxBuffSize  1024   //模拟串口接收缓冲区大小
#define Fpclk 14745600*5/4 
uint8 SimuUartRxBuff[SimuRxBuffSize]; //模拟串口接收缓冲区
uint8 SimuRxIndex=0;              //软件串口接收位置指针
uint8 ReciveData=0;        

           
/****************************************************************************
* 名   称: IRQ_SimuUart()
* 功   能: 模拟串口接收中断服务函数
* 入口参数: 
* 出口参数: 
****************************************************************************/
void IRQ_SimuUart(void) __irq
 {  
 static uint8 count,temp; 

    if((T0IR&0x10)!=0)//捕获到起始位,这个中断是由捕获通道产生的
     { 
     T0IR =0x10;  //复位由捕获产生的中断,即清除中断
        T0TC=0;      //将计数器0的值复位
  T0TCR=0x03;  //启动定时器,并复位定时器
     T0TCR=0x01;  //启动定时器
  T0CCR=0x00;  //禁止捕获中断
     T0MCR=0x18;  //允许MR1匹配,即延时52us


  }
    else if ((T0IR&0x02)!=0) //起始位定时检测,这个中断是由定时器产生的,这是MR1的匹配中断
       {        
      T0IR =0x02;       //复位匹配中断,清除中断 
      if((IOPIN0&(SimuRXD))==0)//判断起始位是否有效,如果有效的话,做if 
      {   T0TCR=0x03;  //启动定时器,并复位定时器
         T0TCR=0x01;  //启动定时器
      T0MCR=0xC0;  //允许MR2匹配,即延时104us
            count=0;
         temp=0;
   
  

      }
      else           //如果无效的话
       {

            T0MCR=0x00;  //禁止匹配
            T0CCR=0x06;  //重新捕捉起始位,设置下降沿捕获,并且捕获发生时产生中断
           T0TCR=0x02;  //计数器复位,但并不使能,若使能的话:T01TCR=0x03
            T0TC = 0; //停止定时器
         
         }
    }
    else if ((T0IR&0x04)!=0)  //数据位定时检测,这是MR2的匹配中断
    {       
      T0IR =0x04;            //清除中断
    if (count<8)    //如果count<8,则接收数据
      {  T0TCR=0x03;
          T0TCR=0x01;
         temp >>=1;
         if ((IOPIN0&(SimuRXD))!=0)   //若接收的数据是高电平
         {   
          temp |=0x80;
         }      
         count++;
  
       }
      else 
      {  
     
            T0MCR=0x00;                             //禁止匹配中断
            T0CCR=0x06;            //重新捕捉起始位
            T0TCR=0;        //禁止计数器使能以及计数器复位
            T0TC=0;           //定时器计数器清零
            SimuUartRxBuff[SimuRxIndex] = temp;    //读取FIFO的数据,并清除中断标志
   if(SimuUartRxBuff[SimuRxIndex]=='/r')  //若收到换行符就将收到数据标志位置1
            ReciveData=1;
            SimuRxIndex++;
      if (SimuRxIndex>=SimuRxBuffSize)   
            SimuRxIndex=0;
  }
  }

    VICVectAddr = 0x00;                 // 中断处理结束
 }               
 
/****************************************************************************
* 名   称: InitSimuUart()
* 功   能: 初始化模拟串口
* 入口参数: 
* 出口参数: 
****************************************************************************/
void InitSimuUart(uint16 Baud)
{  PINSEL1 = (PINSEL1 & 0xFFFFCFFF) | 0x00002000; //设置RXD引脚工作在捕捉模式 P0.22:CAP0.0 
    T0TC=0;
    T0PR=0;
    T0CCR=0x06;        //设定捕捉CAP0下降沿并中断
    T0MR2=Fpclk/Baud;  //每个比特的传输时间,也是传输的位时间
    T0MR1=Fpclk/(Baud*2); //起始位定时检测时间,为位传输时间的一半 ,Fpclk不是外部晶振的频率
    T0TCR=0x03;   //复位定时器
    T0IR=0xff;                 //清除所有中断
   VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
   VICVectCntl0 = 0x20|0x04;  // 软串口中断通道分配到IRQ slot 0,
   VICVectAddr0 = (uint32)IRQ_SimuUart;// 设置软串口向量地址
   VICIntEnable = 1<<0x04;    // 使能定时器1的中断
                        
}
 
 
//****************************************************************************
* 名   称: SimuSendStr
* 功   能:向串口0发送字符串
* 入口参数: 
* 出口参数: 
****************************************************************************/

void SimuSendStr(uint8 *buf,uint16 lenght)
{   uint16 i;

    IOCLR0=0x20000000;      //绿灯亮,代表接收到数据,并且开始发到串口0了

    for (i=0;i<lenght;i++)
   {  U0THR =*(buf+i);
    while((U0LSR&0x40)==0);//等待发送FIFO中的数据被取走
    }

  
     SimuRxIndex=0;  //
     ReciveData=0;  //接收标志清零
               
}

/******************************************************************************
** Function name:delay1()

** Descriptions:延时函数
**    
**
** parameters: time

** Returned value: None
**
******************************************************************************/   
void delay1(int time)
{
 {
  long int i=0;
  for(i=0;i<14745600*time/4000;i++); 
 }
}
/******************************************************************************
** Function name:GPIOInit()
**
** Descriptions:初始化GPIO口
**    
**
** parameters: None
** Returned value: None
**
******************************************************************************/
 void GPIOInit( void )
  {   
     SCS = 0;          /* set GPIOx to use regular I/O */
     PINSEL2= 0x00000000;
     IODIR1 = 0xFFDFFFFF;/* P1.16输出,p1.21输入,其余不用的脚定义为输出*/
     IOPIN1 = 0xFFFEFFFF;/*除了p1.16输出低电平,其余的均输出高电平*/
     PINSEL0= 0x80050005;/*将p0.15配置为EINT2,配置p0.0,p0.1为TXD,RXD,P0.8,P0.9为TXD,RXD*/
     PINSEL1= 0x00002000;//p0.22作为捕获功能
     IODIR0 = 0xFFBF7DFD;/*设置p0.16,p0.29(绿灯),p0.30(红灯)输出,p0.15,P0.22,P0.1,P0.9输入,其中p0.22用于捕获

                                              输 入,产生中断。其余不用的脚均为输出。*/
    IOPIN0 = 0xFFFFFFFF;/*设置所有的脚输出高电平*/  
    IOCLR0 = 0x00010000;//在p0.16置1s低电平
    delay1(1000); //延时1s,p0.16置1s低电平是开机的时间   

    IOSET0=0x00010000;//将p0.16置高
    return;
  }

 

 /******************************************************************************
** Function name:uartini
**
** Descriptions:初始化UART口
**    
**
** parameters: None
** Returned value: None
**
******************************************************************************/ 

void uart0ini(uint16 BaudR)            //串口初始化
 {  unsigned int Fdiv=0;
    U0LCR = 0x83;                     //9600,8,N,1
    Fdiv = ( Fcclk / 64 ) / BaudR ;    //设定波特率
    U0DLM = Fdiv / 256;                   
    U0DLL = Fdiv % 256;
    U0LCR = 0x03;               //DLAB = 0
 } 

 

 

/******************************************************************************
** Function name:main()
**
** Descriptions:实现软串口功能
**    
**
** parameters: None
** Returned value: None
**
******************************************************************************/
main()
{//PINSEL0 = 0x00050005;        //打开 P0.0,P0.1的串口功能
  GPIOInit();                  //初始化GPIO口
  InitSimuUart(9600);  //初始化模拟串口

  uart0ini(9600);     //初始化串口0
  IOCLR0=0x40000000;    //红灯亮,表示程序在工作

  while(1)  
 {  if(ReciveData==1)      //查询是否有新的数据到来
   { SimuSendStr(SimuUartRxBuff,SimuRxIndex);
   }
    IOSET0=0x20000000; //关闭绿灯表示数据发送完毕
 }
}

0 0
原创粉丝点击