/*************************************************************************************************
* 文 件 名: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
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』