⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mycan.c

📁 DSP2407can总线的简单应用
💻 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 + -