pic18f单片机串口通信问题求助,急!

兜兜水袖 2013-07-02 04:40:28
只要上位机发送数据到下位机,下位机就死机。程序是温控系统,lcd显示温度,通过红外遥控能设定警报温度。

#include <p18cxxx.h>
#include "toppic.h"
#include "lcd1602.h"
#include "ds18b20.h"
#include"ds1302.h"
#include "uart.h"

long rece=0X22; //define receive data from rs232
int tp; //define temperature data from 1820
int hong;
long haha;
unsigned char UartFlage;

/*此处为晶振为10时的取值,如用其它频率的晶振时,要改变相应的取值。*/
#define Imax 18988
#define Imin 10850
#define Inum1 1967
#define Inum2 949
#define Inum3 4069

unsigned char IR_buff[4]={0x00,0x00,0x00,0x00};/*客户码低8位,客户码高8位,数据码,数据反码*/
unsigned char show[2]={0,0};
unsigned char flag_start;/*找到启动码标志*/
unsigned long m,Tc;
unsigned char IrOK;

/*0-F共阴字形码表*/
const rom unsigned char sz[]={0x3f , 0x06 , 0x5b , 0x4f , 0x66 ,
0x6d ,0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c ,
0x39 , 0x5e , 0x79 , 0x71 };



/**********************中断**************************/
void PIC18F_High_isr(void);/*中断服务函数声明*/
void PIC18F_Low_isr(void);

#pragma code high_vector_section=0x8/*高优先级中断响应时,会自动跳转到0x8处*/
void high_vector (void)
{
_asm goto PIC18F_High_isr _endasm
}
#pragma code low_vector_section=0x18
void low_vector (void)
{
_asm goto PIC18F_Low_isr _endasm
}
#pragma code


/*---高优先级中断服务程序---*/
#pragma interrupt PIC18F_High_isr
void PIC18F_High_isr (void)
{
/*INT1解码程序*/
/*提取中断时间间隔时长。TMR0读:先读低字节,后读高字节*/
Tc=TMR0L;
Tc=TMR0H*256+Tc;

TMR0H=0;/*TMR0置初值,先写高字节,后写低字节*/
TMR0L=0;
INTCON3bits.INT1IF=0;/*INT1溢出标志清零*/

/*寻找启始码*/
if((Tc>Imin)&&(Tc<Imax))
{
m=0;
flag_start=1;
return;
}
/*找到启动码后,进入解码流程*/
if(flag_start==1)
{
if(Tc>Inum1&&Tc<Inum3)
{
IR_buff[m/8]=IR_buff[m/8]>>1|0x80; m++;/*取码1*/
}
if(Tc>Inum2&&Tc<Inum1)
{
IR_buff[m/8]=IR_buff[m/8]>>1; m++;/*取码0*/
}
/*取码完成后判断码是否正确*/
if(m==32)
{
m=0;
flag_start=0;
if(IR_buff[2]==~IR_buff[3])
{
IrOK=1;
}
else IrOK=0;
}
}

}

/*---低优先级中断服务程序---*/
#pragma interruptlow PIC18F_Low_isr
void PIC18F_Low_isr (void)
{
if(PIR1bits.RCIF==1) /* 判断是不是串口接收中断 */
{
//rece=RCREG;
UartFlage=1; //一组串行数据接收完毕
}
}

/**********************main!!!**************************/
void main(void)
{
toppic_init();
UartIni();
LCD_init();

IrOK=0;
m=0;
flag_start=0;
T0CON=0b00000000;/*TMR0设置:停止运行、16位定时,预分频1:2*/
TMR0H=0;/*TMR0置初值,先写高字节,后写低字节*/
TMR0L=0;
T0CONbits.TMR0ON=1;/*启动TMR0*/

INTCON2bits.INTEDG1=0;/*设定外部中断1触发边沿(下降沿)*/
INTCON3bits.INT1IP=1;/*设置外部中断1为高优先级*/
INTCON3bits.INT1IE=1;/*INT1中断使能*/


TRISD=0X00; /*设置D口为输出*/
RCONbits.IPEN=1;/* 使能中断高低优先级 */
INTCON=INTCON|0xc0;/* 开总中断、开外围接口中断 */

PIE1bits.RCIE=1;/*串口接收中断允许*/

INTCONbits.PEIE=1;/*外设中断允许*/
INTCONbits.GIE=1;/*开总中断*/
/**************************display temperature on the lcd1602***************************/
LCD_setxy(1,1);
LCD_wrstr("TEMP:");
LCD_setxy(1,14);
LCD_wrchar(USER_CHAR6); //display


while(1)
{

if(IrOK==1)
{
show[0]=IR_buff[2] & 0x0F;//取键码的低四位
show[1]=IR_buff[2] >> 4; //取键码的高四位
IrOK=0;
hong=show[1]*10+show[0];
if(hong==15){
rece=rece+1;
}
else if(hong==7)
{rece=rece-1;}
else
{ LCD_setxy(2,10);
LCD_wrstr("wrong");
}

}
tp=get_temp(); //get it!!! ( ds18b20.c)

LCD_setxy(2,4);
LCD_wrul(rece);


if(tp>0x3fff)
{
LCD_setxy(1,7);
LCD_wrchar('-');
}
else
{
LCD_setxy(1,7);
LCD_wrchar('+');
}
tp&=0x3fff; //Shield symbol
LCD_setxy(1,13); // location , on the second line
LCD_wrlval(tp,5,2); //display the temp

UartTx(tp/100); //暂时串口助手只能收2位16进制数
UartTx(tp%100);
if(UartFlage==1)
{

UartFlage=0;

}

if((tp/100)>rece-1) // 不知道为什么与实际数相差1?
{
BZ=!BZ; //超过温度,就警报
}



}
}
...全文
763 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
fighter_xue 2015-11-04
  • 打赏
  • 举报
回复
请问大神,我安装的PICC8.05中没有PIC18F系列的头文件,要自己添加吗?请问你有没有PIC18系列的头文件,能不能发给我一份,邮箱719583781@qq.com。万分感谢!
palleexu 2013-07-02
  • 打赏
  • 举报
回复
不知道你的UartTx函数是怎么写的,也不太明白你的接收是怎么处理的,帮你排下版。
#include <p18cxxx.h>
#include "toppic.h"
#include "lcd1602.h"
#include "ds18b20.h"
#include"ds1302.h"
#include "uart.h"

long rece=0X22;   //define receive data from rs232
int tp;      //define temperature data from 1820
int hong;
long  haha;
unsigned char UartFlage;  

  /*此处为晶振为10时的取值,如用其它频率的晶振时,要改变相应的取值。*/
#define Imax 18988
#define Imin 10850
#define Inum1 1967
#define Inum2 949
#define Inum3 4069

unsigned char IR_buff[4]={0x00,0x00,0x00,0x00};/*客户码低8位,客户码高8位,数据码,数据反码*/
unsigned char show[2]={0,0};
unsigned char flag_start;/*找到启动码标志*/
unsigned long m,Tc;
unsigned char IrOK;

/*0-F共阴字形码表*/
const rom unsigned char sz[]={0x3f  , 0x06 , 0x5b , 0x4f , 0x66 ,
 0x6d ,0x7d , 0x07 , 0x7f  , 0x6f , 0x77 , 0x7c ,
 0x39 , 0x5e , 0x79 , 0x71 };



/**********************中断**************************/
void PIC18F_High_isr(void);/*中断服务函数声明*/
void PIC18F_Low_isr(void);

#pragma code high_vector_section=0x8/*高优先级中断响应时,会自动跳转到0x8处*/
void high_vector (void)
{
_asm goto PIC18F_High_isr _endasm
}
#pragma code low_vector_section=0x18
void low_vector (void)
{
_asm goto PIC18F_Low_isr _endasm
}
#pragma code


/*---高优先级中断服务程序---*/
#pragma interrupt PIC18F_High_isr
void PIC18F_High_isr (void)
{
	/*INT1解码程序*/
	/*提取中断时间间隔时长。TMR0读:先读低字节,后读高字节*/
	Tc=TMR0L;
	Tc=TMR0H*256+Tc;
	 
	TMR0H=0;/*TMR0置初值,先写高字节,后写低字节*/
	 	TMR0L=0;
	 	INTCON3bits.INT1IF=0;/*INT1溢出标志清零*/
	
	/*寻找启始码*/
	if((Tc>Imin)&&(Tc<Imax))
	{ 
		m=0;
		flag_start=1;
		return;
	}	
	/*找到启动码后,进入解码流程*/ 
	if(flag_start==1)
	{
		if(Tc>Inum1&&Tc<Inum3) 
		{
			IR_buff[m/8]=IR_buff[m/8]>>1|0x80; m++;/*取码1*/
		}
		if(Tc>Inum2&&Tc<Inum1) 
		{
			IR_buff[m/8]=IR_buff[m/8]>>1; m++;/*取码0*/
		}
		/*取码完成后判断码是否正确*/
		if(m==32) 
		{
			m=0;  
			flag_start=0;
			if(IR_buff[2]==~IR_buff[3]) 
			{
				IrOK=1; 
			}
			else IrOK=0;   
		}
	}
}

/*---低优先级中断服务程序---*/
#pragma interruptlow PIC18F_Low_isr
void PIC18F_Low_isr (void)
{
	if(PIR1bits.RCIF==1) /* 判断是不是串口接收中断 */
	{
		//rece=RCREG;
    UartFlage=1;    //一组串行数据接收完毕
	}
}

/**********************main!!!**************************/
void main(void)
{	
	toppic_init();  
	UartIni();
	LCD_init();

  IrOK=0;
	m=0;
 	flag_start=0;
 	T0CON=0b00000000;/*TMR0设置:停止运行、16位定时,预分频1:2*/
 	TMR0H=0;/*TMR0置初值,先写高字节,后写低字节*/
 	TMR0L=0;
 	T0CONbits.TMR0ON=1;/*启动TMR0*/ 
 
	INTCON2bits.INTEDG1=0;/*设定外部中断1触发边沿(下降沿)*/
	INTCON3bits.INT1IP=1;/*设置外部中断1为高优先级*/
	INTCON3bits.INT1IE=1;/*INT1中断使能*/


	TRISD=0X00;         /*设置D口为输出*/
	RCONbits.IPEN=1;/* 使能中断高低优先级 */
  INTCON=INTCON|0xc0;/* 开总中断、开外围接口中断 */

	PIE1bits.RCIE=1;/*串口接收中断允许*/

	INTCONbits.PEIE=1;/*外设中断允许*/
	INTCONbits.GIE=1;/*开总中断*/
	/**************************display temperature on the lcd1602***************************/
	LCD_setxy(1,1);
	LCD_wrstr("TEMP:");
	LCD_setxy(1,14);
	LCD_wrchar(USER_CHAR6);    //display  


	while(1)
	{
	
	  if(IrOK==1) 
		{
		  show[0]=IR_buff[2] & 0x0F;//取键码的低四位
			show[1]=IR_buff[2] >> 4; //取键码的高四位 
			IrOK=0;
		  hong=show[1]*10+show[0];
			if(hong==15)
			{
		    rece=rece+1;
			}
		  else if(hong==7)	         {rece=rece-1;}
			else
			{	 
				LCD_setxy(2,10);
				LCD_wrstr("wrong");
			}
		
		}
		tp=get_temp();         //get it!!! ( ds18b20.c)
	
	  LCD_setxy(2,4);
	  LCD_wrul(rece);
	
	
		if(tp>0x3fff)          
		{      
		  LCD_setxy(1,7);  
			LCD_wrchar('-');       
		}
	  else
	  {      
	    LCD_setxy(1,7);  
			LCD_wrchar('+');       
	  }
	  tp&=0x3fff;                //Shield symbol
		LCD_setxy(1,13);            //  location   , on the second line
		LCD_wrlval(tp,5,2);         //display the temp
	
	  UartTx(tp/100);    //暂时串口助手只能收2位16进制数
		UartTx(tp%100);
		if(UartFlage==1)
		{  
			UartFlage=0;
		}
	            
	  if((tp/100)>rece-1)  //	不知道为什么与实际数相差1?
		{
			BZ=!BZ;              //超过温度,就警报
		}
	}
}
vc8fans 2013-07-02
  • 打赏
  • 举报
回复
太长了。。。

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧