一.原理图
功能介绍:
(1).U1单片机控制4X5的矩阵键盘和十个指示灯,名称按图所示.
(2).U2单片机控制18个继电器.
(3).按键”选择枪1”,”选择枪2”,”选择枪3”,”选择枪4”,”PREHEAT”,”CUTTING”,”HEIGHT”,”RETRACE”,”PLASMA”这9个按键是一键控制相对应的继电器的开关.就是说按一下为开,送开保持原先状态,再按一下为关,送开保持,即实现一个D触发器的电平翻转功能.
(4).按键”1 UP”,”1 DOWN”,”2 UP”,”2 DOWN”,”3 UP”,”3 DOWN”,”4 UP”,”4 DOWN”,”ALL UP”,”ALL DOWN”,”IGNITION”为点动按键,即按下为开,继电器吸合,送开为关,继电器放开.
(5).所用单片机为P16F873A
二.程序
为观察方便,特把图分为发送部分和接收部分,并分别编程.
1. 发送部分
原理图如下所示
/***********************************************************************
* 文件标题:CNC-USART-1 *
* 编制日期:2007.12.19 *
* 编制人: wujieflash *
* 程序用途:用于数控切割机上的面板通信(发送部分) *
* 配套图纸:CNC-02 *
* 版本号: V1.0 *
***********************************************************************/
#include
//函数声明
void initial();
void delay();
void key_scan();
void key_serve();
void send_usart();
//定义变量
unsigned int i,j,k1,k2,k3,k4,k5,k6,k7,k8,k9,k10;
//子程序
//初始化子程序
void initial()
{
ADCON1=0x06;//设置为普通数字引脚
TRISC0=0;//键盘四根行线设置为输出
TRISC1=0;
TRISC2=0;
TRISC3=0;
TRISC4=1;//键盘五根列线设置为输入
TRISC5=1;
TRISA2=1;
TRISA3=1;
TRISA4=1;
TRISB=0;
PORTB=0;
TRISA0=0;
RA0=0;
TRISA1=0;
RA1=0;
RC0=0;//四根行线先送低电平
RC1=0;
RC2=0;
RC3=0;
//USART部件初始化
SPBRG=0x19;//设置波特率为9600bps
TXSTA=0x04;//选择异步高速8位数据传输模式
RCSTA=0x80;//允许串行端口工作
TRISC6=1;//设置为高阻态,防止干扰
TRISC7=1;
}
//延时子程序
void delay()
{
for(i=2000;i--;)
continue;
}
//键盘扫描子程序
void key_scan()
{
while(1)
{
if((RC4==0)||(RC5==0)||(RA2==0)||(RA3==0)||(RA4==0))//是否有键按下
{
break;
}
}
delay();
if((RC4==0)||(RC5==0)||(RA2==0)||(RA3==0)||(RA4==0))//确认有键按下
{
key_serve();
}
else
{
j=0x00;
send_usart();
}
}
//按键服务子程序
void key_serve()
{
RC1=1;//先置RC0为低电平,剩余三根行线为高电平
RC2=1;
RC3=1;
RC0=0;
if(RC4==0)//按键1 “select 1"
{
k1++;
k1=k1%2;
if(k1==1)//奇数次为开
{
j=0x01;
send_usart();
RB0=1;//指示灯亮
}
if(k1==0)//偶数次为关
{
j=0x15;
send_usart();
RB0=0;//指示灯灭
}
}
if(RC5==0)//按键2 "1 up"
{
j=0x02;
send_usart();
}
if(RA2==0)//按键3 "1 down"
{
j=0x03;
send_usart();
}
if(RA3==0)//按键4 "select 2"
{
k2++;
k2=k2%2;
if(k2==1)//奇数次为开
{
j=0x04;
send_usart();
RB1=1;
}
if(k2==0)//偶数次为关
{
j=0x16;
send_usart();
RB1=0;
}
}
if(RA4==0)//按键5 “2 up"
{
j=0x05;
send_usart();
}
RC0=1;//置RC1为低电平,剩余行线为高
RC2=1;
RC3=1;
RC1=0;
if(RC4==0)//按键6 "2 down"
{
j=0x06;
send_usart();
}
if(RC5==0)//按键7 "select 3"
{
k3++;
k3=k3%2;
if(k3==1)
{
j=0x07;
send_usart();
RB2=1;
}
if(k3==0)
{
j=0x17;
send_usart();
RB2=0;
}
}
if(RA2==0)//按键8 "3 up"
{
j=0x08;
send_usart();
}
if(RA3==0)//按键9 "3 down"
{
j=0x09;
send_usart();
}
if(RA4==0)//按键10 "select 4"
{
k4++;
k4=k4%2;
if(k4==1)
{
j=0x0a;
send_usart();
RB3=1;
}
if(k4==0)
{
j=0x18;
send_usart();
RB3=0;
}
}
RC0=1;//置RC2为低电平,剩余为高
RC1=1;
RC3=1;
RC2=0;
if(RC4==0)//按键11 "4 up"
{
j=0x0b;
send_usart();
}
if(RC5==0)//按键12 "4 down"
{
j=0x0c;
send_usart();
}
if(RA2==0)//按键13 "all up"
{
j=0x0d;
send_usart();
}
if(RA3==0)//按键14 "all down"
{
j=0x0e;
send_usart();
}
if(RA4==0)//按键15 "preheat"
{
k5++;
k5=k5%2;
if(k5==1)
{
j=0x0f;
send_usart();
RB4=1;
}
if(k5==0)
{
j=0x19;
send_usart();
RB4=0;
}
}
RC0=1;//置RC3为低,剩余为高
RC1=1;
RC2=1;
RC3=0;
if(RC4==0)//按键16 "cutting"
{
k6++;
k6=k6%2;
if(k6==1)
{
j=0x10;
send_usart();
RB5=1;
}
if(k6==0)
{
j=0x1a;
send_usart();
RB5=0;
}
}
if(RC5==0)//按键17 "height"
{
k7++;
k7=k7%2;
if(k7==1)
{
j=0x11;
send_usart();
RB6=1;
}
if(k7==0)
{
j=0x1b;
send_usart();
RB6=0;
}
}
if(RA2==0)//按键18 "ignition"
{
j=0x12;
send_usart();
RB7=1;
}
if(RA3==0)//按键19 "retrace"
{
k9++;
k9=k9%2;
if(k9==1)
{
j=0x13;
send_usart();
RA0=1;
}
if(k9==0)
{
j=0x1d;
send_usart();
RA0=0;
}
}
if(RA4==0)//按键20 "oxy/plasma"
{
k10++;
k10=k10%2;
if(k10==1)
{
j=0x14;
send_usart();
RA1=1;
}
if(k10==0)
{
j=0x1e;
send_usart();
RA1=0;
}
}
RC0=0;//置四根行线为低电平
RC1=0;
RC2=0;
RC3=0;
while(1)
{
if((RC4==1)&&(RC5==1)&&(RA2==1)&&(RA3==1)&&(RA4==1))//等键松开
break;
}
RB7=0;//关“IGNITION”指示灯
j=0x00;
send_usart();
}
//命令发送子程序
void send_usart()
{
TXEN=1;//发送允许
CREN=1;//接收允许
TXREG=j;
while(1)
{
if(TXIF==1)break;//等待发送完成
}
while(1)
{
if(RCIF==1)break;//等待接收完成
}
RCREG=RCREG;//读响应字节,清RCIF
}
//主程序
void main(void)
{
initial();
while(1)
{
key_scan();
}
}
2.接收部分
原理图如下所示
/***********************************************************************
* 文件标题:CNC-USART-2 *
* 编制日期:2007.12.19 *
* 编制人: 吴杰 *
* 程序用途:用于数控切割机上的面板通信(接收部分) *
* 配套图纸:CNC-01 *
* 版本号: V1.0 *
***********************************************************************/
#include
//函数声明
void initial();
void recevie_usart();
void rece_serve();
//定义变量
unsigned int rece;
//子程序
//初始化子程序
void initial()
{
ADCON1=0x06;//设置RA口为普通数字端口
TRISA=0;
PORTA=0;
TRISB=0;
PORTB=0;
TRISC=0;
PORTC=0;
//USART部件初始化
SPBRG=0x19;//设置波特率为9600bps
TXSTA=0x04;//选择异步高速8位数据传输模式
RCSTA=0x80;//允许串行端口工作
TRISC6=1;//设置为高阻态,防止干扰
TRISC7=1;
}
//接收子程序
void recevie_usart()
{
CREN=1;
TXEN=1;
while(1)
{
if(RCIF==1)break;//接收完毕
}
rece=RCREG;//读取接收到的数据,并清RCIF
TXREG=rece;//待发送的数据
while(1)
{
if(TXIF==1)break;//发送完毕
}
}
//接收服务子程序
void rece_serve()
{
switch(rece)
{
case 0x00:{
RC2=0;//继电器“1 up"关
RC3=0;//继电器"1 down"关
RC4=0;//继电器”2 up"关
RC5=0;//继电器“2 down"关
RA0=0;//继电器”3 up"关
RA1=0;//继电器“3 down"关
RA2=0;//继电器”4 up"关
RA3=0;//继电器“4 down"关
RB7=0;//继电器“ignition"关
break;
}
case 0x01:{
RB0=1;//继电器”1 select"开
break;
}
case 0x15:{
RB0=0;//继电器“1 select"关
break;
}
case 0x02:{
RC2=1;//继电器”1 up"开
break;
}
case 0x03:{
RC3=1;//继电器”1 down"开
break;
}
case 0x04:{
RB1=1;//继电器”2 select"开
break;
}
case 0x16:{
RB1=0;//继电器”2 select"关
break;
}
case 0x05:{
RC4=1;//继电器”2 up"开
break;
}
case 0x06:{
RC5=1;//继电器”2 down"开
break;
}
case 0x07:{
RB2=1;//继电器”3 select"开
break;
}
case 0x17:{
RB2=0;//继电器”3 select"关
break;
}
case 0x08:{
RA0=1;//继电器”3 up"开
break;
}
case 0x09:{
RA1=1;//继电器”3 down"关
break;
}
case 0x0a:{
RB3=1;//继电器”4 select"开
break;
}
case 0x18:{
RB3=0;//继电器”4 select"关
break;
}
case 0x0b:{
RA2=1;//继电器”4 up"开
break;
}
case 0x0c:{
RA3=1;//继电器”4 down"开
break;
}
case 0x0d:{
RC6=1;//继电器”all up"开
RC4=1;
RC2=1;
RA0=1;
break;
}
case 0x0e:{
RA1=1;//继电器”all down"开
RC3=1;
RC5=1;
RC7=1;
break;
}
case 0x0f:{
RB4=1;//继电器”preheat"开
break;
}
case 0x19:{
RB4=0;//继电器”preheat"关
break;
}
case 0x10:{
RB5=1;////继电器”cutting"开
break;
}
case 0x1a:{
RB5=0;//继电器”cutting"关
break;
}
case 0x11:{
RB6=1;////继电器”height"开
break;
}
case 0x1b:{
RB6=0;//继电器”height"关
break;
}
case 0x12:{
RB7=1;//继电器”ignition"开
break;
}
/*case 0x1c:{
RB7=0;//继电器”ignition"关
break;
}*/
case 0x13:{
RC0=1;//继电器”retrace"开
break;
}
case 0x1d:{
RC0=0;//继电器”retrace"关
break;
}
case 0x14:{
RC1=1;//继电器”plasma"开
break;
}
case 0x1e:{
RC1=0;//继电器”plasma"关
break;
}
}
}
//主程序
void main()
{
initial();
while(1)
{
recevie_usart();
rece_serve();
}
}
三,总结
虽然板子用用也没啥问题,但程序毕竟考虑的简单了一些,如:没有考虑故障处理的问题,我打算写进一段自动提示故障的程序,在两板之间通信线出现问题不通的时候,闪烁指示灯提示.还有什么欠考虑的地方请大家一起帮忙!
上一篇:PIC单片机实例五:基于PROTEUS模拟的精美万年历
下一篇:PIC单片机实例二:基于I2C的SAA1064数码管显示
推荐阅读最新更新时间:2024-03-16 15:19
设计资源 培训 开发板 精华推荐
- NXP 2.5亿美元收购Aviva,但车载SerDes领域依然处于战国时期
- 应对 AI 时代的云工作负载,开发者正加速向 Arm 架构迁移
- 沉浸式体验漫威宇宙,英特尔锐炫显卡为《漫威争锋》提供Day 0支持
- 艾迈斯欧司朗与法雷奥携手革新车辆内饰,打造动态舱内环境
- 《嵌入式-STM32开发指南》第二部分 基础篇 - 第7章DMA(HAL库)
- 【“源”察秋毫系列】DC-DC电源效率测试,确保高效能与可靠性的关键步骤
- NVIDIA 推出高性价比的生成式 AI 超级计算机
- Mapbox与Arm合作推出虚拟主机 加速软件定义汽车导航
- 移植tslib和Qt5.6到三星s5pv210开发板
- 智能座舱新赛点在哪? 看这四款重磅新车