📄 main.c
字号:
/*--------------------------------------------------------------------------
LPCARM串口无限FIFO应用举例及祥解
本程序在周立功的LPC213x开发板上调试通过,用汽车电子的串口通V3.22进行32K字节
传送无误码。
本程序主要是模拟51的TI=1进行发送激励,同时对接收和发送FIFO进行测试。
软件设计采用软件自环真正地实现了“无限FIFO”.
本程序实际用了256个字节的缓冲区进行接收数据的暂存(用于发送目的),由于汽车
电子的缓冲区只用32K字节,故只能测试到32K字节传送无误码。
本程序的关键部分是经过近一年的产品考验得出的实战摘录。利用此思路可以很容易地
实现海量大速率数据传递。
菜地公告:引用本文必须注明出处!!!
菜农HotPower 2007.1.25 于西安大雁塔菜地 http://HotPower.21ic.org/
---------------------------------------------------------------------------*/
#include <LPC213xdef.h> //水鸟HotPower的LPCARM菜鸟作
#include "main.h" //配置头文件
/*-----------------------------------
串口0中断服务程序
-----------------------------------*/
void __irq IRQ_UART0 (void)
{
volatile unsigned int i,j;
unsigned char ch;
j= U0->IIR;
switch(j&0x0f){
// switch(U0->IIR & 0x0f) {
case 0x06://接收线状态
// switch (U0->LSR) {
// case 0x63:
// break;
// }
break;
/*-----------------------------------------------------------------
串口接收部分代码
用while循环从FIFO中快速地取出全部数据,也可不用循环每次取出一个字节
的数据但达不到FIFO的功效。
-----------------------------------------------------------------*/
case 0x04://接收数据可用
case 0x0c://字符超时指示
while (U0->LSR & 0x01) {//从FIFO中取出全部数据
ch = U0->RBR;//从FIFO中取出1个字符的数据
Uart.RxBuffer[Uart.RxCount ++] = ch;//暂存入缓冲区
}
/*-----------------------------------------------------------------
串口自发部分代码
这里主要利用软件自环来自发自收以方便演示。
-----------------------------------------------------------------*/
while (Uart.TxCount != Uart.RxCount) {
Uart.TxBuffer[Uart.TxCount] = Uart.RxBuffer[Uart.TxCount];//移入发送缓冲区
Uart.TxCount ++;
}
/*-----------------------------------------------------------------
串口激活部分代码
当Uart.TxBusy=1时表示串口忙正在发送数据,这是就不需用软件激活。
因为串口FIFO中最后一个字节的数据发送结束时还要引发一次中断。
否则在Uart.TxBusy=0时,由于串口闲,不可能进入发送中断。故需两种
办法来激活发送中断:
1.取出一个字节发送出去,在发送中断里再发送后续字节。
2.用VIC->SoftInt = (1 << VICIntSel_UART0);//模拟51的TI=1来引发发送中断
-----------------------------------------------------------------*/
if (!Uart.TxBusy) {//发送器不忙可以立即发送
VIC->SoftInt = (1 << VICIntSel_UART0);//模拟51的TI=1来引发发送中断
}
break;
/*-----------------------------------------------------------------
串口发送激活部分代码
由于U0->IIR & 0x0f==1时为LPCARM保留中断,可用于软件模拟激活UART0中断
利用此漏洞来实现非典的思想来达到实战的要求。
-----------------------------------------------------------------*/
case 0x01://LPCARM保留中断,可用于软件模拟激活UART0中断
if (!(VIC->SoftInt & (1 << VICIntSel_UART0))) {//硬件UART0中断
break;//正常的UART0中断退出
}
//至此成功利用了软件模拟中断偷入敌阵~~~继续运行,以达到发送首字符的目的
/*-----------------------------------------------------------------
串口发送部分代码
这里主要是充分地利用LPCARM的16个字节的FIFO来实现“无限FIFO”
-----------------------------------------------------------------*/
case 0x02://THRE中断
Uart.TxBusy = Uart.TxCount != Uart.TxdCount;//保证FIFO发送全部结束时,缓冲区空不拒绝发送
for (i = 0; (i < 16) && (Uart.TxCount != Uart.TxdCount); i ++) {//1次写入FIFO最多16个字节
ch = Uart.TxBuffer[Uart.TxdCount ++];//取出缓冲区1个字节数据
U0->THR = ch;//将缓冲区1个字节数据写入FIFO
}
VIC->SoftIntClr = (1 << VICIntSel_UART0);//这里必须清除此软件标志!!!
break;
}
VIC->VectAddr = 0x00; /* 通知VIC中断处理结束 */
}
void SystemInit(void)
{
// if (SystemRamTest != 0x55aa) {
// SystemRamTest = 0x55aa;
// }
VicInit();
PortInit();
UartInit();
}
void VicInit(void) //向量初始化
{
unsigned int i;
VIC->IntEnable = 0;
VIC->SoftIntClr = 0xffffffff;//清除所有软中断标志
VIC->IntSelect = 0;//全部中断为IRQ中断或默认中断
for(i = 0;i < 16;i++) {
VIC->VectCntls[i] = 0;
VIC->VectAddrs[i] = 0;
}
}
void PortInit(void)
{
PINSEL->PIN_SEL0 = 0x00000000; // 设置管脚连接GPIO
PINSEL->PIN_SEL1 = 0x00000000; // 设置管脚连接GPIO
PINSEL->PIN_SEL2 = 0x00000000; // 设置管脚连接GPIO
}
void UartInit(void)
{
unsigned int Fdiv;
Uart.TxCount = 0;
Uart.RxCount = 0;
Uart.TxdCount = 0;
Uart.RxdCount = 0;
Uart.TxBusy = 0;
PINSEL->PIN_SEL0 |= (P0_0_TXD0 << P0_0_PINSEL) | (P0_1_RXD0 << P0_1_PINSEL); //设置I/O连接到UART0
U0->LCR = 0x83;// DLAB=1,允许设置波特率
Fdiv = (Fpclk / 16) / UART_BPS;// 设置波特率38400
U0->DLM = Fdiv / 256;
U0->DLL = Fdiv % 256;
U0->LCR = 0x03;
U0->FCR = 0x87;/* 初始化FIFO 接收14个字节就中断*/
U0->IER = 0x07;/* 允许接收发送中断 */
VIC->VectAddrs[0] = (unsigned int)IRQ_UART0;
VIC->VectCntls[0] = VICIntSel_Enable//使能IRQ中断
| VICIntSel_UART0;//获取UART0的IRQ级别
VIC->IntEnable |= (1 << VICIntSel_UART0);
}
int main(void)
{
SystemInit();//系统初始化
while(1) {//本例主要是演示串口的FIFO,主循环不想做其他目的。
;// POWER->P_CON = 1;//_idle_() 休眠,串口中断可以苏醒。
//处于睡眠模式时不能使用JTAG
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -