📄 mycan.c
字号:
#include "LF2407REGS.h"
#define uchar unsigned char
#define uint unsigned int
#define clear 0x01 //清屏幕,约1.6ms 清除显示屏幕,把DDRAM位址计数器调整为"00H"
#define home 0x02 //把DDRAM位址计数器调整为"00H",游标回原点,该功能不影响显示DDRAM
#define f_set 0x30 //基本指令集动作
#define dis_on 0x0f //打开显示,光标,闪烁功能
#define in_mode 0x06 //输入方式,地址增1,光标右移
#define img_on 0x36 //打开绘图功能
#define re_img 0x04
uchar str2[6];
int CAN_FLAG; // 定义标志寄存器
void inline disable() // 中断屏蔽子程序
{
asm(" setc INTM");
}
void inline enable() // 中断使能子程序
{
asm(" clrc INTM");
}
/**********系统初始化子程序*************/
void sytem_init()
{
asm(" setc INTM");
asm(" setc SXM");
asm(" clrc OVM");
asm(" clrc CNF");
*IMR=0x0010; // 开中断优先级5
*IFR=0xFFFF; // 清中断标志位
*SCSR1=0x81FE;
*WDCR=0xE8;
*MCRA=*MCRA&0xffe3;
*PADATDIR=*PADATDIR|0xFF00; // 设置方式为输出IOPA2=P_E,IOPA3=P_RW,IOPA4=P_RS
}
/***************CAN初始化子程序*****************/
void CAN_INIT()
{
*MCRB=*MCRB|0X0C0; // 设置IOPC6、IOPC7 为 CANRX,CANTX
*CANIFR=0XFFFF; // 清所有CAN中断标志
*CANLAM1H=0X7FFF; // 设置邮箱2、3的屏蔽ID寄存器
*CANLAM1L=0XFFFF; // 0则ID必须匹配
*CANMCR=0X1040; // CCR=1 改变配置请求
while(*CANGSR&0X0010==0)continue; // 当CCE=1 时即可配置 BCR2,BCR1 寄存器
*CANBCR2=0X01; // 波特率预分频寄存器
*CANBCR1=0X033; // 波特率设置为1M
*CANMCR=*CANMCR&0XEFFF; // CCR=0 改变配置结束请求
while(*CANGSR&0X0010!=0)continue; // 只有当CEE=0时,BCR2,BCR1 寄存器配置成功
*CANMDER=0X040; // 不使能邮箱,邮箱2设为接收方式
*CANMCR=0X0143; // CDR=1,数据区改变请求
*CANMSGID2H=0X2447; // 设置邮箱2的控制字及ID
// IDE=0, AME=0, AAM=0
// 标准方式为MSGID2H[12-2]
*CANMSGID2L=0XFFFF;
*CANMSGCTRL2=0X08; // 设置控制域
// 数据长度DCL = 8,RTR=0 数据帧
*CANMBX2A=0X0000; // 邮箱2信息初始化
*CANMBX2B=0X0000;
*CANMBX2C=0X0000;
*CANMBX2D=0X0000;
*CANMSGID3H=0X2447; // 设置邮箱3的标识符
*CANMSGID3L=0XFFFF;
*CANMSGCTRL3=0X08; // RTR=0,DCL=8
*CANMBX3A=0X2221; // 邮箱3信息初始化
*CANMBX3B=0X4433;
*CANMBX3C=0X6655;
*CANMBX3D=0X8877;
*CANMCR=0X04C0; // DBO=1,ABO=1,STM=1设置为自测试模式
*CANMDER=0X4C; // ME3=1,MBX3 发送, ME2=1 接收
*CANIMR=0XFFFF; //0xF7FF 中断MBX3 不使能 ,MBX2使能, 低中断优先级
*CANIFR=0XFFFF; // 清全部中断标志
}
/*******************中断程序*************/
void CANMBX_rec() // 邮箱2接收中断服务子程序
{
*CANRCR=0X040; // 复位 RMP2 和 MIF2
CAN_FLAG=0; // 置用户接收标志
}
/*
void CANMBX_send(void)
{
*CANTCR=0X20; // MBX3请求发送
while(*CANTCR&0X2000==0); // 等待发送应答
*CANTCR=0X2000; // 清 TA3 和MIF3标志位
CAN_FLAG=1;
}*/
void interrupt CAN_INT() // 中断入口程序
{
switch(*PVIR)
{
case 0x40:CANMBX_rec();break; // 邮箱2接受到相应信息则进入中断服务子程序
//case 0x41:CANMBX_send();break;
default:break;
}
}
void interrupt nothing() // 假中断程序
{
return;
}
/****************LCD显示************************/
void bit8_serial_input(uchar ix)
{
uchar i,j,nc;
*PADATDIR=*PADATDIR&0xfffb;//P_E=0; //clk=0;//IOPA2
/*ab=ix;
for(i=0;i<8;i++){
P_RW=abit7; //din=abit7;
ab<<=1;
*PADATDIR=*PADATDIR|0x0004;//P_E=1;
for(j=0;j<10;j++)nc=0;
*PADATDIR=*PADATDIR&0xfffb;// P_E=0;
} */
for(i=0x80;i>=0x01;i=i>>1)
{
if((ix&i)==0) *PADATDIR=*PADATDIR&0xfff7;//P_RW=0;
else *PADATDIR=*PADATDIR|0x0008;//P_RW=1;
*PADATDIR=*PADATDIR|0x0004;//P_E=1;
for(j=0;j<10;j++)
nc=0;
*PADATDIR=*PADATDIR&0xfffb;// P_E=0;
}
}
/*-----------MCU写指令到指令寄存器IR--------------*/
void instruct(uchar dat) //只有3个指令RS,RW不同时为0
{
uchar ch;
*PADATDIR=*PADATDIR|0x0010;//P_RS=1; //选通
ch=0xf8;
bit8_serial_input(ch); //和单片机进行同步5个1;
ch=dat&0xf0; //写入高四位
bit8_serial_input(ch);
ch=dat<<4; ///写低四位
bit8_serial_input(ch);
*PADATDIR=*PADATDIR&0xffef;//P_RS=0; //结束作业
}
/*-------------MCU写数据到数据寄存器DR--------------*/
void write_abyte(uchar dat)
{
uchar ch;
*PADATDIR=*PADATDIR|0x0010;//P_RS=1; //读数据--不选通
ch=0xfa; //RS=1 RW=0;
bit8_serial_input(ch);
ch=dat&0xf0; //RS=1 RW=0;
bit8_serial_input(ch);
ch=dat<<4;
bit8_serial_input(ch);
*PADATDIR=*PADATDIR&0xffef;//P_RS=0; //结束作业
}
/*---------写一个汉字到x,Y坐标处其中X为8列y为4行-------*/
void write_word(uint w)//两个字节;
{
uchar ch,cl;
ch=w>>8;//高字节
cl=w;//低字节
write_abyte(ch);
write_abyte(cl);
}
/**************************************/
void dis_word(uchar x,uchar y,uchar *word)
{
uchar i,j,t;
instruct(home);
if(x==1||x==3){
if(x==3){
x=1;
y=y+8;
}
t=(y-1);
instruct(t|0x80);
for(i=0;i<=x;i++)
for(j=0;j<y;j=j+16)
write_abyte(word[i+j]);
}
if(x==2||x==4){
if(x==4){
x=2;
y=y+8;
}
t=(y-1);
instruct(t|0x90);
for(i=0;i<=x;i++)
for(j=0;j<y;j=j+15)
write_abyte(word[i+j]);
}
instruct(0x0c);
}
/*---------------确定显示位置和写入显示内容-----------------*/
dis_hz(uchar x, uchar y, uchar *p_hz)
{
uchar loc;
uchar hz;
uchar xline[5]={0,1,3,2,4};
x=xline[x];
instruct(home);
loc=((x<<3)+y-9)|0x80; //LOC中是显示资料RAM
instruct(loc);//设定DDRAM位址(80H-9FH)
hz=*p_hz;
write_word(hz); //显示固定单个汉字或(双字符)单位
}
/*----------显示字母数字在x,y处就是单字节的ASCII字符-----------*/
void dis_str(uchar x, uchar y, uchar *str)
{
uchar loc,*p;
uchar xline[5]={0,1,3,2,4};
p=str;
x=xline[x];
instruct(home);
//loc=((x<<3)+y-9);//注意两者不一样;
loc=(16*(x-1)+y-1);
if(loc&0x01)//是否可以说是奇数,每个显示RAM的第二位
{loc/=2;
instruct(loc|0x80);
//ch=' '; //字符串前加空格(0x20 )
write_abyte(' ');
}else{
loc/=2;
instruct(loc|0x80);//每个显示RAM的第一位
}
while(*p){
write_abyte(*p++);
}
}
/*--------对液晶显示屏初始化--------------------*/
void initial(void)
{
uchar i,j;
*PADATDIR=*PADATDIR&0xffef;//P_RS=0; //串行不选通
*PADATDIR=*PADATDIR&0xfffb;//P_E=0; //串行方式
instruct(f_set); //0x30; //设定使用基本指令集动作,有11条指令
for(i=0;i<30;i++){}
for(i=0;i<250;i++){}
for(i=0;i<250;i++){}
instruct(f_set);
for(i=0;i<30;i++){}
for(i=0;i<250;i++){}
for(i=0;i<250;i++){}
instruct(dis_on); //0x0f; //开启屏幕 光标在第一位闪烁
for(i=0;i<30;i++){}
instruct(clear); //0x01; //清屏幕 clear
for(j=0;j<10;j++){
for(i=0;i<250;i++){}
}
instruct(in_mode); //0x06; //光标右移、地址增1 方式
for(i=0;i<30;i++){}
instruct(home);
}
/*-------------对数进行处理送要显示的数-----------------------*/
void itoa(int x,uchar *str2)
{
unsigned int n;
unsigned char chn,*p,*p2,str1[5];
unsigned char i,j;
p2=str2;
if(x<0){
*p2++='-';
x=-x;
}
n=x;
*p=*p&str1[5];
j=0;
while(n!=0){
chn=n%10;
n=n/10;
*p++=chn+'0';//'0'; //为什么加'0'???不加显示不正确
j++;
}
if(j!=0){
p--;
for(i=0;i<j;i++)*p2++=*p--;
}
else *p2++='0';
*p2=0;
return;
}
/*********************************/
void delay(uchar aa)
{
uint i,j;
for(i=0;i<aa;i++)
for(j=0;j<100;j++);
}
/***************main*******************/
main()
{
uint i=0;
uchar aa[]={"我"};
uchar ss[]={"好"};
sytem_init(); // 系统初始化程序
CAN_FLAG=0X00; // 清CAN用户标志,CAN_FLAG=01表示接收到数据
CAN_INIT(); // CAN初始化程序
enable(); // 中断使能
initial();
dis_word(2,2,aa);
while(1)
{
*CANTCR=0X20; // MBX3请求发送
while(*CANTCR&0X2000==0); // 等待发送应答
*CANTCR=0X2000; // 清 TA3 和MIF3标志位
CAN_FLAG=1;
while(CAN_FLAG==0); // 等待接收数据
//delay(1);
itoa(i,str2);
dis_word(1,1,str2);
i++;
*CANMDER=0X0000; // 邮箱不使能
*CANMCR=0X0140; // CDR=1,数据改变请求
*CANMBX3A=*CANMBX2A+1; // 邮箱2中数据加1用来更新邮箱3中的数据
*CANMBX3B=*CANMBX2B+1;
*CANMBX3C=*CANMBX2C+1;
*CANMBX3D=*CANMBX2D+1;
*CANMCR=0X04C0; // DBO=1,CDR=0,ABO=1,STM=1
*CANMDER=0X04C; // ME2=ME3=1,MBX2接收, MBX3发送
CAN_FLAG=1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -