📄 basiccan.c
字号:
P0=code_led[SetSystemBuf[0]];
P14=1;//选通第四个LED
P15=1;
P17=1;
P17=0;
delay_ms(1);
num--;
}
}
//将数据分别在四个LED上显示
void transform(uint rec_buf)
{ uint temp;
temp=rec_buf;
SetSystemBuf[0]=temp%10;//个位
SetSystemBuf[1]=temp/10%10;//十位
SetSystemBuf[2]=temp/100%10;//百位
SetSystemBuf[3]=temp/1000;//千位
}
//表示清空0000
void display_init(void)
{
SetSystemBuf[0]=0;//个位
SetSystemBuf[1]=0;//十位
SetSystemBuf[2]=0;//百位
SetSystemBuf[3]=0;//千位
display_s();
}
//表示初始化成功A-A-
void display_init_ok(void)
{
SetSystemBuf[0]=16;//个位
SetSystemBuf[1]=10;//十位
SetSystemBuf[2]=16;//百位
SetSystemBuf[3]=10;//千位
display_s();
}
//表示发送数据成功H-H-
void display_Ok(void)
{
SetSystemBuf[0]=16;//个位
SetSystemBuf[1]=17;//十位
SetSystemBuf[2]=16;//百位
SetSystemBuf[3]=17;//千位
display_s();
}
//表示数据发送失败E-E-
void display_Err(void)
{
SetSystemBuf[0]=16;//个位
SetSystemBuf[1]=14;//十位
SetSystemBuf[2]=16;//百位
SetSystemBuf[3]=14;//千位
display_s();
}
//表示数据发送溢出F-F-
void display_flow(void)
{
SetSystemBuf[0]=16;//个位
SetSystemBuf[1]=15;//十位
SetSystemBuf[2]=16;//百位
SetSystemBuf[3]=15;//千位
display_s();
}
//表示唤醒中断P-P-
void display_awake(void)
{
SetSystemBuf[0]=16;//个位
SetSystemBuf[1]=18;//十位
SetSystemBuf[2]=16;//百位
SetSystemBuf[3]=18;//千位
display_s();
}
void main()
{
delay_ms(100);
IT0=0;//外中断0为电平触发方式
IT1=1;//外中断1为脉冲触发方式,后沿负跳有效
TMOD=0x60;//计数器1以工作方式2工作,以TR1启动定时器
TH1=0xFF;
TL1=0xFF;//一次计数则中断(T1负跳变时计一次)
TR1=1;//启动计数
EX0=1;//允许外中断0中断
EA=1;//中断总允许
if(SJA_1000_Init()==0)
{
P16=0;//开启蜂鸣器,表示初始化成功
display_init_ok();//表示初始化成功A-A-
delay_ms(200);
P16=1;//关闭蜂鸣器
}
else
display_Err();//表示初始化失败E-E-
ET1=1;//允许计数器1中断
EX1=1;//允许外中断0中断
//启动ADC0809
ST=0; //用三个ST产生一个正跳变和负跳变;
OE=0; //选通ADC;
ST=1;
ST=0;
while(1)
{
display_s();
}
}
//该函数现实键盘扫描,去抖动,实现要求功能
void keyboard() interrupt 3 using 0
{
static uchar num_send=0;//定义一个静态变量,并初始化为0,用于计算S1键按下的次数,即要发送的数据
static uchar num_rate=0x0D;//用于记录S3按下的次数,从而智能的选择波特率
static bit mode_ch=1;//用于选择操作模式,mode_ch为1表示采集电压值,为0表示用户自己设置发送数据以及波特率
uchar key_code;//用于存储所按下的键值
ET1=0;//关闭计数器1中断
delay_ms(20);//去抖动,等待20ms
if(!T1)
{
key_code=P1&0x0F;//读取P1口的前4位,即P10-P13
switch(key_code)
{
case 0x07://按下S4的情况:用于选择操作模式,mode_ch为1表示采集电压值,为0表示用户自己设置发送数据以及波特率
if(mode_ch)
{
mode_ch=0;
display_init();//初始化输出0
EX1=0;//关闭外中断1
EX0=1;//开外部中断0
}
else
{
mode_ch=1;
EX1=1;//开外中断1
}
break;
case 0x0E://按下S1键的情况:设置发送数据,每按一次加1
if(mode_ch==0)
{
EX0=0;//关闭外中断0
num_send++;
transform(num_send);//将num_send转化为可以显示的十进制数,并存入SetSystemBuf中
display_s();
}
else EX1=1;//开外中断1
break;
case 0x0D://按下S2键的情况:将设置好的数据发送出去
if(mode_ch==0)
{
send_data[0]=0x01;//标识符为0000 0001 000,十进制为8
send_data[1]=0x01;
send_data[2]=num_send;
BCAN_DATA_WRITE(send_data);//将数据存放到REG_TxBuffer
//delay_ms(100);
BCAN_CMD_PRG(TR_CMD);//发送数据到CAN总线上,成功是否在中断判断
num_send=0;//复位发送的数据
EX0=1;//开外中断0
}
else EX1=1;//开外中断1
break;
case 0x0B://按下S3键的情况:设置波特率
if(mode_ch==0)
{
EX0=0;//关闭外中断0
num_rate--;
BCAN_ENTER_RETMODEL();//使CAN控制器进入复位工作模式
BCAN_SET_BANDRATE(num_rate);//设置波特率
BandRateBuf=num_rate;
transform(band_rate[num_rate]);//将band_rate中的数据转化为可以显示的十进制数,并存入SetSystemBuf中
display_s();
if(!num_rate)
num_rate=0x0D;
BCAN_QUIT_RETMODEL();//使CAN控制器退出复位工作模式
EX0=1;//开外中断0
}
else EX1=1;//开外中断1
break;
default:
break;
}
}
ET1=1;//开计数器中断
}
//该中断实现接收显示,并当出现错误是给予显示:EEEE
void SJA_int() interrupt 0 using 0
{
uchar reg_int; //存放中断寄存器的数据
uchar rcv_buf[10];//接收数据存储
EX0=0;//关闭外中断0
SJA_BCANAdr=REG_INTERRUPT;//读取中断寄存器的数据
reg_int=*SJA_BCANAdr;
if(reg_int&0x01) //接收中断处理
{
BCAN_DATA_RECEIVE(rcv_buf);
transform(rcv_buf[2]);//显示数据
display_s();
BCAN_CMD_PRG(RRB_CMD);//释放接收缓存区
}
else if(reg_int & 0x02)
{
display_Ok();//若是发送中断,则显示H-H-,表示发送成功
}
else if(reg_int & 0x04)
{
display_Err();//若是错误中断,则显示E-E-,表示有错误产生
P16=0;//开启蜂鸣器,表示错误报警
delay_ms(200);
P16=1;//关闭蜂鸣器
}
else if(reg_int & 0x08)
{
display_flow();//若是数据溢出中断,则显示F-F-,表示有数据溢出中断
}
else
{
display_awake();//表示唤醒中断,显示P-P-
}
EX0=1;//开外中断0
}
//该函数用于接收AD上来的数据,转发到CAN总线上,并转化成LED上可以正确显示的代码
void ADC0809_Rec() interrupt 2 using 0 //外部中断1
{
uint rec_buf;
uchar num=10;
EX0=0;//关闭外部中断1
EX1=0;//关闭外部中断1
OE=1;//输出转换得到的数据
P0=0xFF;//这句话很重要,没有的话基本上很难正确输出电压值
rec_buf=P0;//读取ADC传来的数据
OE=0;
rec_buf=rec_buf*1.0/255*5000;
transform(rec_buf);//将rec_buf转化为可以显示的十进制数,并存入SetSystemBuf中
while(num)
{
display_s();
num--;
}
send_data[0]=0x02;//标识符为0000 0010 000,十进制为16
send_data[1]=0x02;//发送8个字节,数据帧
send_data[2]=0;
send_data[3]=rec_buf;
BCAN_DATA_WRITE(send_data);//将数据存放到REG_TxBuffer
BCAN_CMD_PRG(TR_CMD);//发送数据到CAN总线上
//启动ADC0809
ST=0; //用三个ST产生一个正跳变和负跳变;
ST=1;
ST=0;
EX1=1;//开外部中断1
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -