打印
[ZLG-ARM]

请教:在使能了发送FIFO时发送中断是如何触发如何工作的?

[复制链接]
3341|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
海洋饼干|  楼主 | 2007-3-21 17:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    我在看ARM7 LPC2131 UART部分时,对在使能了发送FIFO时发送中断是如何触发如何工作的很不理解,我翻看了一些旧的帖子,有个是这样说的:当FIFO的容量少于或等于触发深度时触发THER中断,向发送FIFO中写入数据,直到发送FIFO容量大于触发深度时,复位中断。
    我看了之后,还是一头雾水。  比如,我使能了FIFO,触发深度为8,使能发送中断,用中断方式发送字符串,现在我想发送10个字符,那么这个过程是什么样的呢,中断是在什么时候触发的呢?
    请大家帮我解释,谢谢了。 

相关帖子

沙发
zlgARM| | 2007-3-22 08:38 | 只看该作者

RE

 海洋饼干:
    1、发送FIFO一直都默认使能的;
    2、发送FIFO没有触发深度设置的说法;
    发送FIFO和接收FIFO是两回事。
    最后,关于发送中断的触发,您只要知道,"您的UART发送完一个字符"就会触发中断。设置好IER寄存器,配置好VIC,打开IRQ中断,写好ISR,您做个试验试一试。

使用特权

评论回复
板凳
ourdoctor| | 2007-3-22 11:31 | 只看该作者

re

海洋饼干:
   接收可以实现 设置U0FCR的
7:6 Rx Trigger Level Select
00: trigger level 0 (1 character or 0x01h)
01: trigger level 1 (4 characters or 0x04h)
10: trigger level 2 (8 characters or 0x08h)
11: trigger level 3 (14 characters or 0x0eh)
These two bits determine how many receiver UART0 FIFO characters must be writtenbefore an interrupt is activated.

发送需要自己搞定了

使用特权

评论回复
地板
海洋饼干|  楼主 | 2007-3-23 10:28 | 只看该作者

再次请教各位强人!


    非常感谢2位大哥指点,我好象对发送FIFO有点儿明白了.我正在做UART的实验,我现在就是想先用上接收中断,CTI中断,使能FIFO,禁止发送中断.就是想我给ARM发什么,ARM就能在上位机再给返回什么.
    现在的实验现象是这样的:(设触发深度是8),发低于8个字符没问题,发挺多的也很好,就两种情况会出错,当发8的整数倍+1个字符和发8的整数倍+2个字符时就不行了.第一种情况会少2个字符,第二种情况会少1个字符.比如我想发123456789,会显示1234569;要发1234567890,会显示123456790.   真的是不明白,我感觉程序应该没错啊,别的时候一切都那么完美,咋就一到那种情况就不行呢?我本来想着是如果这样能调好,再加上发送中断,那UART的硬件及中断机制就都用上了吧.但现在还没加发送中断都拿不下,还请大家帮我看看哪里错了,谢谢大伙.程序如下:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:   main.c
** Last modified Date:  2004-09-16
** Last Version:  1.0
** Descriptions:  The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by:   Chenmingji
** Created date:  2004-09-16
** Version:    1.0
** Descriptions:  The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:   Chenxibing
** Modified date:  2005-01-17
** Version:
** Descriptions:  UART0通讯实验,中断方式,使用FIFO。
**
********************************************************************************************************/
#include "config.h"
/* 定义串口模式设置数据结构 */
typedef struct UartMode
{
 uint8 datab;  // 字长度,5/6/7/8可选
 uint8 stopb;  // 停止位,1/2可选
 uint8 parity;  // 奇偶校验位,0-无校验,1-奇校验,2-偶校验
}UARTMODE;
         
                    
char  *rcv_buf;        // UART0数据接收缓冲区
volatile uint8 rcv_new;   // 接收新数据标志
uint8 sum;                //计算字符串中字符的个数
/**********************************************************************************************************
** 函数名称 :IRQ_UART0()
** 函数功能 :串口0接收中断服务程序
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void __irq IRQ_UART0 (void)
{
 uint8 IIR;
uint8 i=0;
  while(((IIR = U0IIR) & 0x01) == 0)     //有中断未处理完 
    {
         rcv_new = 1;   // 设置接收到新的数据标志
         
         switch (IIR & 0x0e)
     {
  
      case 0x04:  
  
              for (;(i==0)||((i%8)!=0) ; i++)
             
           rcv_buf = U0RBR;  // 读取FIFO的数据,并清除中断 
               
      break;
      
      case 0x0c: 
  
              for (;(U0LSR&01)!=0;i++)
 
              rcv_buf = U0RBR;
      break;
      
      default:
      break;
        }
 } 
 sum=i;           
 VICVectAddr = 0x00;   // 中断处理结束
}
/*
*********************************************************************************************************
** 函数名称 :UART0_SendByte()
** 函数功能 :向串口0发送1字节数据
** 入口参数 :dat 要发送的数据
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendByte (uint8 dat)
{
 U0THR = dat; // 要发送的数据
 while ((U0LSR & 0x20) == 0); // 等待数据发送完毕
}
/*
*********************************************************************************************************
** 函数名称 :UART0_SendStr()
** 函数功能 :向串口0发送1字节数据
** 入口参数 :dat 要发送的数据
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendStr(char const *str)
{uint8 i;
 for(i=0;i<sum;i++)
 UART0_SendByte(*str++);
}
/*
*********************************************************************************************************
** 函数名称 :UART0_SendBuf()
** 函数功能 :向串口发送11个字符串数据
** 入口参数 :dat 要发送的数据
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendBuf (void)
{
  
   UART0_SendStr(rcv_buf);
   
  
 
}
/*
*********************************************************************************************************
** 函数名称 :UART0_Init()
** 函数功能 :串口初始化,设置工作模式和波特率。
** 入口参数 :baud 波特率
**     set 模式设置(UARTMODE数据结构)
** 出口参数 :1-初始化成功,  0-初始化失败
*********************************************************************************************************
*/
int8 UART0_Init (uint32 baud, UARTMODE set)
{
 uint32 bak;
 
 /* 参数过滤 */
 if ((baud ==0 ) || (baud > 115200)) return (0);
 if ((set.datab <5) || (set.datab > 8)) return (0);
 if ((set.stopb == 0) || (set.stopb > 2))  return (0);
 if (set.parity > 4) return (0);
 
 /* 设置串口波特率 */
 U0LCR = 0x80;      // DLAB = 1 
 bak   = (Fpclk >> 4) / baud;
 U0DLM = bak >> 8;
 U0DLL = bak & 0xFF;
 
 /* 设置串口模式 */
 bak   = set.datab - 5;    // 设置字长
 if (set.stopb == 2) bak |= 0x04; // 判断是否为2位停止位
 
 if (set.parity != 0)
 {
  set.parity = set.parity - 1;
  bak |= 0x08;
 }
 bak |= set.parity << 4;    // 设置奇偶校验
 
 U0LCR = bak;
 
 return (1);
}

/*
*********************************************************************************************************
** 函数名称 :main()
** 函数功能 :从串口UART0接收字符串"ABCDEFGH",并发送回上位机显示。
** 调试说明 :需要PC串口显示终端软件如EasyARM.exe。
*********************************************************************************************************
*/
int main (void)
{
 UARTMODE set;
   
 set.datab  = 8;
 set.stopb  = 1;
 set.parity = 0;
 
 rcv_new = 0;
 
 
 PINSEL0 = 0x00000005;    // 设置I/O连接到UART0
 
 UART0_Init(115200,set);   // 串口初始化
 U0FCR = 0x81;      // 使能FIFO,并设置触发点为8字节
 U0IER = 0x01;      // 允许RBR中断(即接收中断),禁止THRE中断(发送中断)
 
 IRQEnable();      // 使能IRQ中断
 /* 使能UART0中断 */
 VICIntSelect = 0x00000000;   // 设置所有的通道为IRQ中断
 VICVectCntl0 = 0x20 | 0x06;   // UART0分配到IRQ slot0,即最高优先级
 VICVectAddr0 = (uint32)IRQ_UART0; // 设置UART0向量地址
 VICIntEnable = 1 << 0x06;   // 使能UART0中断
    
    
 
 while (1)
 {
  if (rcv_new==1)
  { 
   rcv_new=0;
   UART0_SendBuf();
   
  }
 }
    return 0;
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

使用特权

评论回复
5
liujigan| | 2007-3-23 13:10 | 只看该作者

re

(1)中断中变量i定义为外部变量,把rcv_new = 1; 放到case 0x0c 后面试试
(2)实际产品中如果每次发送不到16个可以设置U0FCR=0xc1;这样就可一次接收下来再送出去。至于发送用中断我觉得意义不大。

使用特权

评论回复
6
海洋饼干|  楼主 | 2007-3-23 16:54 | 只看该作者

TO liujigan大哥


    (1)变量i是记录一次发送的字符串中字符的个数的,同时它还作为了字符串的结束标志(sum=i),所以i不能放在外头,不然下次再发的时候它就没法清零,那么第n次发的时候就会连同n-1次的一块发出去了.
    现在rcv_new = 1的位置就是把它同时放在 case 0x04:  和case 0x0c:后面的一个减写. 大哥你说是这样不?    
    (2)将来是想用ARM传图象,传的数据比较多哈哈. 我听人说很多商用的产品的代码中很少使用FIFO,它不好用吗?     谢谢大哥的回复.
    还请各位老大帮我看看到底是怎么回事,我是真找不出毛病.郁闷中!

使用特权

评论回复
7
liujigan| | 2007-3-23 17:17 | 只看该作者

to:海洋饼干老弟

(1)放到外面定义是记录是为二次传送累加和最后放入sum中(i放入内部不能二次累加),只有字符超时中断指示(CTI)才把rcv_new = 1,(当然只有接收不为8的整数倍时适用),rcv_new = 1放前面和放case 0x0c能一样吗?放前面哪条满足了都发。
(2)发完后当然要把i=0;不然乱了。

使用特权

评论回复
8
海洋饼干|  楼主 | 2007-3-27 16:15 | 只看该作者

谢谢liujigan和各位大哥的点拨!


    昨天终于把这个小程序调通了,就像liujigan大哥所说,得把i定义成外部变量,最后再把它清零,刚开始这样改完还是不行,实在没法了我就在i清零的后边又加了一句我认为可有可无的一句:sum清零,谁知道加上这句就好了.不管怎么说程序终于完美运行了哈哈.小弟再次感谢liujigan和各位大哥!

使用特权

评论回复
9
liujigan| | 2007-3-27 16:46 | 只看该作者

你快乐,我也高兴,一起进步嘛。

水潭先生的FIFO无限数据发送,可是相当不错的范例,值得一悟。

使用特权

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

本版积分规则

9

主题

12

帖子

0

粉丝