共2条
1/1 1 跳转至页
quot,FIFO,quot 另一个"基于硬件FIFO和缓冲队列的"串口收发演示
问
//====LPC2132 串口演示==========================================================
/*
同样是"基于硬件FIFO和缓冲队列的"串口收发演示,EASYARM2132调试通过
如有调不通的,请发Email给wsg@bbn.cn, 我给你带改进别人摸板的完整压缩包
*/
//====加载包含文件==============================================================
#include <stdio.h>
#include <string.h>
#include "config.h"
//====常量定义==================================================================
#define BTL0 115200 //串口0波特率
#define U0_RBL 2048 //串口0接收缓冲长度
#define U0_WBL 2048 //串口0发送缓冲长度
//====全局变量定义==============================================================
//--串口0缓冲队列
uint8 U0_RBuf[U0_RBL]; //串口0接收缓冲区
uint16 U0_RPw=0,U0_RPr=0; //串口0接收存、取指针
uint8 U0_WBuf[U0_WBL]; //串口0中断内发送缓冲区
uint16 U0_WPw=0,U0_WPr=0; //串口0中断内发送存、取指针
uint8 U0_WS=1; //串口0发送空标志,1=可直接发送
//====函数原型定义==============================================================
//====中断函数实现代码==========================================================
//--串口0 收发中断
void __irq IRQ_UART0 (void)
{
uint8 IIR,xc;
uint16 w;
while (((IIR=U0IIR)&0x01)==0)
{
switch (IIR & 0x0e)
{
case 0x02: // 发送中断
for (xc=0; xc<15; xc++) //一次最多可发15字符
{
if (U0_WPw==U0_WPr)
{
U0_WS=1; //中断发送缓冲已空
break;
}
else
{
U0THR=U0_WBuf[U0_WPr++];
if (U0_WPr>=U0_WBL) U0_WPr=0;
}
}
break;
case 0x04: // 接收中断
case 0x0c:
xc=U0RBR;
w=U0_RPw;
U0_RPw++; if (U0_RPw>=U0_RBL) U0_RPw=0;
if (U0_RPw==U0_RPr) U0_RPw=w; //接收缓冲区满
else U0_RBuf[w]=xc;
break;
case 0x06: // 线状态中断
xc=U0LSR; // 清除出错中断
xc=U0RBR; // 读出出错字符并放弃
break;
default:
break;
}
}
VICVectAddr = 0x00; // 通知VIC中断处理结束
}
//====以下,目标板用户初始化子程序================================================
void TargetInit(void)
{
uint32 x;
//--目标板管脚连接 (配合VTDR-B.SCH)
PINSEL0 = 0x30E5D555;
PINSEL1 = 0x15580000;
//--初始化串口0
U0LCR = 0x80; // DLAB位置1
#if ((((Fpclk>>4)*10)/BTL0)%10) <= 5
x = (Fpclk>>4)/BTL0;
#else
x = ((Fpclk>>4)/BTL0)+1;
#endif
U0DLM = x>>8;
U0DLL = x&0xff;
U0LCR = 0x0b; // 00001011 8位数据位,1位停止位,奇校验
U0FCR = 0x07;
U0IER = 0x07;
//--设置VIC,初始化定时器0中断和A/D中断
VICIntSelect = 0x00; //所有通道设置为IRQ中断
VICVectCntl1 = (0x20 | 0x06); //设置串口0中断在通道2
VICVectAddr1 = (uint32)IRQ_UART0; //设置通道2中断服务程序地址
VICIntEnable = (1<<0x06); //使能上述中断
//--允许IRQ中断
IRQEnable();
}
//===通用子程序代码=================================================================
// 挂接printf函数用
int fputc( int c, FILE *f )
{
uint16 w;
if (U0_WS==1)
{
U0THR = (uint32)c;
U0_WS=0;
return ((uint32)c);
} else
{
w=U0_WPw;
U0_WPw++;
if (U0_WPw>=U0_WBL) U0_WPw=0;
if (U0_WPw==U0_WPr) //缓冲区满
{
U0_WPw=w;
return(-1);
} else
{
U0_WBuf[w]=c;
return((uint32)c);
}
}
}
//====以下,演示主程序===================================================
int main (void)
{
uint8 myBUF[2048];
uint16 myP=2046;
uint8 x;
uint8 *p;
printf("\r\n俗话说:\r\n能把简单事情搞复杂的是教授");
printf("\r\n能把复杂事情搞简单的是农民");
printf("\r\n言归正转,演示开始:《倒背如流》");
printf("\r\n村夫玩耍的规则是:");
printf("\r\n你送出一串西文字符以0x0d结束,看谁给你倒着送回来的快");
while(1)
{
while (U0_RPw!=U0_RPr) //接收缓冲队列有字符
{
x=U0_RBuf[U0_RPr++]; if (U0_RPr>=U0_RBL) U0_RPr=0; //取一个字符
myBUF[myP--]=x;
if (x==0x0d)
{
myBUF[2047]=0; p=&myBUF[myP+1];
printf("%s",p);
myP=2046;
}
}
}
return 0;
}
//====程序结束================================================================= 答 1: RE:非常欢迎“agnd”做出的努力,如果您能提供完整的Demo工程一些初学者学习更加方便。 答 2: 完整程序压缩包已经上传由于本人无法在本网站上传文件,所以文件已经上传到:
http://www.xiao-qi.com/comm/mydemo.rar
需要的可到http://www.xiao-qi.com下载
顺便向晓奇工作室致谢! 答 3: 答网友问有人发邮件说下载后编译出错,我又试了一下,问题在于你存的目录和我不一样,先把没用的udemo_Data目录删掉,把所有文件的只读属性去掉重新编译就没问题了。要是你的PC串口调试软件支持不了115200,就适当降点,我的PC没问题。 答 4: 会自己写的可能都共享了吧?还有谁有原创的LPC21XX串口程序?都贡献出来让大家看看嘛!
/*
同样是"基于硬件FIFO和缓冲队列的"串口收发演示,EASYARM2132调试通过
如有调不通的,请发Email给wsg@bbn.cn, 我给你带改进别人摸板的完整压缩包
*/
//====加载包含文件==============================================================
#include <stdio.h>
#include <string.h>
#include "config.h"
//====常量定义==================================================================
#define BTL0 115200 //串口0波特率
#define U0_RBL 2048 //串口0接收缓冲长度
#define U0_WBL 2048 //串口0发送缓冲长度
//====全局变量定义==============================================================
//--串口0缓冲队列
uint8 U0_RBuf[U0_RBL]; //串口0接收缓冲区
uint16 U0_RPw=0,U0_RPr=0; //串口0接收存、取指针
uint8 U0_WBuf[U0_WBL]; //串口0中断内发送缓冲区
uint16 U0_WPw=0,U0_WPr=0; //串口0中断内发送存、取指针
uint8 U0_WS=1; //串口0发送空标志,1=可直接发送
//====函数原型定义==============================================================
//====中断函数实现代码==========================================================
//--串口0 收发中断
void __irq IRQ_UART0 (void)
{
uint8 IIR,xc;
uint16 w;
while (((IIR=U0IIR)&0x01)==0)
{
switch (IIR & 0x0e)
{
case 0x02: // 发送中断
for (xc=0; xc<15; xc++) //一次最多可发15字符
{
if (U0_WPw==U0_WPr)
{
U0_WS=1; //中断发送缓冲已空
break;
}
else
{
U0THR=U0_WBuf[U0_WPr++];
if (U0_WPr>=U0_WBL) U0_WPr=0;
}
}
break;
case 0x04: // 接收中断
case 0x0c:
xc=U0RBR;
w=U0_RPw;
U0_RPw++; if (U0_RPw>=U0_RBL) U0_RPw=0;
if (U0_RPw==U0_RPr) U0_RPw=w; //接收缓冲区满
else U0_RBuf[w]=xc;
break;
case 0x06: // 线状态中断
xc=U0LSR; // 清除出错中断
xc=U0RBR; // 读出出错字符并放弃
break;
default:
break;
}
}
VICVectAddr = 0x00; // 通知VIC中断处理结束
}
//====以下,目标板用户初始化子程序================================================
void TargetInit(void)
{
uint32 x;
//--目标板管脚连接 (配合VTDR-B.SCH)
PINSEL0 = 0x30E5D555;
PINSEL1 = 0x15580000;
//--初始化串口0
U0LCR = 0x80; // DLAB位置1
#if ((((Fpclk>>4)*10)/BTL0)%10) <= 5
x = (Fpclk>>4)/BTL0;
#else
x = ((Fpclk>>4)/BTL0)+1;
#endif
U0DLM = x>>8;
U0DLL = x&0xff;
U0LCR = 0x0b; // 00001011 8位数据位,1位停止位,奇校验
U0FCR = 0x07;
U0IER = 0x07;
//--设置VIC,初始化定时器0中断和A/D中断
VICIntSelect = 0x00; //所有通道设置为IRQ中断
VICVectCntl1 = (0x20 | 0x06); //设置串口0中断在通道2
VICVectAddr1 = (uint32)IRQ_UART0; //设置通道2中断服务程序地址
VICIntEnable = (1<<0x06); //使能上述中断
//--允许IRQ中断
IRQEnable();
}
//===通用子程序代码=================================================================
// 挂接printf函数用
int fputc( int c, FILE *f )
{
uint16 w;
if (U0_WS==1)
{
U0THR = (uint32)c;
U0_WS=0;
return ((uint32)c);
} else
{
w=U0_WPw;
U0_WPw++;
if (U0_WPw>=U0_WBL) U0_WPw=0;
if (U0_WPw==U0_WPr) //缓冲区满
{
U0_WPw=w;
return(-1);
} else
{
U0_WBuf[w]=c;
return((uint32)c);
}
}
}
//====以下,演示主程序===================================================
int main (void)
{
uint8 myBUF[2048];
uint16 myP=2046;
uint8 x;
uint8 *p;
printf("\r\n俗话说:\r\n能把简单事情搞复杂的是教授");
printf("\r\n能把复杂事情搞简单的是农民");
printf("\r\n言归正转,演示开始:《倒背如流》");
printf("\r\n村夫玩耍的规则是:");
printf("\r\n你送出一串西文字符以0x0d结束,看谁给你倒着送回来的快");
while(1)
{
while (U0_RPw!=U0_RPr) //接收缓冲队列有字符
{
x=U0_RBuf[U0_RPr++]; if (U0_RPr>=U0_RBL) U0_RPr=0; //取一个字符
myBUF[myP--]=x;
if (x==0x0d)
{
myBUF[2047]=0; p=&myBUF[myP+1];
printf("%s",p);
myP=2046;
}
}
}
return 0;
}
//====程序结束================================================================= 答 1: RE:非常欢迎“agnd”做出的努力,如果您能提供完整的Demo工程一些初学者学习更加方便。 答 2: 完整程序压缩包已经上传由于本人无法在本网站上传文件,所以文件已经上传到:
http://www.xiao-qi.com/comm/mydemo.rar
需要的可到http://www.xiao-qi.com下载
顺便向晓奇工作室致谢! 答 3: 答网友问有人发邮件说下载后编译出错,我又试了一下,问题在于你存的目录和我不一样,先把没用的udemo_Data目录删掉,把所有文件的只读属性去掉重新编译就没问题了。要是你的PC串口调试软件支持不了115200,就适当降点,我的PC没问题。 答 4: 会自己写的可能都共享了吧?还有谁有原创的LPC21XX串口程序?都贡献出来让大家看看嘛!
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |