📄 main.c
字号:
/************************************************************************
* 广州周立功单片机发展有限公司 http://www.zlgmcu.com *
************************************************************************/
/************************************************************************
* *
* SJA1000 BasicCAN模式的通讯测试 *
* *
************************************************************************/
/************************************************************************
* *
* 目的: 建立直观的BasicCAN测试平台 *
* 文件名: main.c *
* *
* 模块名: sjanetdemo *
* *
* 目标系统: 任何基于任何兼容8051指令的微处理器同SJA1000组成的CAN系统*
* *
* 应用语言: Keil C51 *
* *
************************************************************************
* 版本 :V1.0 *
* *
************************************************************************
* 广州周立功单片机发展有限公司 保留所有的版权 *
************************************************************************/
#include <P8xc5x2.H>
#include <intrins.h>
#include "time_module.C"
#include "sja_bcanFunc.C"
#include "seriele.c"
#include "keyled.c"
//数据类型定义
#define uchar unsigned char
#define ulong unsigned long
#define uint unsigned int
//设置系统数据缓冲区
static uchar data SetSystemBuf[10]; //系统设置数据缓冲区
static uchar data BandRateBuf; //设置总线波特率值缓冲区
static uchar idata EditMsSendCount; //编辑自动发送的频率
static uchar idata EditMsSendSave; //保存自动发送的频率
static uchar idata SendDataCount; //发送数据显示
static uchar idata SendFrq; //自动发送的频率
bit AutoSendFlag;
static bit MoveFlag=0; //移位计数
unsigned int AutoSendFrameID;
unsigned int TestSendData;
//键盘操作函数
extern void Write_Xdata(unsigned char value); // 将info送入外部地址xadr中
extern uchar Read_Xdata(uint Xadr); //从外部地址xadr中读取数据
extern void Key_Scan(void); //键盘扫描程序
extern uchar Key_Get(void); //取键盘值
extern void PushKey(uchar keynum); //将键值送入按键处理队列
extern uchar PopKey(void); //
void Key_handle(void); //处理键值
void FundationKey(void); //功能键
void MoveKey(void); //移位键
void SearchKey(void); //检索键
void EnterKey(void); //确认键
void IncKey(void); //增加键
void QuitKey(void); //退出键
void CanSendKey(void); //发送键
void EnterNext(void); //按确认键后进入下一小项处理
//led 送显
#define LED_SelBit() disp_pt++;if(disp_pt>4)disp_pt=0//位选
extern void Show_LED(void); //显示处理
extern void Write_DispBuf(uchar buf0,uchar buf1,uchar buf2,uchar buf3,uchar buf4);//写入显示缓冲区
extern uchar GetLedData(void); //将显示的值换算
extern void Error_disp(uchar ErrByte); //将错误字送显
void InitCPU(void); //初始化函数
// 配置sja1000
uchar Config_SJA(void); //配置sja1000
void CanRcv_Prg(void); //can总线数据接收后处理
void CanSend_Prg(void); //can发送数据
void CanErr_Prg(void); //发现错误后处理
void CanDtOver_Prg(void); //超载处理
void CanWui_Prg(void); //唤醒中断处理
void UartRcv_Prg(void); //串口接收到数据处理
void DrecDisplay(uchar *databuf); //直通显示处理函数
void TestDispPrg(void); //测试处理函数
void ClearDispPrg(uchar *databuf); //消隐处理函数
void FlightDispPrg(uchar *databuf); //闪烁处理函数
void LiftCrcDispPrg(uchar *databuf); //左循环显示处理
void RightCrcDispPrg(uchar *databuf); //右循环显示处理
void AutoSendDataToCanBus(void); //自动发送
//提取波特率的对应值
unsigned char ValueToBandRate(void);
// 外部中断0
static uchar bdata CanBusFlag=0; //can标志
sbit CanRcv_Good=CanBusFlag^0; //成功接收标志
sbit CanSend_Good=CanBusFlag^1; //成功发送标志
sbit CanErrFlag=CanBusFlag^2; //can总线错误标志
sbit CanDtOverFlag=CanBusFlag^3; //can总线超载标志
sbit CanWuiFlag=CanBusFlag^4; //can总线唤醒中断
/*-------------------------------------------------------------------------------------------
外部中断0处理程序
-------------------------------------------------------------------------------------------*/
void ex0_Val(void) interrupt 0 using 1
{
SJA_BCANAdr=REG_INTERRUPT;
CanBusFlag=*SJA_BCANAdr; //保存sja1000中断标志
}
/*-------------------------------------------------------------------------------------------
main程序
-------------------------------------------------------------------------------------------*/
void main(void)
{
uchar status; //状态字
uchar i;
Delay_50us(100) ; //50us*100=5ms
status=Config_SJA(); //配置sja1000
InitCPU(); //初始化
if(status!=0) Error_disp(status); //配置sja1000出现错误
else
{ Disp_Can(); //无措显示CAN1
Exe_Scon(0xaa,0,0);
}
Write_Xdata(0x00);
//设置并行方式
TimeOut_Start(20); //20*50us=1ms,定时周期1ms
while(1)
{
if(_testbit_(T0IR)) //ms时间到
{
i++;
LED_SelBit(); //位选
Key_Scan();
Show_LED();
if(i>=SendFrq)
{
i=0;
AutoSendDataToCanBus();
}
TimeOut_Start(20); //20*50us=1ms,定时周期1ms
}
// CanBusFlag=Read_Xdata(REG_INTERRUPT);
if(_testbit_(CanRcv_Good)) CanRcv_Prg(); //是接收中断标志
if(_testbit_(CanSend_Good)) CanSend_Prg(); //是发送中断标志
if(_testbit_(CanErrFlag)) CanErr_Prg(); //是错误中断标志
if(_testbit_(CanDtOverFlag))CanDtOver_Prg();//是超载中断标志
if(_testbit_(CanWuiFlag)) CanWui_Prg(); //是唤醒中断标志
if(_testbit_(UartRcvGood)) UartRcv_Prg(); //串口接收成功标志
Key_handle(); //键盘队列处理
}
}
/*-------------------------------------------------------------------------------------------
按键队列处理程序
-------------------------------------------------------------------------------------------*/
void Key_handle(void)
{
uchar TempData;
TempData=PopKey();
switch(TempData)
{
case Key0:
SearchKey();
break;
case Key1:
IncKey();
break;
case Key2:
break;
case Key3:
QuitKey();
break;
case Key4:
FundationKey();
break;
case Key5:
MoveKey();
break;
case Key6:
EnterKey();
break;
case Key7:
CanSendKey();
break;
default:
break;
}
}
//功能键处理
bit FunckeyFlag=0; //进入功能标志
static uchar data FunckeyCount; //功能选项计数
void FundationKey(void)
{
uchar i;
ClearDispAttr();
MoveFlag=0;
AutoSendFlag =0;
if(FunckeyFlag)
{
if(++FunckeyCount>3)FunckeyCount=0;
switch(FunckeyCount)
{
case 0:
FunckeyFlag=0;
Disp_Can(); //上电显示CAN1
DispFlag=0x00;
break;
case 1:
if((ReadSjaReg(REG_CONTROL)&0x01)==0)
{
Write_DispBuf(0,0x0b,0x01,0,0); //进入b功能
FlightLed3=1; //led3闪烁
FlightLed4=0;ClearLed4=0;
}
else
{
Write_DispBuf(0,0x0b,0x12,0x12,0x12); //进入b功能
}
break;
case 2:
Write_DispBuf(0,0x0c,0x01,0,0); //进入c功能
FlightLed3=1; //led3闪烁
FlightLed4=0;ClearLed4=0;
break;
case 3:
Write_DispBuf(0,0x05,0x0d,0,0); //进入自动发送功能
FlightLed3=1; //led3闪烁
FlightLed4=0;ClearLed4=0;
break;
default:
AutoSendFlag=0;
break;
}
}
else
{
FunckeyFlag=1;
BCAN_ENTER_RETMODEL();
i = ReadSjaReg(REG_ACR);
Write_DispBuf(0,0x0a,0x01,i>>4,i&0x0f); //a1功能
BCAN_QUIT_RETMODEL();
FlightLed3=1; //led3闪烁
FlightLed4=0;ClearLed4=0;
}
}
//检索键处理
static uchar data SearchCount; //检索计数器
void SearchKey(void) //检索键
{
uchar i;
if(FunckeyFlag)
{
switch(DispBuf[1])
{
case 0x0a:
SearchCount=DispBuf[2]; //检索a功能项
if(++SearchCount>3)SearchCount=1;
DispBuf[2]=SearchCount;
switch(SearchCount)
{
case 1:
BCAN_ENTER_RETMODEL();
i = ReadSjaReg(REG_ACR);
Write_DispBuf(0,0x0a,0x01,i>>4,i&0x0f); //a1功能
BCAN_QUIT_RETMODEL();
break;
case 2:
BCAN_ENTER_RETMODEL();
i = ReadSjaReg(REG_AMR);
Write_DispBuf(0,0x0a,0x02,i>>4,i&0x0f); //a2功能
BCAN_QUIT_RETMODEL();
break;
case 3:
i = ValueToBandRate();
Write_DispBuf(0,0x0a,0x03,i>>4,i&0x0f); //a3功能
break;
default:
SearchCount =1;
break;
}
break;
case 0x0b: //检索b功能项
if((ReadSjaReg(REG_CONTROL)&0x01)==0)
{
SearchCount=DispBuf[2];
if(++SearchCount>10)SearchCount=1;
DispBuf[2]=SearchCount;
switch(SearchCount)
{
case 1:
i = ReadSjaReg(REG_TxBuffer1);
break;
case 2:
i = ReadSjaReg(REG_TxBuffer2);
break;
case 3:
i = ReadSjaReg(REG_TxBuffer3);
break;
case 4:
i = ReadSjaReg(REG_TxBuffer4);
break;
case 5:
i = ReadSjaReg(REG_TxBuffer5);
break;
case 6:
i = ReadSjaReg(REG_TxBuffer6);
break;
case 7:
i = ReadSjaReg(REG_TxBuffer7);
break;
case 8:
i = ReadSjaReg(REG_TxBuffer8);
break;
case 9:
i = ReadSjaReg(REG_TxBuffer9);
break;
case 10:
i = ReadSjaReg(REG_TxBuffer10);
break;
default:
i=0;
break;
}
Write_DispBuf(0,0x0b,SearchCount,i>>4,i&0x0f); //b功能
}
break;
case 0x0c:
default:
break;
}
}//if结束
}
//移位键处理
void MoveKey(void) //移位键
{
if(FunckeyFlag)
{
MoveFlag=~ MoveFlag; //移位
if(MoveFlag)
{FlightLed3=0;ClearLed3=0;
FlightLed4=1;
}
else
{
FlightLed3=1;
FlightLed4=0;ClearLed4=0;
}
}
}
//增加键处理
void IncKey(void) //增加键
{
if(FunckeyFlag)
{
if(MoveFlag)
{
if(++DispBuf[4]>0x0f)DispBuf[4]=0;
}
else
if(++DispBuf[3]>0x0f)DispBuf[3]=0;
}
}
//退出键处理
void QuitKey(void) //退出键
{
if(FunckeyFlag)
{
FunckeyFlag=0;
Disp_Can(); //上电显示CAN1
AutoSendFlag=0;
DispFlag=0x00;
AutoSendFlag=0;
}
}
//确认键处理
void EnterKey(void) //确认键
{
uchar Tempdata,i;
if(FunckeyFlag)
{
Tempdata=GetLedData();
if(DispBuf[1]==0x0a)
{
switch(DispBuf[2])
{
case 0x01:
BCAN_ENTER_RETMODEL();
WriteSjaReg(REG_ACR,Tempdata); //a1功能
i= ReadSjaReg(REG_AMR);
BCAN_QUIT_RETMODEL();
Write_DispBuf(0,0x0a,0x02,i>>4,i&0x0f); //a2功能
MoveFlag=0;
FlightLed3=1;
FlightLed4=0;ClearLed4=0;
break;
case 0x02:
BCAN_ENTER_RETMODEL();
WriteSjaReg(REG_AMR,Tempdata); //a2功能
i = ValueToBandRate();
BCAN_QUIT_RETMODEL();
Write_DispBuf(0,0x0a,0x03,i>>4,i&0x0f); //a3功能
MoveFlag=0;
FlightLed3=1;
FlightLed4=0;ClearLed4=0;
break;
case 0x03:
BCAN_ENTER_RETMODEL();
BCAN_SET_BANDRATE(Tempdata);
i= ReadSjaReg(REG_ACR);
BCAN_QUIT_RETMODEL();
Write_DispBuf(0,0x0a,1,i>>4,i&0x0f);
MoveFlag=0;
FlightLed3=1;
FlightLed4=0;ClearLed4=0;
break;
default:
MoveFlag=0;
FlightLed3=1;
FlightLed4=0;ClearLed4=0;
Write_DispBuf(0,0x0a,1,i>>4,i&0x0f);
break;
}
}
if(DispBuf[1]==0x0b)
{
if((ReadSjaReg(REG_CONTROL)&0x01)==0)
{
if(0<DispBuf[2])
{
WriteSjaReg(REG_TxBuffer1+DispBuf[2]-1,Tempdata);
if(DispBuf[2]==0x0a)
{
i=ReadSjaReg(REG_TxBuffer1);
Write_DispBuf(0,0x0b,1,i>>4,i&0x0f);
MoveFlag=0;
FlightLed3=1;
FlightLed4=0;ClearLed4=0;
}
else EnterNext();
}
}
}
if(DispBuf[1]==0x0c)
{
switch(DispBuf[2])
{
case 1:
EditMsSendCount =Tempdata;
EditMsSendSave =Tempdata;
DispBuf[1]=0x05;
DispBuf[2]=0x0d;
FunckeyCount++;
ClearDispAttr();
MoveFlag=0;
break;
default:
break;
}
}
if((DispBuf[1]==0x05)&&(DispBuf[2]==0x0d)) //设定
{
SendFrq =Tempdata;
AutoSendFlag =1;
DispBuf[3]=0;
DispBuf[4]=0;
MoveFlag=0;
FlightLed3=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -