打印

PIC16的USART程序一问

[复制链接]
3312|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chenyuejian|  楼主 | 2013-1-4 20:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void usart_int(void)
{
GIE=1;
PEIE=1;
RCIE=1;
TRISB1=1; //输入
TRISB2=1;
SPBRG=25; //4MHz 波特率9600kbs
RCSTA=0b10010000;
//接收状态控制寄存器
//SPEN=1 使能串行端口 RX9=0 第九位接收使能弃用 SREN=0 单字节接收使能,异步模式忽略 CREN=1 异步模式允许连续接收 ADEN=0 地址检测在9位情况下使用 FERR OERR RX9D为标志位  
TXSTA=0b00000100;
//发送状态控制寄存器
//CSRC=0 同步模式有效 TX9=0 第九位传输弃用 TXEN=1 使能发送 SYNC=0 异步模式 - BRGH=1 快速 TMRT=0 发送移位寄存器状态位,仅读,1代表空 TX9D=0 要发送的第九位
}
void usart_tx(char temp)
{
while(!TRMT);   //检测TSR寄存器是否为空
TXEN=1;        //启动发送,会产生中断
TXREG=temp;   //将待发数据给发送寄存器   
while(!TRMT);   //等待发关完一字节数据
TXEN=0;      //关闭发送使能
}
main(void)
{  
Sen[0]='0';
Rec[0]='0';
usart_int();//receive everytime
LCD_init();
Display_char(8,1,"Sen:");
Display_char(8,3,"Rec:");
while(1)
{
  if(INC)
  {
   delay(1000);
   if(INC)
   {
    while(INC);
    Sen[0]='A';
    usart_tx(Sen[0]);
   }
  }   
  Display_char(40,1,&Sen);
  Display_char(40,3,&Rec);
}
}
void interrupt Timer(void)
{  
if(RCIE&&RCIF)
{
  Rec[0]=RCREG;
}
}
请问这样写USART控制程序有什么问题?这个程序未能调试成功,不知道问题出在哪儿。我用的是PIC16F628A单片机!请各位高手神人指教
沙发
Light_David| | 2013-1-5 00:25 | 只看该作者
太多同学被PIC的USART绕进去:P

写入TXREG 后并不立即清零TXIF 标志位。TXIF 在执行写
操作后的第2 个指令周期才有效。写入TXREG 后立即
查询TXIF 位将返回无效结果

TXREG=temp;   //将待发数据给发送寄存器   
while(!TRMT);   //等待发关完一字节数据
在这两句之间加一个NOP看看吧

使用特权

评论回复
板凳
yewuyi| | 2013-1-5 08:48 | 只看该作者
发送使能一直打开,直接定时向TXREG送数就可以了,

使用特权

评论回复
地板
chenyuejian|  楼主 | 2013-1-5 11:51 | 只看该作者
void usart_tx(char temp)
{       
        while(!TRMT);   //检测TSR寄存器是否为空
        TXREG=temp;   //将待发数据给发送寄存器       
        ;;;               
}
void interrupt Timer(void)
{               
        if(RCIE&&RCIF)
        {
                Rec[0]=RCREG;
                RA7=~RA7;
        }
}
我将接收处设了标志位,发现接收在启动时刻响应一次就停止了。发送改成如上形式,一直打开TXEN。

使用特权

评论回复
5
angelsa0106| | 2013-1-7 08:12 | 只看该作者
试试这样可以吧?
        for(fi=0;fi<200;fi++);
        while(!TXIF);        /* set when register is empty */
        TXREG = byte;
        while(TRMT==0);//发送完成
        NOP();
        NOP();

使用特权

评论回复
6
沧海之道| | 2013-1-7 12:01 | 只看该作者
TXREG=*a;
while(!TXIF);
TXIF=0;
我这样用过,照抄51的思路,能成功,不知道有隐患不?

使用特权

评论回复
7
chenyuejian|  楼主 | 2013-1-8 10:59 | 只看该作者
已经调成功了:
void usart_tx(char temp)
{       
        delay(1000);
//        while(!TXIF);
        TXREG=temp;   //将待发数据给发送寄存器       
        delay(1);
        while(!TRMT);   //等待发关完一字节数据
}

使用特权

评论回复
8
wkei007| | 2016-6-13 14:39 | 只看该作者
6楼的做法是瞎猫撞到死老鼠,也不能说这方法不能用,而楼主虽然解决了问题,但用这长长的延迟来处理发送数据也不可行,如果要发送一堆数据,那这个延迟会很长了。
楼主可以用这方法测试下:
TXREG = send_data;
Nop();Nop();Nop();     //放几个空操作,等待第2个时钟到来自动清除IF标志
while(!TXIF);              //等待发送完成

使用特权

评论回复
9
943614033| | 2016-6-16 10:22 | 只看该作者
8楼的做法也是有问题的。TXIF ==1只代表TXREG里面没有数据,并不代表TSR里面没有数据。

使用特权

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

本版积分规则

12

主题

45

帖子

1

粉丝