打印

【赛元微单片机专题】源程序讲解[4] UART

[复制链接]
450|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xys9190|  楼主 | 2020-11-12 17:48 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xys9190 于 2020-11-12 17:52 编辑

SC92F8463通常会提供一个UART0以及SPI/TWI/UART三选一串行接口SSI,主要用于驱动模块电路或者其他UART通信接口的驱动芯片。
模式0,8位半双工同步通信模式。
模式1,10位全双工异步通信,由1个起始位,8个数据位和1个停止位组成,通信波特率可变。
模式3,11位全双工异步通信,由1个起始位,8个数据位,一个可编程的第9位和1个停止位组成,通信波特率可变。
模式1与模式3可选择定时器1及定时器2作为TX和RX的波特时钟源。
BaudRate = fsys/[TH1,TL1];
对应的GPIO  TX,RX 设置为带上拉输入模式。

源程序:
//UART ok
SCON = 0x50;                                                //10位模式
//UART0
TMCON = TMCON | 0x04;         //
T2MOD = 0;                                                        //时钟输入
//TL2 = 0x83;
//TH2 = 0x06;
RCAP2L = 0x83;                                        //16000000/1667 = 9600
RCAP2H = 0x06;
T2CON |= 0x30;                                        //T2作为UART波特率发生器存在0x34
TR2 = 0;
ET2 = 0;
EUART = 1;


我们采用中断的方式来发送数据,发送数据前对前局变量赋值
void TrUart(unsigned char instruct,unsigned char cdata)
{
        trIntruct = instruct,
        trCdata = cdata;
        
        trData = 0x55;
        SBUF = trData;

}
当发送完成触发中断执行,下面中断函数,以发送和接收数据
void RevUart0() interrupt 4
{
        if(RI)                      //中断接收
        {
                REN = 0;
                rcvUartdata[rcvUartCount] = SBUF;                                                                                                                                                                //接收数据到缓存
        
                if((rcvUartCount % 5 == 0)&&(rcvUartdata[rcvUartCount] != 0x55))                                //检测帧头
                {
                        rcvUartdata[rcvUartCount] = 0;
                }
                else if((rcvUartCount % 5 == 1)&&(rcvUartdata[rcvUartCount] != 0xaa))
                {
                        rcvUartdata[rcvUartCount] = 0;
                        rcvUartdata[rcvUartCount-1] = 0;
                        rcvUartCount = rcvUartCount - 1;
                }
                else if((rcvUartCount % 5 == 4)&&(rcvUartdata[rcvUartCount] != 0xfa))                //检测帧尾
                {
                        rcvUartdata[rcvUartCount] = 0;
                        rcvUartdata[rcvUartCount-1] = 0;
                        rcvUartdata[rcvUartCount-2] = 0;
                        rcvUartdata[rcvUartCount-3] = 0;
                        rcvUartdata[rcvUartCount-4] = 0;
                        rcvUartCount = rcvUartCount - 4;
                }
                else
                {
                        if(rcvUartCount % 5 == 4)
                        {
                                revOk** = 1;
                        }
                        rcvUartCount ++;
                }
               
                if(rcvUartCount == 20)
                {
                        rcvUartCount = 0;
                }
                RI = 0;
                REN = 1;
        }
        

        if(TI)                              //中断发送
        {
                TI = 0;
                uartTx0** = 1;
                trStep++;
                if(trStep == 1)
                {
                        trData = 0xaa;
                        SBUF = trData;
                }
                else if(trStep == 2)
                {
                        SBUF = trIntruct;
                }
                else if(trStep == 3)
                {
                        SBUF = trCdata;
                }
                else if(trStep == 4)
                {
                        trData = 0xfa;
                        SBUF = trData;
                }
                else if(trStep == 5)
                {
                        trStep = 0;        
                }
        }
}



//uart数据处理--------------------------------------------------------------------------------------------------
if(revOk**)                //接收完成数据 检查数据帧内容是否正确接收。
{
        for(arrayCount = 0;arrayCount < 20; arrayCount += 5)
        {
                if((rcvUartdata[arrayCount] == 0x55)&&(rcvUartdata[arrayCount+1] == 0xaa)&&(rcvUartdata[arrayCount+4] == 0xfa))
                {
                        instruct        = rcvUartdata[arrayCount+2];
                        ctrolData  = rcvUartdata[arrayCount+3];
                        crcData = rcvUartdata[arrayCount+4];        
                                                
                        switch(instruct)
                        {
                                case 0x10:        lackWaterState = ctrolData;                                //缺水 标志
                                                                                                                break;
                                case 0x20:        slaveState = ctrolData;                                                //1 EN 0 dis 开/关机
                                                                                                                break;
                                default:        break;
                        }
                        instruct = 0;
                        ctrolData = 0;
                        crcData = 0;
                                                        
                        rcvUartdata[arrayCount] = 0;        
                        rcvUartdata[arrayCount+1] = 0;        
                        rcvUartdata[arrayCount+2] = 0;
                        rcvUartdata[arrayCount+3] = 0;        
                        rcvUartdata[arrayCount+4] = 0;
                }
        }
        revOk** = 0;
}
有什么问题直接加群主询问                                
                        





使用特权

评论回复

相关帖子

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

本版积分规则

18

主题

141

帖子

5

粉丝