打印

请教一下pic16F687的串口问题

[复制链接]
3684|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
孤独泪|  楼主 | 2013-1-31 23:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
首先芯片的RB7脚是TX, RB5脚是RX.手册里面却有如下设置描述:
In order to configure pin RB6/SCK/SCL and RB7/TX/CK as the universal synchronous asynchronous receiver transmitter.
SPEN bit must be set 1
TRISB6 set 1
TRISB7 set 1.

我是觉得应该是TRISB5和TRISB7设置在1.
因此考虑这种情况,我将TRISB4~TRISB7都设置成1.初始化程序如下:

void InitSFR(void)
//初始化特殊功能寄存器
{
OSCCON = 0x61;  //内部振荡器用于系统时钟,且是4MHZ
TRISA = 0x04;  //设置RA0和RA1输入,RA2输出
TRISB = 0xf0;  //RB7输出.RB6,RB5,RB4输入,
TRISC = 0x20;  //RC5输入,其他输出
//定时器0初始化
OPTION_REG = 0x04;  //预分频32,
T0CS = 0;      //选择内部时钟
T0IE = 1;      //允许定时器中断
/////串口设置
SPBRG = 25;   //波特率设置成9600
SPEN = 1;      //串口允许
CREN = 1;      //接收允许
//RCSTA = 0x90;
TXEN = 1;       //发送允许
BRGH = 1;       //高速模式
//TXSTA = 0x24;
//////////
TXIE = 0;      //不做发送中断
RCIE = 1;      //接收中断设置
PEIE = 1;      //允许所有的位屏蔽的外设中断
GIE = 1;       //打开总中断
}

之后我发送数据正常,发送程序如下,
while (!TXIF)       ;
    TXREG = 0x55;      

波特率是9600正常的。
但是我上位机发送0x55,在RB5脚上面测的有正常的数据接收到,但是没有中断产生。
程序如下
void SerialReceiveInterrupt(void)
//串口通迅接收中断
{
receivedata = RCREG;
receivenum++;
IO_LED1 = 0;   //test
}

void interrupt com(void)   
{
if (RCIF && RCIE)
{
  SerialReceiveInterrupt();
}
if (TXIF && TXIE)
{
   SerialSendInterrupt();
}
if (T0IF && T0IE)
{
  Timer0Interrupt();
  //中断标志清零
  T0IF = 0;
}
}

或者我在主程序里面直接判断RCIF标志一直不会为1.

请教哪位大侠有用过款单片机做过串口通讯。我的问题会出在什么地方?
谢谢!
沙发
NE5532| | 2013-2-1 08:52 | 只看该作者
串口寄存器里面,溢出错误标志没有处理,溢出以后接收会被自动关闭。

使用特权

评论回复
板凳
shiyan1532| | 2013-2-1 09:51 | 只看该作者
帮顶了

使用特权

评论回复
地板
孤独泪|  楼主 | 2013-2-1 11:20 | 只看该作者
shiyan1532 发表于 2013-2-1 09:51
帮顶了

请问一下,溢出标志该什么处理,还是要哪儿屏蔽溢出。谢谢!

使用特权

评论回复
5
NE5532| | 2013-2-1 21:48 | 只看该作者
数据手册里面写了出现溢出标志以后该怎么操作,而且楼主的问题也不一定就是这个标志问题,我提的意思就是——楼主没有认真看过串口这个章节,靠猜是猜不出来的,需要认真读数据手册。

使用特权

评论回复
6
仰望星期五| | 2013-2-2 11:39 | 只看该作者
本帖最后由 仰望星期五 于 2013-2-2 11:40 编辑

#include <htc.h>
#include <pic18.h>
#include <pic18f45k20.h>
#include "keyinit.h"

#define uchar unsigned char
#define uint unsigned int

uchar rebuf[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
uchar lednun,ledstat,reflag=0,recount=0;

void serinit()
{
        IRCF2=1;
        IRCF1=0;
        IRCF0=1;    //内部晶振4Mhz
        BRG16=0;    //使用8位波特率发生器
        SPBRG=0x19;        //波特率9600  十进制25
        TXSTA=0x24; //异步模式、8位发送、使能发送、高速
        RCSTA=0x90; //使能串口、连续接收
        TRISC6=1;        //RX,TX设置为输入
        TRISC7=1;
}
void fdata(uchar data)
{
        TXREG=data;
        while(!TRMT);
}

void delay(uint t)
{
        uint i,j;
        for(i=t;i>0;i--)
        for(j=100;j>0;j--);
}

void ioinit()
{
        TRISA=0X00;
        TRISB=0X00;
        TRISD=0X00;
        TRISE=0X00;//设置为输出

        PORTA=0X00;
        PORTB=0X00;
        PORTD=0X00;
        PORTE=0X00;//输出低电平
}
void main()
{
        uchar i;
        serinit();        //串口初始化
        ioinit();   //端口初始化
        GIE=1;                //开总中断
        RCIE=1;                //开接收中断
        PEIE=1;                //开外设中
        while(1)
        {

                if(reflag==1)
                {
/*                        for(i=0;i<9;i++)
                        {
                                TXREG=rebuf;
                                while(!TRMT);
                        }
*/
                        reflag=0;
                        GIE=0;
                        if((rebuf[2]==0)&&(rebuf[3]==0)&&(rebuf[4]==0)&&(rebuf[5]==0))
                        {
                                if(rebuf[6]==0x02)
                                {
                                        if(rebuf[8]==0x01)
                                        {
                                                ledstat=1;
                                        }
                                        else if(rebuf[8]==0x00)
                                        {
                                                ledstat=0;
                                        }
                                        lednun=rebuf[7];
                                        switch(lednun)
                                        {
                                                case 0xa0:
                                                {
                                                        if(ledstat==1)
                                                        {
                                                                AIN=0;
                                                                delay(10);
                                                                AIN=1;
                                                                delay(300);
                                                                AIN=0;
                                                        }
                                                        else if(ledstat==0)
                                                        {
                                                                BIN=0;
                                                                delay(10);
                                                                BIN=1;
                                                                delay(300);
                                                                BIN=0;
                                                        }
                                                }break;
                                                case 0xa1:
                                                        K1=ledstat;
                                                        break;
                                                case 0xa2:
                                                        K2=ledstat;
                                                        break;
                                                case 0xa3:
                                                        K3=ledstat;
                                                        break;
                                                case 0xa4:
                                                        K4=ledstat;
                                                        break;
                                                case 0xa5:
                                                        K5=ledstat;
                                                        break;
                                                case 0xa6:
                                                        K6=ledstat;
                                                        break;
                                                case 0xa7:
                                                        K7=ledstat;
                                                        break;
                                                case 0xa8:
                                                        K8=ledstat;
                                                        break;
                                                case 0xa9:
                                                        K9=ledstat;
                                                        break;
                                                case 0xaa:
                                                        K10=ledstat;
                                                        break;
                                                case 0xab:
                                                        K11=ledstat;
                                                        break;
                                                case 0xac:
                                                        K12=ledstat;
                                                        break;
                                                case 0xad:
                                                        K13=ledstat;
                                                        break;
                                                case 0xae:
                                                        K14=ledstat;
                                                        break;
                                                case 0xaf:
                                                        K15=ledstat;
                                                        break;
                                                case 0xb0:
                                                        K16=ledstat;
                                                        break;
                                                case 0xb1:
                                                        K17=ledstat;
                                                        break;
                                                case 0xb2:
                                                        K18=ledstat;
                                                        break;
                                                case 0xb3:
                                                        K19=ledstat;
                                                        break;
                                                case 0xb4:
                                                        K20=ledstat;
                                                        break;
                                                default:
                                                        reflag=0;
                                                        break;
                                        }
                                }
                                else
                                {
                                        reflag=0;
                                }
                        }
                        else
                        {
                                reflag=0;
                        }
                        GIE=1;
                }
        }
}
void interrupt uart()
{
        if(RCIF&&0x01)
        {
                rebuf[recount++]=RCREG;//存储接收数据
//                TXREG=RCREG;
//                while(!TRMT);
                if(rebuf[0] == 0x01)   //判断数据帧头是否为0x01
                {
                        if(recount>=9)
                        {
                                recount=0;
                                reflag=1;
                        }
                }
                else
                {
                        recount=0;
                }
//        TXREG=RCREG;
        }
}
看下串口的初始化以及中断函数  应该对你有帮助

使用特权

评论回复
7
伍戈123| | 2016-2-18 19:19 | 只看该作者
你好,我这两天也是在调PIC16F687这款单片机,调串口的时候遇到跟你一样的情况,发送没问题,但是接受就有问题,老是产生不了接受中断,不知道你是怎么弄得,最后弄出来了吗?可否赐教

使用特权

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

本版积分规则

个人签名:高精度天平方案研究,称重系统开发,

97

主题

2303

帖子

9

粉丝