打印

模拟串口接收问题

[复制链接]
5725|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
linyueqiang|  楼主 | 2011-8-10 20:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<pic18.h>
#define TXD RC6 //宏定义:发送数据的引脚
#define RXD RC7 //宏定义:接收数据的引脚
//#define TIMER_ENABLE() {TMR0L=0XAE;TMR0IE=1;TMO_FLAG=0;}  //使能T/C
//#define TIMER_DISABLE() {TMR0IE=0;TMO_FLAG=0;} //禁止T/C
//#define wait_timer() {while(!TMO_FLAG);TMO_FLAG=0;}//等待T/C超时
//unsigned char TMO_FLAG;  //T/C超时溢出标志位
/*****************************
*函数名称:delay
*输    入:无
*输    出:无
*功    能:延时1ms
******************************/
void delay()
{
unsigned char j,k;
  for(k=0;k<250;k++)
    for(j=0;j<250;j++)
   {;}
}
/*****************************
*函数名称:init
*输    入:无
*输    出:无
*功    能:程序初始化
******************************/
void init()
{
TRISC6=0;
TRISC7=1;
T0CON=0Xc0;//定时器0使能,外部晶振,8bit数据,分频给定时器0,分频比是2
}
/*****************************
*函数名称:send
*输    入:要发送的字节
*输    出:无
*功    能:串口发送单个字节
******************************/
void send(unsigned char a)
{
unsigned char i;
TXD=0;
TMR0IE=1;
TMR0L=0XA9;
TMR0IF=0;
while(!TMR0IF);
TMR0IF=0;
for(i=0;i<8;i++)
{
  TXD=(a&0x01);
  TMR0L=0XA9;
  TMR0IF=0;
  while(!TMR0IF);
  
  a=a>>1;
}
TXD=1;
TMR0L=0XA9;
TMR0IF=0;
while(!TMR0IF);
TMR0IE=0;
}
/*****************************
*函数名称:receive
*输    入:无
*输    出:单个字节
*功    能:串口接收单个字节
******************************/
unsigned char  receive()
{
unsigned char j;
unsigned char newrec_data=0;
while(!RXD);
{
  TMR0IE=1;
  TMR0L=0X54;
  TMR0IF=0;
  while(!TMR0IF);
  while(!RXD);
  {
   TMR0L=0Xa9;
   TMR0IF=0;
   while(!TMR0IF);
   for(j=0;j<8;j++)
   { newrec_data=newrec_data>>1;
    if(RXD)
    {
     newrec_data|=0x80;
     TMR0L=0XA9;
     TMR0IF=0;
     while(!TMR0IF);
     continue;
    }
    else
    {
     newrec_data&=0x7f;
     TMR0L=0XA9;
     TMR0IF=0;
     while(!TMR0IF);
     continue;
    }
   }
  while (RXD)
  {
   //break;
   TMR0L=0XA9;
   TMR0IF=0;
   while(!TMR0IF);
   
  }
}
}
TMR0IE=0;
return newrec_data;
}
/*****************************
*函数名称:StartBitCome
*输    入:无
*输    出:0/1
*功    能:是否有起始位到来
unsigned char  StartBitCome(void)
{
return (RXD==0);
}
******************************/
/*****************************
*函数名称:main
*输    入:无
*输    出:无0/1
*功    能:函数主体
******************************/
void main()
{
unsigned char gch;
init();
while(1)
{  send(0x00);
  //delay();
  //if(StartBitCome())
  //{
   gch=receive();
   send(gch);
   //delay();
  //}
}
}
发送程序没有问题,就是接收不到数据,起始位好像一直是高电平,不知道如何置低
沙发
NE5532| | 2011-8-10 20:52 | 只看该作者
楼主,你写的模拟串口应该打屁股,用了这么多资源,浪费呢?再想下呢。

使用特权

评论回复
板凳
linyueqiang|  楼主 | 2011-8-10 21:11 | 只看该作者
现在起始位检测到了,可是波特率不对,接收到的数据都是错误的,我波特率是9600,接收和发送的波特率都是一致的,数据怎么会出错呢

使用特权

评论回复
地板
NE5532| | 2011-8-10 22:15 | 只看该作者
楼主你的定时器用了和没用有啥区别?还有你定时器设的多长?

使用特权

评论回复
5
linyueqiang|  楼主 | 2011-8-11 08:35 | 只看该作者
定时104us,刚好波特率是9600,为什么说定时器没有用,?求教

使用特权

评论回复
6
NE5532| | 2011-8-11 12:31 | 只看该作者
定时104us,刚好波特率是9600,为什么说定时器没有用,?求教
linyueqiang 发表于 2011-8-11 08:35


用定时器,还让CPU死等,你觉得你占了哪边的便宜?

使用特权

评论回复
7
linyueqiang|  楼主 | 2011-8-11 13:19 | 只看该作者
明白了,不应该是while(!RXD);
/*****************************
*函数名称:receive
*输    入:无
*输    出:单个字节
*功    能:串口接收单个字节
******************************/
unsigned char  receive()
{
        unsigned char j;
        unsigned char newrec_data=0;
        RXD=1;
        if(RXD==0)
        {
                TMR0IE=1;
                TMR0L=0XFD;
                TMR0IF=0;
                while(!TMR0IF);       
                if(RXD==0)
                {
                        TMR0L=0XA9;
                        TMR0IF=0;
                        while(!TMR0IF);
               
               
               
                        for(j=0;j<8;j++)
                        {        newrec_data=newrec_data>>1;
                                if(RXD)
                                {       
                                        newrec_data|=0x80;
                                        TMR0L=0XA9;
                                        TMR0IF=0;
                                        while(!TMR0IF);
                                        continue;
                                }
                                else
                                {
                                        newrec_data&=0x7f;
                                        TMR0L=0XA9;
                                        TMR0IF=0;
                                        while(!TMR0IF);
                                        continue;
                                }
                        }
                        while (RXD)
                        {       
                                TMR0L=0XA9;
                                TMR0IF=0;
                                while(!TMR0IF);
                                break;
                        }       
                }       
        }

        TMR0IE=0;
return newrec_data;       
}
改成这样子了

使用特权

评论回复
8
snakeemail| | 2011-8-13 22:01 | 只看该作者
直接copy程序匠人的,不要自己编了,纯粹浪费时间

使用特权

评论回复
9
jimmychen| | 2011-8-13 22:15 | 只看该作者
楼上的,有错误才有进步嘛,总是copy怎么行呢

使用特权

评论回复
10
linyueqiang|  楼主 | 2011-8-15 20:05 | 只看该作者
示波器上看到有低电平,但是程序好像一直检测不到低电平,这是为什么呢

使用特权

评论回复
11
NE5532| | 2011-8-15 20:18 | 只看该作者
提示你一下,找个不用的端口,在接收采样点那里取反,示波器看双踪。不会调程序的程序员是不合格的程序员,楼主没想通定时器为啥不对前就还木深入了解单片机。

使用特权

评论回复
12
hncxu| | 2011-8-15 20:50 | 只看该作者
如果是IO口无法读高低电平,有可能是初始化IO口的问题。楼主可以看看RC7有没有复用什么其他功能,如果有的话,通过相应的寄存器那它给关掉~~

使用特权

评论回复
13
linyueqiang|  楼主 | 2011-8-16 08:48 | 只看该作者
程序搞定了,是对定时器了解的不够透彻,造成了波特率的不正确,谢谢11楼的提示方法了,把调试好的程序贴上来#include<pic18.h>
#define TXD RC6        //宏定义:发送数据的引脚
#define RXD RC7        //宏定义:接收数据的引脚

//#define TIMER_ENABLE() {TMR0L=0XAE;TMR0IE=1;TMO_FLAG=0;}  //使能T/C
//#define TIMER_DISABLE() {TMR0IE=0;TMO_FLAG=0;}        //禁止T/C
//#define wait_timer() {while(!TMO_FLAG);TMO_FLAG=0;}//等待T/C超时
//unsigned char TMO_FLAG;                //T/C超时溢出标志位
/*****************************
*函数名称:delay
*输    入:无
*输    出:无
*功    能:延时1ms
******************************/
void delay()
{
        unsigned char j,k;
                for(k=0;k<250;k++)
                                for(j=0;j<250;j++)
                        {;}
}
/*****************************
*函数名称:init
*输    入:无
*输    出:无
*功    能:程序初始化
******************************/
void init()
{
        TRISC5=0;
        RC5=1;
        TRISC6=0;//TXD定义为输出
        TRISC7=1;//RXD定义为输入
        T0CON=0Xc0;//定时器0使能,外部晶振,8bit数据,分频给定时器0,分频比是2
}
/*****************************
*函数名称:send
*输    入:要发送的字节
*输    出:无
*功    能:串口发送单个字节
******************************/
void send(unsigned char a)
{
        unsigned char i;
        TXD=0;
        TMR0IE=1;
        TMR0L=0XA9;
        TMR0IF=0;
        while(!TMR0IF);
        for(i=0;i<8;i++)
        {
                TXD=(a&0x01);
                TMR0L=0XA9;
                TMR0IF=0;
                while(!TMR0IF);
                a=a>>1;
        }
        TXD=1;
        TMR0L=0XA9;       
        TMR0IF=0;
        while(!TMR0IF);
        TMR0IE=0;

}
/*****************************
*函数名称:receive
*输    入:无
*输    出:单个字节
*功    能:串口接收单个字节
******************************/
unsigned char  receive()
{
        unsigned char j;
        unsigned char newrec_data=0;
                       
                                TMR0IE=1;
                                TMR0L=0XD4;
                                TMR0IF=0;
                                while(!TMR0IF);       
                        if(RXD==0)
                        {
                                TMR0L=0Xa9;
                                TMR0IF=0;
                                while(!TMR0IF);       
                        for(j=0;j<8;j++)
                        {        newrec_data=newrec_data>>1;
                                if(RXD)
                                {       
                                        newrec_data|=0x80;
                                        TMR0L=0Xa9;
                                        TMR0IF=0;
                                        while(!TMR0IF);
                                       
                                }
                                else
                                {
                                        newrec_data&=0x7f;
                                        TMR0L=0Xa9;
                                        TMR0IF=0;
                                        while(!TMR0IF);       
                                }
                        }
        while(RXD==1)
                {
                        TMR0L=0Xa9;
                        TMR0IF=0;
                        while(!TMR0IF);       
                        break;       
                }
                TMR0IE=0;
        }
return newrec_data;       
}

/*****************************
*函数名称:StartBitCome
*输    入:无
*输    出:0/1
*功    能:是否有起始位到来

unsigned char  StartBitCome(void)
{
        return (RXD==0);
}
******************************/
/*****************************
*函数名称:main
*输           入:无
*输    出:无0/1
*功    能:函数主体
******************************/
void main()
{       
        unsigned char gch;
        init();
        while(1)
        {
               
                        if( !RXD)
                        {
                                gch=receive();
                                send(gch);
                        }
               
        }
}

使用特权

评论回复
14
NE5532| | 2011-8-16 19:40 | 只看该作者
楼主啊,你还是没看懂我的意思。你的定时器用查询方式来定时和用软件写个死定时有啥区别啊?白白浪费一个定时器。

使用特权

评论回复
15
lwylwy1| | 2012-1-11 12:05 | 只看该作者
我把这个程序移置到,12F615上没有输出,不能发送也不能接收,
       ANSEL=0X00;//全部设置为数字口
        CMCON0=0x00;
        TRISIO=0b00111101;
        ////GP1 TXD定义为输出发送
        ////GP0 RXD定义为输入接收
        GPIO=0XFF;
        INTCON=0X00;//禁止所有中断
        OPTION=0Xcc;

使用特权

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

本版积分规则

7

主题

32

帖子

0

粉丝