原创 串口通信调试日志

2009-11-26 17:37 5621 5 6 分类: MCU/ 嵌入式

这几天刚从51转到AVR还有很多东西不太熟悉,现在用的是mega8515,今天调试串口,都快把我弄崩溃了,开始是能接收不能 发送,到后来是能发送不能接收,再到后为是不能发送比拟能接收……真快把我弄死了,后来再看看寄存器,再看看程序,还是程序的问题,下面是俺开始写的程序:


      //ICC-AVR application builder : 2009-11-24 14:09:56
// Target : M8515
// Crystal: 8.0000Mhz
#include <iom8515v.h>
#include <macros.h>
#define Setbit(REG,N)   REG|=(1<<N)    //对REG的N位置1
#define Clrbit(REG,N)   REG&=~(1<<N)   //对REG的N位清零
#define Invbit(REG,N)   REG^=(1<<N)    //对REG的N位取反
/*_*=============ID指示灯亮/灭宏定义==================*_*/
#define Led_on() Clrbit(PORTD,7)
#define Led_off() Setbit(PORTD,7)
/*>>>>>>>>>>>>>>>>>>>>>>发送使能、发送关闭宏定义<<<<<<<<<<<<<<<<<<<<<*/
#define Send_on() Setbit(PORTD,2)
#define Send_off() Clrbit(PORTD,2)
typedef unsigned char uint8;   /* 定义可移植的无符号8位整数关键字*/
typedef signed   char int8;   /* 定义可移植的有符号8位整数关键字*/
typedef unsigned int uint16;   /* 定义可移植的无符号16位整数关键字*/
typedef signed   int int16;   /* 定义可移植的有符号16位整数关键字*/
typedef unsigned long uint32;   /* 定义可移植的无符号32位整数关键字*/
typedef signed   long int32;   /* 定义可移植的有符号32位整数关键字*/
void port_init(void)
{
PORTA = 0xff;   //初始状态为高电平,为读取设备ID号做准备
DDRA  = 0x00;   //A口做为输入口,用来读取编码开关的值
PORTB = 0x00;   //B口做为输出口,通过2803来控制继电器
DDRB  = 0xFF;
PORTD = 0x80;   //初始状态时灯灭
DDRD  = 0x84;   //PD2控制485芯片的使能端,PD7控制指示灯
}
/**************************************************************/
//UART0 initialize串口初始化
// desired baud rate: 38400
// actual: baud rate:38462 (0.2%)
/*************************************************************/
void uart0_init(void)
{
UCSRB = 0x00;         //disable while setting baud rate
UCSRA = 0x00;
UCSRC =(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//0x46;// BIT(URSEL) | 0x06;//异步、无校验、9位数据位

UBRRL = 0x0C;    //UBRRL=(Fosc/16/(Baud+1))%256;  set baud rate lo
UBRRH = 0x00;    //UBRRH=(Fosc/16(Baud+1))/256;   set baud rate hi

UCSRB |=/*(1<<RXCIE)|(1<<RXEN)/*|(1<<TXEN)*/(1<<UCSZ2);//0x94;先关闭发送使能
}
void init_devices(void)
{
//stop errant interrupts until set up
CLI();          //disable all interrupts  (关中断)
port_init();
uart0_init();
MCUCR = 0x00;
EMCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00;
SEI();         //re-enable interrupts  (开中断)
              //all peripherals are now initialized
}
/*=====================================================*/
void Delay_100us(uint16 t) //100us
{
uint8 i;
while((t--)>0)
{
  for(i=0;i<12;i++);
}
}
void Delay_1ms(void) //1ms
{
uint16 i;
for(i=1;i,(uint16)(8*143-2);i++);
}
void Delay_ms(uint16 tt)//tt ms
{
uint8 i;
while(i<tt)
{
  Delay_1ms();
  i++;
}
}
void Usart_transmit(uint16 data)
{
//UCSRB|=BIT(3);//开启发送使能
while(!(UCSRA&(1<<UDRE)));
//Send_on();
/*******将第九位数复制到TXB8*********/
//while(UCSRB&(~BIT(3)));//等待发送使能
UCSRB&=~(1<<TXB8); //发送的第九位数据一直是0
//if(data&0x0100)
//UCSRB|=(1<<TXB8);
UDR=data;
while(!(UCSRA&(1<<TXC)));
//UCSRC|=(1<<TXC);
//Send_off();
  UCSRB&=~BIT(3);//发送使能关闭
}
void main(void)
{
uint8 i;
init_devices();
//Send_on();
PORTD|=BIT(2);   //485发送使 能
UCSRB|=BIT(3);//发送使能关
while(1)
{
   Led_on();
   //for(i=0;i<10;i++)
   //{
    PORTC="0X58"; //TEST
   Usart_transmit(0x58);  //发送数据
   //Delay_ms(100);
   //Led_off();
   //}
   //UCSRB&=~BIT(3);//发送使能关闭
   //PORTD&=~BIT(2);   //485发送关闭
   //PORTC=0X58; //TEST
   Led_off();
}
}



当时我只是查询接收,但接收完了,灯不会灭,也就是程序执行到  Usart_transmit(0x58);  //发送数据  ;就不往下执行了,真弄不明白到底是怎么回事?


……


……


……


经过若干小时的奋斗,现在终于弄出了点眉目,原来是


 PORTC=0X58; //TEST
   Usart_transmit(0x58);  //发送数据
这两句话是不能话在while(1)这个死循环中的,不然程序一直在执行这个死循环,当然就是连续发数据了,应该在这里面写几个条件语句限制才行
   例如:
    if(flag==1)
  {
   PORTB=0xff;
   Usart_transmit(Dat);
   Delay_ms(5000);
   Led_off();
   //flag=0;
  }
  else{Led_on();PORTB=Dat;}

这样的话就不会连续发数据了
不过还是有些其它的问题,只有再看看程序再说了,呵呵,不过终于看到希望了^_^


  下面是俺现在的程序:


   /*===========================================================================*/
// ICC-AVR application builder : 2009-11-6
// Target : M8515
// Crystal: 8.0000Mhz
// Author: Citect Xu
/*==========================================================================*/


#include <iom8515v.h>
#include <macros.h>
#include<stdio.h>


#define Setbit(REG,N)   REG|=(1<<N)    //对REG的N位置1
#define Clrbit(REG,N)   REG&=~(1<<N)   //对REG的N位清零
#define Invbit(REG,N)   REG^=(1<<N)    //对REG的N位取反


/*_*==================ID指示灯亮/灭宏定义=============*_*/
#define Led_on() Clrbit(PORTD,7)
#define Led_off() Setbit(PORTD,7)


/*>>>>>>>>>>>>>>>>>>>>>>发送使能、发送关闭宏定义<<<<<<<<<<<<<<<<<<<<<*/
//Send_on()是485发送使能;Send_off()是485发送关闭
//TX_EN()是单片机串口发送使能;RX_EN()是单片机串口发送关闭
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>^_^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
#define Send_on() Setbit(PORTD,2)
#define Send_off() Clrbit(PORTD,2)
#define TX_EN() UCSRB|=BIT(3)
#define RX_EN() UCSRB&=~BIT(3)


typedef unsigned char uint8;   /* 定义可移植的无符号8位整数关键字*/
typedef signed   char int8;   /* 定义可移植的有符号8位整数关键字*/
typedef unsigned int uint16;   /* 定义可移植的无符号16位整数关键字*/
typedef signed   int int16;   /* 定义可移植的有符号16位整数关键字*/
typedef unsigned long uint32;   /* 定义可移植的无符号32位整数关键字*/
typedef signed   long int32;   /* 定义可移植的有符号32位整数关键字*/


void port_init(void)
{
 PORTA = 0xff;   //初始状态为高电平,为读取设备ID号做准备
 DDRA  = 0x00;   //A口做为输入口,用来读取编码开关的值
 PORTB = 0x00;   //B口做为输出口,通过2803来控制继电器
 DDRB  = 0xFF;
 PORTD = 0x80;   //初始状态时灯灭
 DDRD  = 0x84;   //PD2控制485芯片的使能端,PD7控制指示灯
}


/**************************************************************/
//UART0 initialize串口初始化
// desired baud rate: 38400
// actual: baud rate:38462 (0.2%)
/*************************************************************/
void uart0_init(void)
{
 UCSRB = 0x00;         //disable while setting baud rate
 UCSRA = 0x00;
 UCSRC =(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//0x46;// BIT(URSEL) | 0x06;//异步、无校验、9位数据位
 
 UBRRL = 0x0C;    //UBRRL=(Fosc/16/(Baud+1))%256;  set baud rate lo
 UBRRH = 0x00;    //UBRRH=(Fosc/16(Baud+1))/256;   set baud rate hi
 
 UCSRB=(1<<RXCIE)|(1<<RXEN)/*|(1<<TXEN)*/|(1<<UCSZ2);//0x94;先关闭发送使能
}


void init_devices(void)
{
 CLI();          //disable all interrupts  (关中断)
 
 port_init();
 uart0_init();
 MCUCR = 0x00;
 EMCUCR = 0x00;
 GICR = 0x00;
 TIMSK = 0x00;
 
 SEI();         //re-enable interrupts  (开中断)
}


/*=====================================================*/
void Delay_100us(uint16 t) //100us
{
 uint8 i;
 while((t--)>0)
 {
  for(i=0;i<12;i++);
 }
}


void Delay_1ms(void) //1ms
{
 uint16 i;
 for(i=1;i,(uint16)(8*143-2);i++);
}


void Delay_ms(uint16 tt)//tt ms
{
 uint8 i;
 while(i<tt)
 {
  Delay_1ms();
  i++;
 }
}


uint8 Receive_buf[6];
uint8 R_count=0;
uint8 Dat;
uint8 flag="0";
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
/***********************************************************/
//uart has received a character in UDR
//USART接收中断,接收一个字符
/**********************************************************/
void uart0_rx_isr(void) 
{
 CLI();
 if(UCSRB&(1<<RXB8)) 
     {
   Dat="UDR";
   if(Dat==0xff)
   {flag=1;}
   else {flag=0;}
      /*Receive_buf[R_count++]=UDR;
      if(R_count==6)
      {R_count=0;}
      UDR="0X00";*/
      }
 else {
     Dat="0";
       /* uint8 i;
   for(i=0;i<6;i++)
    {
     Receive_buf=0;
    } */
    }
 SEI();



void Usart_transmit(uint8 data)
{
 Send_on();//开启485发送使能
 TX_EN();  //开启串口发送使能
 while(!(UCSRA&(1<<UDRE)));
 //Send_on();
 /*******将第九位数复制到TXB8*********/
 //while(UCSRB&(~BIT(3)));//等待发送使能
 UCSRB&=~(1<<TXB8); //发送的第九位数据一直是0
 //if(data&0x0100)
 //UCSRB|=(1<<TXB8);
 UDR=data;
 while(!(UCSRA&(1<<TXC)));
 //UCSRC|=(1<<TXC);
  Send_off();
  UCSRB&=~BIT(3);//发送使能关闭
}
void main(void)
{
 uint8 i;
 init_devices();
 //Send_on();
 //PORTD|=BIT(2);   //485发送使 能
 //UCSRB|=BIT(3);//发送使能关
  //PORTB=0X01;
 while(1)
 {
  if(flag==1)
  {
   PORTB="0xff";
   Usart_transmit(Dat);
   Delay_ms(5000);
   Led_off();
   //flag=0;
  }
  else{Led_on();PORTB=Dat;}
  /*if(Receive_buf[0]=0xff)
  {
   Led_on();
   PORTB="Receive"_buf[0]; //TEST
   UCSRB|=BIT(3);//发送使能关
   Usart_transmit(Receive_buf[0]);  //发送数据
   Delay_ms(500);
   Led_off();
  }*/
 }
}


 


 


不过现在还是有问题,就是:


      在主程序中 


 if(flag==1)
  {
   PORTB="0xff";B口给高电平
   Usart_transmit(Dat); //发送Dat


   Delay_ms(5000);//延时5S
   Led_off();//灯关


   }


           这两句没有好好执行,在实验中发现当我发送0xff时,PORTB口确实是高了一下,而灯也只是闪了一下,为什么没有停在这个状态呢?


          这一情况还没有想明白,还得好好检查一下程序,也得好好理一下思路才行,不然钻进死胡同就完蛋了,不管怎么说吧,俺还是看到了希望的曙光!


         不知道在这里能不能遇到什么大虾什么的前辈否,要是有缘遇到希望能帮俺看一下,谢谢!俺的QQ是515673876;俺的邮箱是:xucun915@126.com

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户181767 2010-1-4 21:35

好好注意一下UDRE,TXC,RXC这几位的状态的变化哦。。。。。
相关推荐阅读
xucun915_925777961 2013-04-28 11:31
毕业后的五年拉开大家差距的原因在哪里?【转】
  有人工作,有人继续上学,大家千万不要错过这篇文章,能看到这篇文章也是一种幸运,真的受益匪浅,对我有很大启迪,这篇文章将会改变我的一生,真的太好了,希望与有缘人分享,也希望对有缘人有所帮助!...
xucun915_925777961 2013-03-31 20:28
职场大牛精彩总结:职场上,如何做人做事做管理【转】(文/张子阳)
      大道至简,越是根源和基本的问题,道理实际上越简单。关于如何做人、做事、做管理的书很多,我看得不多,但是我觉得这些书更多是侧重技术和实现细节上的,而很少从人的思想和观念去讲。实际...
xucun915_925777961 2013-03-28 14:03
介绍几种优秀的UML工具
统一建模语言(UML是 Unified Modeling Language的缩写)是用来对软件密集系统进行可视化建模的一种语言。UML为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言...
xucun915_925777961 2013-03-27 18:05
IAR EW FOR 8051 修改工程名称的方法
        近段时间一直在搞蓝牙4.0的开发任务,所以用到了IAR编译器,话说IAR编译器用途蛮广,可以编译MSP430,ARM,还有TI的51核芯片,当然,这要不同的版本,我现在用的是for...
xucun915_925777961 2013-03-26 16:40
Cortex-M3学习日志(八)-- TFT实验Part(a)
    自己用的LPC1768的开板带有一块2.4寸的TFT彩色液晶屏,虽然自己工作中还用不过显示屏,但是晚上闲着也是闲着,于是继续玩咱的LPC1768吧。 我的开发板上的液晶屏的用的是SPI接口,当...
xucun915_925777961 2013-03-25 20:48
说说那几款查看源代码的工具
说说那几款查看代码的工具 今天给大家介绍几款单片机工程师所喜欢的几款查看源代码的工具,这几款工具在懒猫的日常工作中可是帮了不少忙。 一、 Source Insight     Source Insig...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条