本帖最后由 limin86918 于 2010-4-11 19:04 编辑
最近在做一个试验台挂件识别和按键指示灯操作的小项目,原来是用西门子S7-200
实现的,由于功能比较简单,BOSS(我的研究生导师)嫌PLC太贵了(总共承包了学校
8台试验台,主要是电力谐波和无功补偿方面的试验台,供本科生做实验用),要我(
申明一下,我是一名电气工程专业研一学生)用单片机去代替以节约成本。现在我的
进度到了现在这个程度:硬件电路设计完毕,并且分块功能调试成功,现在是卡在PIC16F877A编程上了,就差功能的整合了。希望各位老鸟、高手指点赐教,小弟在此
谢过了!
现在我的问题是:试验台有八个挂件,每个挂件串入或者并入主供电线上,串并关系通过相应继电器的吸合控制,继电器控制的单片机I/O端口为:RC1,RC2,RC3,RA0,RA1,RA2,RB5,RB0(位置与挂件序号对应,如RC1控制一号挂件的串并),每次扫描挂件编码时(编码有6位,包括串并位C/B,0定义为串入,1为并入),如果检测到C/B=0,则让相应的继电器吸合。扫描的方法采用for循环,将地址从0b00~0b111扫描,我要怎么样编程在for循环中控制无规则的I/O端口呢?我的想法是把这些无规则的端口放在一个数组里,控制下标就可以实现有序控制了,但是程序报错了。请高手指点。
以下为我编写的程序,报错的(位数组定义有问题?):
#include "head.h"
uchar flag; //自检键是否按下标志,uchar,uint在头文件中定义
uchar finish; //自检完成标志
uchar data[8]; //定义一个8位数组存放读取的编码板数据
bit relay[12]={RC0,RC1,RC2,RC3,RA0,RA1,RA2,RB5,RB0,RB1,RB2,RB3};
//上面是继电器控制位,这样定义可以么?有位组成的数组么?
/******************************************************/
//延时子程序
void delay(uint x)
{
uchar y;
for(;x>0;x--)
for(y=0;y<120;y++);
}
/******************************************************/
//端口初始化子程序
void init()
{
TRISA=0x38; //RA<0:2>做继电器输出控制口,RA<3:5>做按键操作输入口
TRISB=0x00; //RB<0:2,4:5>口做继电器输出控制口,其他口做ICSP调试口
TRISC=0xc0; //RC<0:3>口做继电器输出控制口,RC<6:7>做RS232通讯输入端口
TRISD=0xff; //RD<0:6>数据总线输入口
TRISE=0x00; //RE<0:2>地址总线输出口
PORTA=0x00;
PORTB=0x00;
PORTC=0x00;
PORTD=0x00;
PORTE=0x00; //I/O端口数据初始化为零
ADCON1=0x06; //A、E口为模拟输入复用口,初始化关闭A/D采样功能
flag=0; //是否按下自检标志初始化为零
}
/******************************************************/
//自检数据读取、控制继电器子程序
void check()
{
uchar num=0; //定义数组下标
DIS_CHECK=1; //自检灯以一定频率闪烁
delay(200);
for(PORTE=0x00;PORTE<=0x07;PORTE++) //地址线(RE<0:2>)从0b000-0b111扫描
{
if(LIFE&!CB) //有挂件且C/B位为零则动作相应继电器
relay[num+1]=1; //挂件控制继电器从第二个开始,第一个为主继电器
data[num]=PORTD; //读取相应数据,如没有挂件数据为零
num++; //下标自加
DIS_CHECK=!DIS_CHECK; //自检灯以一定频率闪烁
delay(200);
}
}
/******************************************************/
//按键指示灯控制子程序
void button_lamp()
{
if(RUN&flag) //启动按键检测
{
delay(35); //延时消除按键抖动
if(RUN&flag)
{
DIS_RUN=1;
DIS_CHECK=0;
DIS_STOP=0;
}
flag=0;
}
if(STOP) //停止按键检测
{
delay(35); //延时消除按键抖动
if(STOP)
{
DIS_RUN=0;
DIS_CHECK=0;
DIS_STOP=1;
}
}
if(CHECK&DIS_STOP) //自检按键检测
{
delay(35); //延时消除按键抖动
if(CHECK&DIS_STOP)
{
DIS_RUN=0;
DIS_STOP=1;
flag=1;
check();
}
}
}
/******************************************************/
//主程序
void main()
{
init();
while(1)
{
button_lamp();
}
}
头文件head.h定义:
#include<pic.h>
#define uint unsigned int
#define uchar unsigned char
#define RUN RA3
#define STOP RA4
#define CHECK RA5
#define DIS_STOP RB0
#define DIS_CHECK RB1
#define DIS_RUN RB2
#define AB1 RE0
#define AB2 RE1
#define AB3 RE2
#define BM1 RD0
#define BM2 RD1
#define BM3 RD2
#define BM4 RD3
#define BM5 RD4
#define CB RD5
#define LIFE RD6 |