正文

把LPC900的串口模拟程序移植到了LPC922,很稳定2008-04-12 20:18:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/niao0311/34105.html

分享到:

把LPC900的串口模拟程序移植到了LPC922,很稳定    yuzhuju 发表于 2005-6-14 11:49 Philips LPC900单片机 感觉LPC900写的程序可读性很好,不像有些网友的C语言里面都偏僻语法,看上去好象很高深厉害,实际可读性一点都不好.第一次用模拟串口,感觉收发很稳定,谢谢LPC900. /*用I/O模拟串行口例程(LPC900)    下面的程序是我以前写的,适合于80C52内核的单片机,不能直接用在LPC900系列单片机上。我现在懒了,    不想再修改,如果要用,您自己动手做一些修改吧:    首先,该程序中的定时器用的是T2,然而LPC900系列单片机中没有T2。您可以将其换成T0或者是T1。    RXD_pin和TXD_pin的属性要重新做一些设置,使之能够在您的LPC900单片机上运行。    晶振不能用22.1184MHz那么高,建议用低于12MHz的晶振或者直接使用片内RC振荡器。*/ /*    52单片机实用的IO模拟串行口C语言源程序    作者:LPC900    移植: saint(yuzhuju)    用途:短距离、波特率要求不高、环境干扰不大的场合    特点:        程序简练、实用、移植方便        占用定时器T0        只消耗约600字节的ROM        有详细的注释    参数:        晶振  :7.373MHz        波特率:2400        起始位:1        数据位:8        校验位:无        停止位:1    -----------------------    yuzhuju:    感觉程序中的HITS只有在判断开始位时,才有实际意义,    其它HITS使用场合中,如果不是每次采样都和上次结果作比较判断,意义就不是很大,只能凑个接收周期    不知道理解对不对.    -----------------------*/ extern void Uart2Init(void);//初始化extern void TXD_Send_String(const unsigned char s[]);//发送字符串函数extern void Uart2Task(void);//放在主函数WHILE(1)中,一旦收到结束符号'?',把RXD_buf中收到的数据发送回来   #i nclude <REG922.H> //修改如下定义将方便程序移植sbit RXD_pin = P0^4;  //定义接收引脚sbit TXD_pin = P0^5;  //定义发送引脚#define MAIN_CLK    7373000    //定义主频#define BAUD_RATE   2400       //定义波特率(数值不能太高,因为要给T2中断服务程序留足执行时间)#define HITS        8          //定义采样率(应当是偶数;减少采样率能提高波特率,但为保证可靠工作,最小不能少于6次) #define RXD_BUF_LEN  16  //定义接收缓冲区大小volatile unsigned char RXD_buf[RXD_BUF_LEN];  //定义接收缓冲区(循环队列)volatile unsigned char RXD_p1;  //指向缓冲区,由中断程序自动修改volatile unsigned char RXD_p2;  //指向缓冲区,由主程序修改 #define TXD_BUF_LEN  16  //定义发送缓冲区大小volatile unsigned char TXD_buf[TXD_BUF_LEN];  //定义发送缓冲区(循环队列)volatile unsigned char TXD_p1;  //指向TXD_buf,由主程序修改volatile unsigned char TXD_p2;  //指向TXD_buf,由中断程序修改volatile bit U2TEnable; //定时器T0初始化void Time0Init(void){    unsigned char TimeValue;    TAMOD&=(~0x01);//T0M2=0    TMOD|=0X02;//T0M1=1    TMOD&=(~0X01);//T0M0=0,T0 MODE 2    TMOD&=(~0X04);//设置为定时器功能;    TMOD&=(~0X08);//设置为TR0使能定时器    IP0H|=0x02;//设置T0为最高优先级中断    IP0|=0x02;       TimeValue=256 - ( MAIN_CLK / 2 ) / ( BAUD_RATE * HITS );  //此公式值得你琢磨一下    //好象只能设置到2400,再低就要溢出了    TH0 = TimeValue;    TL0 = TimeValue;       ET0= 1;    TR0 = 1;} //接收初始化void RXDInit(void){    unsigned char i;    P0M1 &= ~(0X01 << 4); //PortSet(0,4,GPIO);把P0.4设置为GPIO    P0M2 &= ~(0X01 << 4);    RXD_pin = 1;    RXD_p1 = 0;    RXD_p2 = 0;    for(i=0;i<16;i++)//RXD_BUF_LEN    {        RXD_buf[i] = 0x00;    }} //发送初始化void TXDInit(void){    unsigned char i;    P0M1 &= ~(0X01 << 5); //PortSet(0,5,GPIO);把P0.5设置为GPIO    P0M2 &= ~(0X01 << 5);    TXD_pin = 1;    TXD_p1 = 0;    TXD_p2 = 0;    for ( i=0; i< TXD_BUF_LEN; i++ )    {TXD_buf[i] = 0x00;}} //发送单个字符void TXD_Send_Char(const unsigned char c){    unsigned char p;  //临时变量    p = TXD_p1 + 1;    if ( p >= TXD_BUF_LEN ) p = 0;    while ( p == TXD_p2 );  //判断发送缓冲队列是否已满,如果是,则暂时不能发送    TXD_buf[TXD_p1] = c;  //先将c写入队列    TXD_p1 = p;  //再修改TXD_p1    //在T2中断服务程序里会自动完成发送} //发送字符串(不包括末尾的'\0')void TXD_Send_String(const unsigned char s[]){    unsigned char c;    unsigned int i = 0;        for (;;)        {            c = s[i++];            if ( c == '\0' ) break;            TXD_Send_Char(c);        }} //定义接收缓冲字符volatile unsigned char bdata RXD_ch;sbit RXD_ch_MSB = RXD_ch^7; //定义发送缓冲字符volatile unsigned char bdata TXD_ch;sbit TXD_ch_LSB = TXD_ch^0; //T2中断服务程序//每中断HITS次处理1位static void IRQTIME0() interrupt 1 using 3{//定义接收所需要的变量    static bit RXD_doing = 0;  //正在接收的标志    static unsigned char RXD_t = HITS/2;  //接收时计数T2的中断次数    static unsigned char RXD_cnt;  //接收时bit位的计数器//定义发送所需要的变量    static bit TXD_doing = 0;  //正在发送的标志    static unsigned char TXD_t;  //发送时计数T2的中断次数    static unsigned char TXD_cnt;  //发送时bit位的计数器//先清除TF2    TF0 = 0;//接收数据    if( RXD_doing )  //正处于接收状态        {        if( --RXD_t == 0 )  //经过了HITS个采样脉冲           {            if( RXD_cnt == 0 )  //8个数据位接收完毕                {                if( RXD_pin )  //检测到停止位                        {                                RXD_t = RXD_p1 + 1;  //在这里,RXD_t作为临时变量                                if ( RXD_t >= RXD_BUF_LEN ) RXD_t = 0;                                if ( RXD_t != RXD_p2 )  //如果接收缓冲队列未满                                {                                    RXD_buf[RXD_p1] = RXD_ch;                                    RXD_p1 = RXD_t;                                    if(RXD_ch=='?'){U2TEnable=1;}                                }                                else                                {                                    //如果接收缓冲队列已满,只好丢弃新收到数据                                }                        }                        else  //检测停止位时出错                        {                                //舍弃新收到的数据                        }                        RXD_doing = 0;  //接收全部完毕,清除正在接收的标志                        RXD_t = HITS/2;  //恢复RXD_t的初始值                    }                    else  //接收数据位                    {                        RXD_ch >>= 1;                        RXD_ch_MSB = RXD_pin;                        //上面2条语句若用{CY=RXD_pin; CY=(RXD_ch&0x01); RXD_ch=ACC;}代替,效率更高                        RXD_cnt--;                        RXD_t = HITS;                    }            }    }    else  //检测起始位[/#]    {            if ( RXD_pin )            {                    RXD_t = HITS/2;            }            else            {                    RXD_t--;                    if ( RXD_t == 0 )  //连续HITS/2次采样RXD_pin都是0,就可以确认起始位                    {                       //启动接收                      RXD_t = HITS;                      RXD_cnt = 8;                      RXD_doing = 1;            }            }    }//发送数据    if ( TXD_doing )  //正处于发送状态        {            TXD_t--;            if ( TXD_t == 0 )            {                    if ( TXD_cnt == 0 )  //发送全部完毕                    {                        TXD_doing = 0;  //清除正在发送的标志                    }                    else                    {                        if ( TXD_cnt == 1 )  //8个数据位发送完毕                        {                                TXD_pin = 1;  //发送停止位                        }                        else  //发送数据位                        {                                TXD_pin = TXD_ch_LSB;                                TXD_ch >>= 1;                            //上面2条语句若用{CY=(TXD_ch&0x01); TXD_pin=CY; TXD_ch=ACC;}代替,效率更高                        }                        TXD_cnt--;                        TXD_t = HITS;                    }            }        }        else        {            if ( TXD_p2 != TXD_p1 )  //如果发送缓冲队列不空            {                //从发送缓冲队列中取出要发送的数据                    TXD_ch = TXD_buf[TXD_p2++];                    if ( TXD_p2 >= TXD_BUF_LEN ) TXD_p2 = 0;                //启动发送                    TXD_doing = 1;                    TXD_cnt = 9;                    TXD_t = HITS;                //先发送起始位                    TXD_pin = 0;            }            else            {                    //发送缓冲队列是空的,不发送任何数据            }        }} //系统初始化void Uart2Init(void){    TXDInit();    RXDInit();    Time0Init();    U2TEnable=0;} void Uart2Task(void){        unsigned char c;    if(U2TEnable)    {        while ( RXD_p2 != RXD_p1 )        {            c = RXD_buf[RXD_p2++];            if ( RXD_p2 >= RXD_BUF_LEN ) RXD_p2 = 0;            TXD_Send_Char(c);        }           TXD_Send_String("Return Data Over.\r\n");        U2TEnable=0;    }} //主程序void main(void){    Uart2Init();    TXD_Send_String("The author is 21IC LPC900.\r\n");    {        Uart2Task();    } }

阅读(2083) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册