📄 can.c
字号:
#include "public.h"
void can_init(void)
{
P2_7=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
P2_7=1;
do{XBYTE[((P2&0xe0)|0x0F)*256]=0x09;} //进入复位状态,为单滤波方式
while(XBYTE[((P2&0xe0)|0x0F)*256]&0x01==0); //复位信号的查询和置位
//定义时钟分配器,CLKOUT没有使用,则clock off为1,RXINTEN为0,CBP置位,CAN 模式为Pelican,为1;
XBYTE[((P2&0xe0)|0x0F)*256+31]=0xc8;
XBYTE[((P2&0xe0)|0x0F)*256+3]=0; //禁止SJA1000所有的中断
XBYTE[((P2&0xe0)|0x0F)*256+16]=0x2c; //代码为:00101100,101:内选标识符+1+内选标识符
XBYTE[((P2&0xe0)|0x0F)*256+17]=0xa0;
XBYTE[((P2&0xe0)|0x0F)*256+18]=0x00;
XBYTE[((P2&0xe0)|0x0F)*256+19]=0x00;
XBYTE[((P2&0xe0)|0x0F)*256+20]=0x00;
XBYTE[((P2&0xe0)|0x0F)*256+21]=0x00;
XBYTE[((P2&0xe0)|0x0F)*256+22]=0xff;
XBYTE[((P2&0xe0)|0x0F)*256+23]=0xff;
// 定义总线定时器:波特率为:125kbit,采样点为:87。5%
XBYTE[((P2&0xe0)|0x0F)*256+6]=0x02; //此时为12兆晶振。
XBYTE[((P2&0xe0)|0x0F)*256+7]=0x1c;
//当为8兆晶振时,应该为:XBYTE[0x06]=0x01;XBYTE[0x07]=0x1c;
//定义CAN输出:TX1悬空,TX0为推拉方式,输出为Normal方式
//当为16兆晶振时,应该为:XBYTE[0x06]=0x03;XBYTE[0x07]=0x1c;
//定义CAN输出:TX1悬空,TX0为推拉方式,输出为Normal方式
XBYTE[((P2&0xe0)|0x0F)*256+8]=0x1a;
//定义RX buffer start address RBSA(由于每个数据帧为11个字节)
do //置位复位状态
{XBYTE[((P2&0xe0)|0x0F)*256]=0x08;} //运行状态,单滤波
while((XBYTE[((P2&0xe0)|0x0F)*256]&0x01)!=0x00);
}
void senddata(void)
{
uchar i=0,j=0;
uchar cTemp=0;
uchar cTempOrg=0;
uchar cTemp5State=0;
uchar cIdx=0;
//5状态发送条件: 1.变化时发送; 2.500ms定时发送
if(time_5sta_flg==1){ // 100ms计时到
if((sum_state1==0)||(sum_state1>=TIMER_FILTER_NUM)){ //司机上状态
if(temp_state1==1){
cTemp5State=0;
}else if(temp_state1==0){
cTemp5State=1;
}
if(m_state1!=temp_state1){ //变化
//第二块内选板不发送5状态 2005.03.03
// dispose_sendata(49,cTemp5State);
_nop_();
_nop_();
}
m_state1=cTemp5State;
}else{
//不做处理
}
if((sum_state2==0)||(sum_state2>=TIMER_FILTER_NUM)){ //司机下状态
if(temp_state2==1){
cTemp5State=0;
}else if(temp_state2==0){
cTemp5State=1;
}
if(m_state2!=temp_state2){ //变化
//第二块内选板不发送5状态 2005.03.03
// dispose_sendata(50,cTemp5State);
_nop_();
_nop_();
}
m_state2=cTemp5State;
}else{
//不做处理
}
if((sum_state3==0)||(sum_state3>=TIMER_FILTER_NUM)){ //司机状态
if(temp_state3==1){
cTemp5State=0;
}else if(temp_state3==0){
cTemp5State=1;
}
if(m_state3!=temp_state3){ //变化
//第二块内选板不发送5状态 2005.03.03
// dispose_sendata(51,cTemp5State);
_nop_();
_nop_();
}
m_state3=cTemp5State;
}else{
//不做处理
}
if((sum_state4==0)||(sum_state4>=TIMER_FILTER_NUM)){ //直驶状态
if(temp_state4==1){
cTemp5State=0;
}else if(temp_state4==0){
cTemp5State=1;
}
if(m_state4!=temp_state4){ //变化
//第二块内选板不发送5状态 2005.03.03
// dispose_sendata(52,cTemp5State);
_nop_();
_nop_();
}
m_state4=cTemp5State;
}else{
//不做处理
}
if((sum_state5==0)||(sum_state5>=TIMER_FILTER_NUM)){ //保留状态
if(temp_state5==1){
cTemp5State=0;
}else if(temp_state5==0){
cTemp5State=1;
}
if(m_state5!=temp_state5){ //变化
//第二块内选板不发送5状态 2005.03.03
// dispose_sendata(53,cTemp5State);
_nop_();
_nop_();
}
m_state5=cTemp5State;
}else{
//不做处理
}
sum_state1=0;
sum_state2=0;
sum_state3=0;
sum_state4=0;
sum_state5=0;
time_5sta_flg=0;
time_5sta_count=TIMER_FILTER_NUM;
}
if(time_insel_flg==1){
//内选数据发送(注意点:由于硬件的限制,内选按钮数组只能使用前3个字节)
keyboardorg[0]=keyboard[0];
keyboardorg[1]=keyboard[1];
keyboardorg[2]=keyboard[2];
keyboard[0]=array0[0]|array1[0]|array2[0]|array3[0]|array4[0];
keyboard[1]=array0[1]|array1[1]|array2[1]|array3[1]|array4[1];
keyboard[2]=array0[2]|array1[2]|array2[2]|array3[2]|array4[2];
//(1.此处简化逻辑,提高效率 2.对应24-48层)
//2004.01.28 LHM
for(i=0; i<3; i++){
for(j=0; j<8; j++){
cTempOrg = (keyboardorg[i]>>j)&0x01;
cTemp = (keyboard[i]>>j)&0x01;
if((cTempOrg==1)&&(cTemp==0)){ //按钮被按下
cIdx=24+i*8+j; //based 0
if((cIdx>=24)&&(cIdx<=(m_cMaxFloorCnt-1)))
SendInSelData(cIdx);
}
}
}
time_insel_flg=0;
time_insel_count=TIMER_100ms;
}
//500ms发送5状态,读最大楼层数
if(time_500ms_flg==1){
//第二块内选板不发送5状态 2005.03.03
/*
dispose_sendata(49,m_state1); //司机上
_nop_();
_nop_();
_nop_();
_nop_();
dispose_sendata(50,m_state2); //司机下
_nop_();
_nop_();
_nop_();
_nop_();
dispose_sendata(51,m_state3); //司机
_nop_();
_nop_();
_nop_();
_nop_();
dispose_sendata(52,m_state4); //直驶
_nop_();
_nop_();
_nop_();
_nop_();
dispose_sendata(53,m_state5); //保留
_nop_();
_nop_();
_nop_();
_nop_();
*/
if((m_cMaxFloorCnt<2)||(m_cMaxFloorCnt>48)){
dispose_sendata(57,1); //读楼层数
_nop_();
_nop_();
_nop_();
_nop_();
}
time_500ms_flg=0;
time_500ms_count=TIMER_500ms;
}
}
void dispose_sendata(uchar data1,uchar data2) //发送数据,每次发送两个数据
{ do {}
while((XBYTE[((P2&0xe0)|0x0F)*256+2]&0x04)!=0x04); //判断发送缓冲区是否释放
XBYTE[((P2&0xe0)|0x0F)*256+16]=0x02; //数据长度为2;
XBYTE[((P2&0xe0)|0x0F)*256+17]=0xac; //发送标识符为:10101+1+00101:控制器标识符+内选标识符
XBYTE[((P2&0xe0)|0x0F)*256+18]=0xa0;
XBYTE[((P2&0xe0)|0x0F)*256+19]=data1;
XBYTE[((P2&0xe0)|0x0F)*256+20]=data2;
XBYTE[((P2&0xe0)|0x0F)*256+1]=0x01;
}
//仅对应24层以上,cIdx from 24 to 47
void SendInSelData(uchar cIdx)
{
uchar cLamp=0;
uchar cGrpIdx, cSurplus;
cGrpIdx = (cIdx)/GRP_UNIT_NUM;
cSurplus= (cIdx)%GRP_UNIT_NUM;
cLamp = (m_cInSelLamp[cGrpIdx]>>cSurplus)&0x01;
if(m_cDirect==1){ //上
if(cLamp==1){ //亮
dispose_sendata((cIdx+1),0);
}else if(cLamp==0){ //暗
// if(cIdx>(m_cCurFloorNum-1))
dispose_sendata((cIdx+1),1);
}
}else if(m_cDirect==0){ //下
if(cLamp==1){ //亮
dispose_sendata((cIdx+1),0);
}else if(cLamp==0){ //暗
// if(cIdx<(m_cCurFloorNum-1)){
dispose_sendata((cIdx+1),1);
/* if(cIdx==3){//for test
reg_insellamp(9,1);
}
if(m_cCurFloorNum==5){//for test
reg_insellamp(10,1);
}*/
// }
}
}else if(m_cDirect==0xFF){ //无
if(cLamp==1){ //亮
dispose_sendata((cIdx+1),0);
}else if(cLamp==0){ //暗
dispose_sendata((cIdx+1),1);
}
}
}
/*
uchar getsenddata(void)
{
uchar cTest;
return(cTest);
}
*/
void receivedata(void)
{
uchar /*c0id1,c0id2,*/c0command,c0data;
if((XBYTE[((P2&0xe0)|0x0F)*256+2]&1)==1){
// c0id1=XBYTE[((P2&0xe0)|0x0F)*256+17]; //接收的数据id1
// c0id2=XBYTE[((P2&0xe0)|0x0F)*256+18]; //接收的数据id2
c0command=XBYTE[((P2&0xe0)|0x0F)*256+19]; //接收的命令
c0data=XBYTE[((P2&0xe0)|0x0F)*256+20]; //接收的参数
XBYTE[((P2&0xe0)|0x0F)*256+1]=0xc;
dispose_recdata(/*c0id1,c0id2,*/c0command,c0data);/*调用数据处理*/
time_nocan_count=TIMER_5s;
time_nocan_flg=0;
}
}
void dispose_recdata(/*uchar c0id1,uchar c0id2,*/uchar c0command,uchar c0data)
{
// uchar cTemp;
//2005.03.07
if((c0command>=25)&&(c0command<=m_cMaxFloorCnt)){ //内选灯(仅接收25-48层内选灯)
reg_insellamp(c0command,c0data);
}else if(c0command==49){ // 超载
if(c0data==1){
m_cOverLoadLampFlg=1;
}else if(c0data==0){
m_cOverLoadLampFlg=0;
}
}else if(c0command==50){ // 蜂鸣器
if(c0data==1){
m_cBingFlg=1;
}else if(c0data==0){
m_cBingFlg=0;
}
}else if(c0command==51){ // 到站钟(只有确认,没有取消)
if(c0data==1){
m_cArriveRingFlg=1;
}else if(c0data==0){
m_cArriveRingFlg=0;
}
}else if(c0command==0xCC){ // 灯全灭
m_cInSelAllOffFlg=1;
}else if(c0command==0xAA){ // 最大楼层数
if(m_cMaxFloorCnt!=c0data)
if((c0data>=1)&&(c0data<=48)){
m_cMaxFloorCnt=c0data;
m_set5045flg=0;
}
}else if(c0command==0x5A){ // 方向
if(c0data==0x55){
m_cDirect=1;
}else if(c0data==0xAA){
m_cDirect=0;
}else if(c0data==0x00){
m_cDirect=0xFF;
}
}
}
void reg_insellamp(uchar c0command,uchar c0data)
{
uchar cGrpIdx, cSurplus;
uchar cUp24Idx;
//2005.01.27 LHM
cUp24Idx= c0command;
cGrpIdx = (cUp24Idx-1)/GRP_UNIT_NUM;
cSurplus= (cUp24Idx-1)%GRP_UNIT_NUM;
//!!!24层以上lamp登记在灯数组的后3字符
if(c0data==1){
m_cInSelLamp[cGrpIdx]=m_cInSelLamp[cGrpIdx]|(0x01<<cSurplus);
}else if(c0data==0){
m_cInSelLamp[cGrpIdx]=m_cInSelLamp[cGrpIdx]&(~(0x01<<cSurplus));
}else if(c0data==0xAA){ //当前楼层数
m_cCurFloorNum=cUp24Idx;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -