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; //关闭绿灯表示数据发送完毕
}
}