您的位置:首页 > 理论基础 > 数据结构算法

串口通讯程序(中断方式)

2008-01-23 15:39 267 查看
把我用的串口通讯程序(中断方式)搭个便车让大家看看,并非原创,从<<嵌入式系统构件>>的相关代码移植而来。
#include "../inc/includes.h"

char xdata ser_buffer[SERIAL_BUFF_SIZE];  /* the receive buffer*/

int ser_end = -1;
int ser_start=-1;      /* indexes into receive buffer*/
int ser_ch;
int char_ready=0;           /* current character and ready flag*/

int serial_lock = 0;                /* serial ISR semaphore so the buffer*/
                                 /* isn't altered will it is being written*/
//功能介绍:串口通讯中断服务程序。
//入口参数:无
//出口参数:无
//备注:系统开中断后由中断触发执行。
void  Serial_Isr(void) interrupt 4
{
   
/* this is the ISR (Interrupt Service Routine) for the com port.  It is very*/
/* simple.  When it gets called, it gets the next character out of the receive*/
/* buffer register 0 and places it into the software buffer. Note: C takes care*/
/* of all the register saving and house work.  Cool huh!*/

            /* lock out any other functions so the buffer doesn't get corrupted*/
    if(TI)
    {
        //TI = 0;
        return ;
    }
   
    if ( !RI )
    {
        return ;                         //有数据或无数据用1、0表示   
    }  
    serial_lock = 1;        /*封锁对串行缓冲区的其它操作*/

            /* place character into next position in buffer*/

    ser_ch = SBUF;
    if (++ser_end > SERIAL_BUFF_SIZE-1)
    {
        ser_end = 0;        /*寻找到循环缓冲区的结尾位置*/
    }

    ser_buffer[ser_end] = ser_ch;       /*将串行口读取到的数据放入队列尾部*/

    ++char_ready;               /*接收数量计数器加1 */

    serial_lock = 0;            /*打开对串行接收数据缓冲区的锁定*/
    RI = 0;
}

/*///////////////////////////////////////////////////////////////////////*/
//功能介绍:检查缓冲区是否接收到数据。获取收到的数据的数量
//入口参数:无
//出口对数:返回接收的数据个数,没有数据返回0
//备注:

int Ready_Serial(char SeriesComID)
{
    SeriesComID = SeriesComID;
    return(char_ready);

}

/*/////////////////////////////////////////////////////////////////////////*/
// 功能介绍:从串行缓冲接收区中读取1个数据
// 入口参数:存放读取到的数据的地址指针
// 出口参数: 读取成功,返回1,失败时,返回数据0
// 备注:
int Serial_Read(char SeriesComID,char *RdData)
{
        /* wait for isr to end*/

    SeriesComID = SeriesComID;

    while(serial_lock);     /*等待串行接收中断完成*/
    if (ser_end != ser_start)
    {

        if (++ser_start > SERIAL_BUFF_SIZE-1)   /*移动头指针, 找到读取数据的位置*/
            ser_start = 0;

        *RdData = ser_buffer[ser_start];         /*从缓冲区中取数*/
                                                /*并送到入口变量中*/
        if (char_ready > 0)             /*接收数据数量计数器减1*/
            --char_ready;

        return(1);     /*返回读取到数据的成功标志*/

    } 
    else
    {
        return(0);      /*读取失败时,返回读取失败的标志*/
     }
}

//功能介绍:将字符的内容从串行口发出
//入口参数:准备发送的数据
//出口参数:无
//备注:   程序中没有使用超时退出机制,如果硬件发生故障,会出现死循环.
void Serial_Write(char SeriesComID,char ch)
{
    SeriesComID = SeriesComID;

    SBUF = ch;
    while ( !TI );
    TI = 0;
}

//功能介绍:打开串行口
//  入口参数:     port_base 使用串行口的端口号
//                baud    串行口设定的波特率
//                configuration 串行口工作参数设置,包括数据位数,剞偶校验等
//  出口参数:
//      备注: 请使用头文件中定义的符号常量来设置工作参数
void Open_Serial(int port_base, int baud, int configuration)
{
    port_base = port_base;
    baud = baud;
    configuration = configuration;

    //串口初始化
    SCON = 0x52;                                //设置串口
    PCON &= 0x80;

    TMOD = 0x20;
    TH1  = 0xFB;                                //波特率19200
    TL1  = 0xFB;                               
   
    TR1  = 1;
    TI = 0;
   
    ES = 1;            //允许串口中断
    EA = 1;
   
}

/*功能介绍:关闭串行口
  入口参数:将关闭的串行口号
  出口参数:无
    备注:
*/
void Close_Serial(int port_base)
{
    port_base = port_base;
    ES = 0;
}

嵌入式系统构件  Embedded Systems Building Blocks: Complete and Ready-to-Use Modules in C (Hardcover) Jean J. Labrosse (Author) ,准备看之中……

分析一下程序的组成:
打开串行口 void Open_Serial(int port_base, int baud, int configuration)
关闭串行口 void Close_Serial(int port_base)
将字符的内容从串行口发出 void Serial_Write(char SeriesComID,char ch)
从串行缓冲接收区中读取1个数据 int Serial_Read(char SeriesComID,char *RdData)
检查缓冲区是否接收到数据/获取收到的数据的数量int Ready_Serial(char SeriesComID)
串口通讯中断服务程序  void  Serial_Isr(void) interrupt 4

使用的数据结构:数组,循环数组

使用semaphore来控制对缓存的访问,只是在void  Serial_Isr(void) interrupt 4使用,在int Serial_Read(char SeriesComID,char *RdData)中使用,不怕在读取过程中发生中断吗?读取一个字符这样做可能比较不错,如果字符多了,可能就有点危险的,我认为,在读一个字符的情况下,这样就足够了吧

如何加入超时机制呢?

 以后再来修改^^^^^超时机制  环数据结构
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息