/**************************************************************
** 文件名:usart_tongxin.c **
** 功 能:实现单片机串行通信的收发功能。两片单片机通信,
单片机1键盘按键按下,单片机2显示单片机1按下的按键
值,单片机2 键盘按键按下,单片机1显示单片机2按下的
按键值。 **
**************************************************************/
#include<pic.h> //包含PIC16F877A内部寄存器的定义文件
__CONFIG(0X1832); //芯片配置字,看门狗关,上电延时开,
//掉电检测关,低压编程关,加密,4M晶体HS振荡
#define uchar unsigned char //定义无符号字符类型
#define uint unsigned int //定义无符号整形类型
void jianpan_saomiao(); //函数申明
uchar a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,
0x6f,0x77,0x7C,0x39,0x5E,0x79,0x71,0x76};//共阴数码管显示0~F段码值
uchar jz,k,mark; //定义无符号通用寄存器
/**************************************************
#include<pic.h> //包含PIC16F877A内部寄存器的定义文件
__CONFIG(0X1832); //芯片配置字,看门狗关,上电延时开,
//掉电检测关,低压编程关,加密,4M晶体HS振荡
#define uchar unsigned char //定义无符号字符类型
#define uint unsigned int //定义无符号整形类型
void jianpan_saomiao(); //函数申明
uchar a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,
0x6f,0x77,0x7C,0x39,0x5E,0x79,0x71,0x76};//共阴数码管显示0~F段码值
uchar jz,k,mark; //定义无符号通用寄存器
/**************************************************
*函数功能:端口初始化 *
*入口:无 *
*出口:无 *
**************************************************/
void initial(void)
{
ADCON1=0X07; //将A、E端口设置为通用I/O口
TRISA=0X00; //A口设置为输出
PORTA=0X00; //端口A置低电平
TRISC=0x80; //RC端口RC6、RC7分别为输出和输入
TRISD=0x00; //端口D设置为输出
PORTD=0x00; //PORTD输出清零
PORTC=0X00; //端口C初始设置为低电平
TRISB=0XF0; //R0~RB3设置为输出,R4~RB5设置为输入
PORTB=0XF0; //R0~RB3设置为低电平,R4~RB5设置为高电平
INTCON=0xC0; //总中断和外设中断使能
}
/**************************************************
*函数功能:串行通信接收数据设置 *
*入口:无 *
*出口:无 *
**************************************************/
void usart_set(void)
{
SPBRG=0x1A; //设置波特率9600,系统时钟4MHZ
TXSTA=0b00100100; //异步方式、高波特率,发送不使能
RCSTA=0b10010000; //设置连续接收数据
RCIE=1; //开放usart的接收中断
RCREG=0; //接收缓冲寄存器清0
}
/**************************************************
*函数功能:延时微秒级程序 *
*入口:j *
*出口:无 *
**************************************************/
void Delay_us(uchar j)
{
while(--j); //通过设置j的值可设置延时时间长短
}
/**************************************************
*函数功能:中断服务程序 *
*入口:无 *
*出口:无 *
**************************************************/
void interrupt usart()
{
if(RCIF==1) //接收到数据产生中断
{
PORTD=RCREG; //显示收到的数据,通过D口显示
}
}
/**************************************************
*函数功能:主函数 *
*入口:无 *
*出口:无 *
**************************************************/
void main()
{
initial(); //端口和中断使能初始化
while(1)
{
usart_set(); //串行通信接收数据设置
jianpan_saomiao(); //调用键盘扫描程序
if(mark==1) //有键按下时
{
TXREG=a[jz]; //将按键值发送到发送寄存器
mark=0; //清除按键按下的标志位
}
}
}
/**************************************************
*函数功能:键盘扫描 *
*入口:无 *
*出口:无 *
**************************************************/
void jianpan_saomiao()
{
if(PORTB!=0XF0) //判断是否有键按下
{
Delay_us(150); //延时消抖动
if(PORTB!=0XF0) //再次判断是否有键按下
{
mark=1; //有键按下时,自定义标志位
PORTB=0XFE; //将RB0设置输出低电平,扫描矩阵键盘第一行
switch(PORTB)
{ case 0xEE: jz=0;break; //若RB4为低电平,则键0按下
case 0xDE: jz=1;break; //若RB5为低电平,则键1按下
case 0xBE: jz=2;break; //若RB6为低电平,则键2按下
case 0x7E: jz=3;break; //若RB7为低电平,则键3按下
}
PORTB=0XFD; //将RB1设置输出低电平,扫描矩阵键盘第二行
switch(PORTB)
{ case 0xED: jz=4;break; //若RB4为低电平,则键4按下
case 0xDD: jz=5;break; //若RB5为低电平,则键5按下
case 0xBD: jz=6;break; //若RB6为低电平,则键6按下
case 0x7D: jz=7;break; //若RB7为低电平,则键7按下
}
PORTB=0XFB; //将RB2设置输出低电平,扫描矩阵键盘第三行
switch(PORTB)
{ case 0xEB: jz=8;break; //若RB4为低电平,则键8按下
case 0xDB: jz=9;break; //若RB5为低电平,则键9按下
case 0xBB: jz=10;break; //若RB6为低电平,则键A按下
case 0x7B: jz=11;break; //若RB7为低电平,则键B按下
}
PORTB=0XF7; //将RB3设置输出低电平,扫描矩阵键盘第四行
switch(PORTB)
{ case 0xE7: jz=12;break; //若RB4为低电平,则键C按下
case 0xD7: jz=13;break; //若RB5为低电平,则键D按下
case 0xB7: jz=14;break; //若RB6为低电平,则键E按下
case 0x77: jz=15;break; //若RB7为低电平,则键F按下
}
PORTB=0XF0; //对端口清零
while(PORTB!=0XF0); //等待键释放
}
}
} |