×
单片机 > 单片机程序设计 > 详情

pic16f877双机通信lcd1602液晶显示

发布时间:2020-05-16 发布时间:
|

/************************************************************************************************* 
* 文 件 名:485c.c 
* 功    能:485从机通信模块 
* 硬件条件: 1.CPU型号:PIC16F877

* 2.晶振:2M 

*************************************************************************************************/ 
//-----------------------函数声明,变量定义-------------------------------------------------------- 
#include   
#include "LCD1602.h" 
#include  
#include  
#include   
#include   
#define        L0        RB5 
#define        L1        RB6   
#define  unchar  unsigned char 
bank2    unchar send_buffer[10]; 
unsigned char Receive_Dzdata_Buffer[2];//定义接受缓冲区 
bank2    unchar Display_Rate[16];           //定义接收数据个数指示变量 
bit    orderflag,receflag; 
bank1    unsigned char dis[]={"ID:"}; 
unchar FIFO;  

//============================================================================= 
//function:函数声明 
//============================================================================== 
void             delay(void); 
void             Port_ini(void); 
void             Picini(void); 
unsigned char     CLU_checkdata(void); 
void             Send_Date(unsigned char    address); 
void            Generator_Data(void); 
void              Send_display(void); 
void            command_display(void); 
void            instruction_display(void); 


//======================================================================================== 
//函数名称:delay() 
//输入函数:无 
//返回:无 
//函数功能:延时子函数 
//======================================================================================= 
void delay(void) 

    unchar i=124; 
    while(i--); 


//======================================================================================= 
// 函数名称: Port_ini() 
// 函数功能: 端口初始化         
//======================================================================================== 
void Port_ini(void) 

    TRISA=0x00; 
    TRISB=0X00;            //RB口为输出,RB4,RB1,RB2为LCD控制端口 
    PORTB=0X00;             
    TRISC=0XF0;                     
    TRISD=0X00;             



//====================================================================================== 
// 函数名称: UART_init()串口初始化函数 
// 函数功能: 在系统时钟为11.059MHz时,设定串口波特率为9600bit/s 
//            串口接收中断允许,发送中断禁止 
//====================================================================================== 
void Picini(void) 

  
   TRISC=0xF0; 
   TXSTA=0X66;         //使能串口同步从动发送9位数据,选择高速波特率 
   RCSTA=0XD0;         //使能串口同步连续接受9位数据工作,允许单字节接受 
   SPBRG=0X33;         //设置波特率为2400BPS 
   RCIE=1;             // 
   TXIE=0;          //禁止发送中断 
   GIE=1;             //使能全局中断 
   PEIE=1;             //使能外部中断 
   ADCON1=0x07;        //禁止A口的AD转换功能(第二功能) 


//-------------------------------------------------------------------------------------------------- 
// 函数名称: CLU_checkdata()计算校验位函数 
// 输入变量: 无 
// 返回: checkdata,包括六位数据的校验异或 
// 函数功能: 计算校验异或值 
//-------------------------------------------------------------------------------------------------- 

unsigned char CLU_checkdata(void) 
{            
     unchar i,checkdata=0; 
    for(i=2;i<8;i++) 
      { 
         checkdata=checkdata^send_buffer[i];//计算校验位 
        } 
   return(checkdata); 
 } 




//=============================================================== 
// 函数名称: Generator_Data() 
// 输入变量:  
// 返回: 无 
// 函数功能: 产生数据 
//=============================================================== 

void        Generator_Data(void) 

    volatile    unsigned    long        OCCur_Data=6878968; 
    volatile    unsigned    int    Middle_Data; 
      unsigned  int    D0,D1,D2; 
    unsigned int  A1,A2,B1,B2,C1,C2; 
    Occur_Data+=100; 
//    sprintf(Display_Rate,"%d",Occur_Data); 

    if(Occur_Data==420000000) 
    {Occur_Data=688;} 
    Middle_Data=Occur_Data; 
    Middle_Data=Middle_Data/100;//定义指数幂2,即send_buffer[5]=0x07 
     
    D2=Middle_Data/10000; 
    C1=D2/16%16; 
    C2=D2%16; 
    send_buffer[4]=C1*16+C2; 

    D1=Middle_Data%10000/100; 
    B1=D1/16%16; 
    B2=D1%16; 
    send_buffer[3]=B1*16+B2; 

    D0=Middle_Data%10000%100; 
    A1=D0/16%16; 
    A2=D0%16; 
    send_buffer[2]=A1*16+A2; 
    send_buffer[5]=0x06; 
    send_buffer[6]=0x01; 
    send_buffer[7]=0x00; 


//================================================================================== 
//函数名称:Send_display() 
//输入变量: 
//返回: 
//函数功能:发送从机自加数列值给主机 
//=================================================================================== 
void  Send_display(void) 

    unchar point; 
    send_buffer[0]=Receive_Dzdata_Buffer[0]; 
    send_buffer[1]=Receive_Dzdata_Buffer[1]; 
    send_buffer[8]=CLU_checkdata();    //把校验和赋值给send_buffer[8],用于主机校验 
    send_buffer[9]=0xAA;     

for(point=0;point<10;point++) 
    { 
    TXREG=send_buffer[point]; 
    while(TXIF==0); 
    TXIF=0; 

    } 



void    command_display(void) 

        unchar i; 
        LCD_set_xy(3,0);  
        i=0; 
        while(Receive_Dzdata_Buffer[i] != ’’) 
        {                     
          LCD_write_data(Receive_Dzdata_Buffer[i]); 
          i++; 
         } 
  } 


//================================================================================ 
//name:    instruction_display() 
//function:声明显示 
//input:无 
//output:无 
//============================================================================ 

void    instruction_display(void) 

        unchar i; 
        LCD_write_cmd(0x01);      //显示清屏 
        LCD_set_xy(0,0);  
        i=0; 
        while(dis[i] != ’’) 
        {                        // 显示字符dis1 
          LCD_write_data(dis[i]); 
          i++; 
         } 
  } 


//-------------------------------------------------------------------------------------------------- 
// 函数名称: 主函数 
// 函数功能: 调度个子函数,完成通信过程 
//-------------------------------------------------------------------------------------------------- 
 void main(void) 
{     

     Port_ini(); 
    Picini(); 
    LCD_init(); 
    L0=0; 
    L1=0; 
    orderflag=0; 
    receflag=0;  
    instruction_display(); 
//    LCD_write_string(dis,0,0); 
    do 
     {      
    //    Generator_Data(); 
        if(receflag==1) 
        { 
    //    instruction_display(); 
         Send_display(); 
    //    command_display(); 
        LCD_write_string(Receive_Dzdata_Buffer,5,0); 
        receflag=0;     
         
        } 
     
     }while(1); 



//-------------------------------------------------------------------------------------------------- 
// 函数名称: serial()串口接收中断处理函数 
// 函数功能: 接收十位数据到数据缓冲区 
//-------------------------------------------------------------------------------------------------- 

void interrupt serial(void) 

     
    if(RCIF==1) 
    {    
        RCIF=0; 
        FIFO=RCREG; 
        if(FIFO==0x41)//核对主机发来的地址是否为从机地址 
            { 
                Receive_Dzdata_Buffer[0]=FIFO; 
                orderflag=1; 
                L0=1;    //地址正确D4灯点亮 
                return; 
            } 

        if(orderflag==1) 
        { 
            Receive_Dzdata_Buffer[1]=FIFO;     
            orderflag=0; 
            L1=1; 
            receflag=1; 
        }     
     
    } 


 

lcd1602.h

#include
//定义MCU与LCD的接口
#define EN   RA3
#define RW   RA2
#define RS   RA1
#define LCD_DATA  PORTD

/*--------------------------------------------------------------------------------------------------
Public function prototypes
--------------------------------------------------------------------------------------------------*/
void LCD_init         (void);
void LCD_en_write     (void);
void LCD_write_data(unsigned char data);
void LCD_string_data(unsigned char *str);
void LCD_write_cmd    (unsigned char command);
void LCD_wait_Ready   (void);
void LCD_set_xy       (unsigned char x, unsigned char y);
void LCD_write_string(unsigned char *s,unsigned char x,unsigned char y);
void delay_nms        (unsigned int n);
void delay_1ms        (void);

/**********************************************************
LCD_init(void)    :LCD初始化函数
**********************************************************/
void LCD_init(void)
  {
    delay_nms(15);
   
    LCD_write_cmd(0x38);      //8bit 
    LCD_write_cmd(0x0C);      //显示开
    LCD_write_cmd(0x01);      //显示清屏
    LCD_write_cmd(0x06);      //显示光标移动设置
  }

void LCD_en_write(void)        //EN端产生一个高电平脉冲,写LCD
  {
    EN = 0;
    delay_nms(10);
    EN = 1;
  }
/*-----------------------------------------------------------------------
LCD_write_cmd    : 写命令字函数

输入参数:command      :命令字

编写日期          :2007-4-12
最后修改日期      :2004-4-12   
-----------------------------------------------------------------------*/
void LCD_write_cmd    (unsigned char command)
  {
    LCD_DATA=command;
    RS=0;
    RW=0;
    LCD_en_write();
    
  }
/*-----------------------------------------------------------------------
LCD_write_data    : 英文字符串显示函数

输入参数:data    :英文字符串指针;
         
编写日期          :2007-4-12 
最后修改日期      :2007-4-12   
-----------------------------------------------------------------------*/
void LCD_write_data(unsigned char data)
  {
   
    //LCD_wait_Ready();
    LCD_DATA = data;
    RS=1;
    RW=0;
    LCD_en_write();  
  }


void LCD_string_data(unsigned char *str)
{
 unsigned i=0;
 while(*str)
 {
 LCD_write_data(str[i]);
 i++;
 }
}

void LCD_wait_Ready(void)                  //等待LCD空闲
  {
    TRISD |= 0x80;                 //PC7 I/O口方向设置为输入
    RW=1;  
    RS=0;   
    EN=1;  
    while (!( LCD_DATA&0x80 ) == 0);   //RW=1,读PC7,为0表示空闲;   
    TRISD= 0x00;
  }

/*-----------------------------------------------------------------------
LCD_set_xy        : 设置LCD显示的起始位置

输入参数:x、y    : 显示字符串的位置,X:0-15,Y:0-1
                    LCD第一行显示寄存器地址:0X80-0X8F
                    LCD第一行显示寄存器地址:0XC0-0XCF

编写日期          :2004-8-19 
最后修改日期      :2004-8-19   
-----------------------------------------------------------------------*/
void LCD_set_xy( unsigned char x, unsigned char y )
  {
    unsigned char address;
    if (y == 0) address = 0x80 + x;
    else 
       address = 0xc0 + x;
    LCD_write_cmd( address );
  }
/*-----------------------------------------------------------------------
LCD_write_string  : 英文字符串显示函数

输入参数:*s      :英文字符串指针;
          X、Y    : 显示字符串的位置

编写日期          :2004-8-19 
最后修改日期      :2004-8-19   
-----------------------------------------------------------------------*/
void LCD_write_string(unsigned char *s,unsigned char x,unsigned char y)
  {
    unsigned char ch,i=0;
    if (y == 0)
  ch = 0x80 + x;
    else 
       ch = 0xc0 + x;
    
    while (*s) 
      {
  LCD_write_cmd(ch+i);
        LCD_write_data( s[i] );
  i++;
      }
  }
 

 

void delay_1ms(void)                 //1ms延时函数
  {
   unsigned int i;
   for (i=0;i<1000;i++);
  }
  
void delay_nms(unsigned int n)       //N ms延时函数
  {
   unsigned int j=0;
   for (j=0;j   delay_1ms();
  }



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil(MDK-ARM)系列教程(七)_菜单