📄 jd1a.c
字号:
return 0;
}
/*
********************************************************************************************
**函数原型: bit BCAN_SET_OUTCLK (unsigned char Out_Control,
** unsigned char Clock_Out)
**参数说明: Out_Control:存放输出控制寄存器(OC) 的参数设置;
** Clock_Out:存放时钟分频寄存器(CDR) 的参数设置
**返回值: 0 ;设置成功
** 1 ;设置失败
* *说明: 设置SJA1000 的输出模式和时钟分频该子程序只能用于复位模式
********************************************************************************************
*/
bit BCAN_SET_OUTCLK (unsigned char Out_Control,unsigned char Clock_Out){
SJA_BCANAdr=REG_OCR ; //访问地址指向输出控制寄存器
*SJA_BCANAdr=Out_Control; //写入参数
if(*SJA_BCANAdr != Out_Control) { //校验写入值
return 1;
}
SJA_BCANAdr=REG_CDR; //访问地址指向输出控制寄存器
*SJA_BCANAdr=Clock_Out; //写入参数
return 0;
}
/*
********************************************************************************************
**函数原型: bit BCAN_DATA_WRITE(unsigned char *SendDataBuf)
**参数说明: SendDataBuf 特定帧各式的数据
**返回值: 0 表示将数据成功的送至发送缓冲区
** 1 送至发送缓冲区失败
**说明: 注本函数的返回值仅指示将数据正确写入SJA1000 发送缓存区中与否
** 不指示SJA1000 将该数据正确发送到CAN 总线上完毕与否
********************************************************************************************
*/
bit BCAN_DATA_WRITE(unsigned char *SendDataBuf){
unsigned char TempCount,status;
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr&0x08) == 0) { //判断上次发送是否完成
return(1);
}
if((*SJA_BCANAdr&0x04)==0) { //判断发送缓冲区是否锁定
return(1);
}
SJA_BCANAdr = REG_TxBuffer1; //访问地址指向发送缓冲区1
if((SendDataBuf[1]&0x10)==0) { //判断RTR 从而得出是数据帧还是远程帧
TempCount =(SendDataBuf[1]&0x0f)+2; //输入数据帧
}
else{
TempCount =2; //远程帧
}
memcpy(SJA_BCANAdr,SendDataBuf,TempCount);
return 0;
}
/**函数原型: bit BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf)
**参数说明: RcvDataBuf,存放微处理器保存数据缓冲区
**返回值: 0;接收成功
** 1;接收失败
**说明: CAN 控制器接收数据,仅限于接收数据
********************************************************************************************
*/
bit BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf) {
unsigned char TempCount;
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr&0x01)==0) { //判断报文是否有效
return 1;
}
SJA_BCANAdr = REG_RxBuffer2; //访问地址指向接收缓冲区2
if((*SJA_BCANAdr&0x10)==0) { //如果是数据帧
TempCount=(*SJA_BCANAdr&0x0f)+2; //计算报文中数据的个数
}
else{
TempCount=2;
}
SJA_BCANAdr = REG_RxBuffer1; //访问地址指向接收缓冲区1
memcpy(RcvDataBuf,SJA_BCANAdr,TempCount); //读取接收缓冲区的报文
return 0;
}
/**函数原型: bit BCAN_CMD_PRG(unsigned char cmd)
**参数说明: cmd:sja1000 运行的命令字
**返回值: 0 ; 表示命令执行成功
** 1; 表示命令执行失败
**说明: 执行sja1000 命令
********************************************************************************************
*/
bit BCAN_CMD_PRG(unsigned char cmd) {
SJA_BCANAdr=REG_COMMAND; //访问地址指向命令寄存器
*SJA_BCANAdr=cmd; //启动命令字
switch(cmd){
case TR_CMD: //发送请求命令
return 0;
break;
case AT_CMD: //夭折发送命令
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 0x20)==0) { //判断是否正在发送
return 0;
}
else{
return 1;
}
break;
case RRB_CMD: //释放接收缓冲区
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 0x01)==1) { //判断是否释放成功
return 1;
}
else{
return 0;
}
break;
case COS_CMD: //清除超载状态
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 0x02)==0) { //判断清除超载是否成功
return 0;
}
else{
return 1;
}
break;
case GTS_CMD: //进入睡眠状态命令
return 0;
break;
default:
return 1;
break;
}
}
// 串行口 ************************************************************************
// Trax string via SBUFF untill s[i]==0
void traxstring(unsigned char *s)
{
unsigned char i=0;
while(s[i])
{
SBUF=s[i];
do{
_nop_();
}
while(!TI);
TI=0;
i++;
}
}
//Interrupt function of the serial com
void ints(void) interrupt 4 using 3
{
unsigned char ich;
ES=0;
RI=0;
ich=SBUF;
if(ich=='$')
{
buff[0]=ich;
comnum=1;
ROK=0;
}
else if(ich==10) //Receive until SBUF==10
{
buff[comnum]=0;
ROK=1;
comnum=0;
}
else
{
buff[comnum]=ich;
comnum++;
ROK=0;
}
if(comnum>108) //Receive until comnum>108
{
ROK=0;
comnum=0;
}
ES=1;
}
void i2hex2(unsigned char ch,unsigned char *s)
{
unsigned char i;
i=(ch>>4) & 0x0f;
if(i<10) s[0]=i+'0';
else s[0]=i-10+'A';
i=ch & 0x0f;
if(i<10) s[1]=i+'0';
else s[1]=i-10+'A';
s[2]=0;
}
//将十六进制的字符串转换为数字
int hex2i(unsigned char *s)
{
unsigned char i,len,ch;
unsigned int ii;
len=strlen(s);
ii=0;
for(i=0;i<len;i++)
{
ii<<=4;
if(s[i]>='0' && s[i]<='9')
ii=ii+s[i]-'0';
else if(s[i]>='a' && s[i]<='f')
ii=ii+10+s[i]-'a';
else if(s[i]>='A' && s[i]<='F')
ii=ii+10+s[i]-'A';
}
return(ii);
}
void delayms(unsigned int n) //delay for n ms
{
unsigned int i,j;
for(i=0;i<n;i++){
for(j=0;j<101;j++) // @11.0592MHz 229@22.1184MHz
{
_nop_();
}
}
}
//我的子程序结束*******************************************************************************
// LCD 12864 显示屏 函数 ******************************************************************************
//显示一个字符或发送一个命令 20050426
void w_cd(unsigned char dat,unsigned char cd_type) /* type=0(instruction), type=1(data) */
{
int i;
LCDCS=1;
SID=1; SCLK=0;
for(i=0;i<5;i++)
{ SCLK=1;SCLK=0;}
SID=0;SCLK=1;SCLK=0; //RW=0;
if(!cd_type)
{ SCLK=1;SCLK=0;SCLK=1;SCLK=0;}
else
{ SID=1;SCLK=1;SCLK=0;SID=0;SCLK=1;SCLK=0;}
for(i=0;i<4;i++)
{
if(dat & 0x80) SID=1;
else SID=0; // SID=serdat[i];
dat<<=1;
SCLK=1;SCLK=0;
}
for(i=0;i<4;i++)
{ SID=0;SCLK=1;SCLK=0;}
for(i=0;i<4;i++)
{
if(dat & 0x80) SID=1;
else SID=0;
dat<<=1;
SCLK=1;SCLK=0;
}
for(i=0;i<4;i++)
{ SID=0;SCLK=1;SCLK=0;}
LCDCS=1;
if(!cd_type) delayms(5);
}
//初始化12864LCD显示屏
void LCDInit()
{
w_cd(0x38,0);
w_cd(0x01,0); //清屏
w_cd(0x06,0); //进入点设置
w_cd(0x0c,0); //显示状态开关
}
//清屏 12864 LCD
void LCDClear()
{
int i;
w_cd(0x80,0);
for(i=0;i<16;i++)
{
w_cd(0xA1,1);w_cd(0xA0,1);
}
w_cd(0x90,0);
for(i=0;i<16;i++)
{
w_cd(0xA1,1);w_cd(0xA0,1);
}
}
//显示 LCDBuff 中的数据
void LCDDisplay(unsigned char x,unsigned char y,unsigned char *LCDBuff)
{
unsigned char i;
unsigned char code pos[4]={0x80,0x90,0x88,0x98};
w_cd(pos[x]+y,0);
for(i=0;i<16-2*y;i++)
{
if(LCDBuff[i]==0) break;
w_cd(LCDBuff[i],1);
}
}
//ADC0832有关函数 修改于 2002-01-19 ********************************************************
unsigned char ADC0832(bit ch)
{
unsigned char i,result;
ADCS=1;
ADCLK=0;
ADCS=0;
ADDI=1; //起始位
ADCLK=1;
ADCLK=0;
ADDI=1; //单极性方式
ADCLK=1;
ADCLK=0;
if(ch==0) ADDI=0; //信号通道号
else ADDI=1;
ADCLK=1;
ADCLK=0;
ADCLK=1; //再来一个时钟脉冲
ADCLK=0;
for(i=0;i<8;i++) //循环读取数据
{ result<<=1;
ADCLK=1;
if(ADDO) result=result|0x01;
else result=result&0xfe;
nop=1;
ADCLK=0;
nop=1;
}
ADCS=1;
return result;
}
bit ICclock();
//24C64基本操作函数 ***************************
//I2C 器件开始操作
void ICstart()
{
ICSDA=1;
ICSCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
ICSDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
ICSCL=0;
}
//I2C 器件停止操作
void ICstop()
{
ICSDA=0;
ICSCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
ICSDA=1;
}
//应答
void ICack()
{
ICSDA=0;
ICclock();
}
//无应答
void ICnack()
{
ICSDA=1;
ICclock();
}
//从 I2C 器件读入 1 个字节
unsigned char ICinbyt()
{
unsigned char i,ch;
bit b;
ch=0;
ICSDA=1;
for(i=0;i<8;i++){
b=ICclock();
ch<<=1;
if(b) ch|=0x01;
else ch&=0xfe;
}
return ch;
}
//向 I2C 器件输出 1 个字节
void ICoutbyt(unsigned char ch)
{
unsigned char i;
for(i=0;i<8;i++){
if(ch&0x80) ICSDA=1;
else ICSDA=0;
ch<<=1;
ICclock();
}
}
//I2C 器件 ICclock
bit ICclock()
{
bit b;
_nop_();
ICSCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
b=ICSDA;
ICSCL=0;
return b;
}
unsigned char Read8574()
{
unsigned char ch;
ICstart();
ICoutbyt(0x41);
ICack();
ch=ICinbyt();
ICnack();
ICstop();
return ch;
}
//DS18B20 温度传感器 有关函数
//延时
void delay(unsigned int useconds)
{
for(;useconds>0;useconds--);
}
//复位
unsigned char ow_reset(void)
{
unsigned char presence;
DQ = 0; //pull DQ line low
delay(29); // leave it low for 480us
DQ = 1; // allow line to return high
delay(3); // wait for presence
presence = DQ; // get presence signal
delay(25); // wait for end of timeslot
return(presence); // presence signal returned
} // 0=presence, 1 = no part
//从 1-wire 总线上读取一个字节
unsigned char read_byte(void)
{
unsigned char i;
unsigned char value = 0;
for (i=8;i>0;i--)
{
value>>=1;
DQ = 0; // pull DQ low to start timeslot
DQ = 1; // then return high
delay(1); //for (i=0; i<3; i++);
if(DQ)value|=0x80;
delay(6); // wait for rest of timeslot
}
return(value);
}
//向 1-WIRE 总线上写一个字节
void write_byte(char val)
{
unsigned char i;
for (i=8; i>0; i--) // writes byte, one bit at a time
{
DQ = 0; // pull DQ low to start timeslot
DQ = val&0x01;
delay(5); // hold value for remainder of timeslot
DQ = 1;
val=val/2;
}
delay(5);
}
//读取温度
int Read_Temperature(void)
{
union{
unsigned char c[2];
int x;
} temp;
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0xBE); // Read Scratch Pad
temp.c[1]=read_byte();
temp.c[0]=read_byte();
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0x44); // Start Conversion
return temp.x; //return temp.x/2;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -