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

📄 can_ad.c

📁 基于arm7的can总线模拟采集及总线通讯程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include  "config.h" 
#include  "stdio.h"
#include  "math.h"

stcTxBUF 	CTBuf;
stcRxBUF	CRBuf;
UINT8   IDCom,IDInfo,IDDAddr,CanSendFlag=0,DetCounter=0;      // Can  DetFlag=0,
UINT8   DateBuf[7],CanDateBuf1[7],CanDateBuf[7];              // SD2200
UINT8   TimeFlag,Hour,Minute,Second,Second1,THPExitFlag=0,WExitFlag=0,OneHourFlag=0,DirFlag=0;
UINT32  Count=0,CanCounter=0;
UINT32  WindDir[102],Azimuth[102];  // 合成风向用数组
float   MostWindSpeed=0,Temp=0,Press=0,DetPress=0,DetTemp=0,TrueSpeedCount=0;
UINT32  TenSpeedCount=0;
UINT32  AverageWindDir=0,DetWindDir=0,Humi=0,DetHumi=0;
char    CanAzimuth[36],QIXGData[40],DetQIXGData[40];
float   FxTotal=0,FyTotal=0;
float   FTemp,AzimuthValue=0,TemWindDir1=0;
#define  OneHourWind          17.2
#define  TSensorPower         0x00000080      // 12V
#define  FSensorPower         0x00000040      // 5V
#define  UART_BPS	115200			/* 定义通讯波特率 */
#define  PI         3.14159265
/***********************
// WDT喂狗操作函数
******************************/
void WdtFeed(void)
{
   WDFEED = 0xAA;
   WDFEED = 0x55;
}
/****************************************************************************
* 名称:UART0_Ini()
* 功能:初始化串口0。设置为8位数据位,1位停止位,无奇偶校验,波特率为115200
* 入口参数:无
* 出口参数:无
****************************************************************************/
void  UART0_Ini(void)
{  
   UINT16  Fdiv;
   U0LCR = 0x83;		            // DLAB = 1,可设置波特率
   Fdiv  = (Fpclk / 16) / UART_BPS;  // 设置波特率
   U0DLM = Fdiv / 256;							
   U0DLL = Fdiv % 256;						
   U0LCR = 0x03;
}
/****************************************************************************
* 名称:UART0_SendByte()
* 功能:向串口发送字节数据,并等待发送完毕。
* 入口参数:data		要发送的数据
* 出口参数:无
****************************************************************************/
void  UART0_SendByte(UINT8 data)
{  
   U0THR = data;				    // 发送数据
   while( (U0LSR&0x40)==0 );	    // 等待数据发送完毕
}
/****************************************************************************
* 名称:PC_DispChar()
* 功能:向PC机发送显示字符。
* 入口参数:x        显示位置的纵坐标,0-79   
*           y        显示位置的横坐标,0-24 
*           chr      显示的字符,不能为0xff
*           color    显示的状态包括前景色、背景色、闪耀位。它与dos的字符显示状态一样。 
*                    即0~3位:前景色,4~6位:背景色,7位:闪耀位。
* 出口参数:无
****************************************************************************/
void  PC_DispChar(UINT8 x, UINT8 y, UINT8 chr, UINT8 color)
{  
   UART0_SendByte(0xff);			// 发送起始字节
   UART0_SendByte(x);				// 发送字符显示坐标(x,y)
   UART0_SendByte(y);
   UART0_SendByte(chr);				// 发送显示字符
   UART0_SendByte(color);			
}
/****************************************************************************
* 名称:ISendStr()
* 功能:向PC机发送字串,以便显示。
* 入口参数:x        显示位置的纵坐标,0-79   
*           y        显示位置的横坐标,0-24 
*           color    显示的状态包括前景色、背景色、闪耀位。它与dos的字符显示状态一样。 
*                    即0~3位:前景色,4~6位:背景色,7位:闪耀位。
*           str      要发送的字符串,字串以'\0'结束
* 出口参数:无
****************************************************************************/
void  ISendStr(UINT8 x, UINT8 y, UINT8 color, char *str)
{  
   while(1)
   {  
      if(*str=='\0') break;                     // 若为'\0',则退出
      PC_DispChar(x++, y, *str++, color);       // 发送显示数据
      if(x>=80)
      {  
         x = 0;
         y++;
      }
   }
} 
//外部中断0,由时钟芯片每秒一次,下降沿产生中断
void  __irq  EINT0(void)  
{     
   EXTINT = 0x01;
   VICVectAddr = 0;
   TimeFlag = 1;
   //DetFlag = 1;
   CanCounter++;
   TenSpeedCount = Count;            // 一秒风脉冲计数值赋值给风Hz变量
   IO2CLR = IO2CLR | 0x00100000;     // 开秒中断指示灯
}
// 定时器1初始化,1.3为捕获输入
void Time1Init(void)
{
    PINSEL1 = (PINSEL1 & 0xffffffcf)|0x00000010; //选择CAP1.3为捕获输入 P0.18脚
    T1PR  = 0;
    T1CCR = 0xc00;
    T1TC  = 0;
    T1TCR = 0x01;    
}
// 定时器1,1.3捕获中断函数
void  __irq  CAP13(void)
{
   T1IR = 0x80;  
   VICVectAddr = 0;
   Count++;   
}
// 风向合成计算,100次风向和方位后取平均数  入口参数:无 出口参数:跟方位合成后方向
UINT32  CaluWindDir(void)
{
    UINT8  iLoop;
    INT32  iResult;
    FxTotal = 0, FyTotal = 0;
    
    for(iLoop = 0; iLoop < 100; iLoop++)
    {
       FTemp=WindDir[iLoop]*PI/180+Azimuth[iLoop]*PI/180;
       FxTotal+=100*cos(FTemp);
       FyTotal+=100*sin(FTemp);
    }
    if(FxTotal < 0)
    {
       iResult = 180 + atan(FyTotal/FxTotal) * 180 / PI;
       if(iResult < 0) iResult += 360;
       iResult = (UINT32)iResult;
       return iResult;
    }
    else if(FxTotal > 0)
    {
       iResult = atan(FyTotal / FxTotal) * 180 / PI;
       if(iResult < 0) iResult += 360;
       iResult = (UINT32)iResult;
       return iResult;
    }
    else if(FyTotal > 0)  return(90);
    else                  return(270);
}
// 单次合成风向合成计算  入口参数:无 出口参数:跟方位合成后方向
UINT32  CaluWindDir1(UINT8  iLoop)
{    
    INT32  iResult;
    FxTotal = 0, FyTotal = 0;
    
    FTemp=WindDir[iLoop]*PI/180+Azimuth[iLoop]*PI/180;
    FxTotal += 100 * cos(FTemp);
    FyTotal += 100 * sin(FTemp);
    
    if(FxTotal < 0)
    {
       iResult = 180 + atan(FyTotal/FxTotal) * 180 / PI;
       if(iResult < 0) iResult += 360;
       iResult = (UINT32)iResult;
       return iResult;
    }
    else if(FxTotal > 0)
    {
       iResult = atan(FyTotal / FxTotal) * 180 / PI;
       if(iResult < 0) iResult += 360;
       iResult = (UINT32)iResult;
       return iResult;
    }
    else if(FyTotal > 0)  return(90);
    else                  return(270);
}
// 从总线接收到方位数据送到气象节点 接收到数据传到TempBuf数组
UINT8	CanDirToQX(P_stcRxBUF CanReBuf,char TempBuf1[])
{
	UINT8  i=0,j=0,k=0,FrameL=0,ByteL=0,Counter=0;
	UINT8  TempBuf[8];
	while(1)
	{ 
	   TempBuf[0] = CanReBuf->CANRDA.Bits.Data2_BIT;
	   TempBuf[1] = CanReBuf->CANRDB.Bits.Data1_BIT;
	   TempBuf[2] = CanReBuf->CANRDB.Bits.Data4_BIT;
	   if(TempBuf[0] == 0)
	   {
	      FrameL = TempBuf[2];
	      ByteL  = TempBuf[1];
	      if(ByteL > 35)
	        break;
	      i = 0;
	      j = 0;
	      while(1)
	      {
	         if(ReadCANRcvCyBuf(0,CanReBuf) == 0)
	         { 
	            ParseCanRxData(0,CanReBuf,&IDCom,&IDInfo,&IDDAddr);
	            Counter = CanReBuf->CANRDA.Bits.Data2_BIT;
	            if((IDCom == 2)&&(Counter == (i+1)))
	            {	               
	               TempBuf1[i*6]   = CanReBuf->CANRDA.Bits.Data3_BIT;
	               TempBuf1[i*6+1] = CanReBuf->CANRDA.Bits.Data4_BIT;
	               TempBuf1[i*6+2] = CanReBuf->CANRDB.Bits.Data1_BIT;
	               TempBuf1[i*6+3] = CanReBuf->CANRDB.Bits.Data2_BIT;
	               TempBuf1[i*6+4] = CanReBuf->CANRDB.Bits.Data3_BIT;
	               TempBuf1[i*6+5] = CanReBuf->CANRDB.Bits.Data4_BIT;
	               i++;
	               if(i == FrameL)                 // 9.1号下午 判断应加在此处,接收can数据正常
	               {
	                  TempBuf1[ByteL - 2] = '\r';
	                  TempBuf1[ByteL - 1] = '\n';
	                  TempBuf1[ByteL] = '\0';	                  
	                  return 1;
	               }
	            }
	         }
	      }
	      break;
	   }
	   else
	     k++;
	   if(k > 100) 
	     break;  
	}
	return 0;	
}
/****************************************************************************
* 名称:main()
* 功能:向E2PROM写入10字节数据,然后读出判断是否正确写入。
* 说明:在STARTUP.S文件中使能IRQ中断(清零CPSR中的I位);
*       在CONFIG.H文件中包含I2CINT.H。 
****************************************************************************/
int  main(void)
{   
   INT32  TempArr[3];    // 温度采集数组和温度检测状态时临时值
   UINT32 HumiArr[3];
   UINT32 PressArr[3]; 
   UINT32 TemWindSpeed;  
   UINT8  i=0,j=0,k=0,m=0;  // ,l=0
   UINT8  DirStart[]={0x00,0x88,0x1f,0xfc,0x6a,0xff,0x80},DataDirStart[]={0x02,0x02},DataDirExit[]={0x03,0x03};// 打开方位
   //UINT8   SDDate[]={0x06,0x10,0x08,0x00,0x14,0x06,0x00};  //时间更新数组
   UINT32  ADC_Data; 
   char   str[30];  	
   UINT8  IDTran[]={0x00,0x88,0x10,0x04,0x6f,0xff,0x80},IDStor[]={0x00,0x88,0x10,0x04,0x6f,0xff,0x00};     // 气象节点数据发送ID
   UINT8  IDOneHour[]={0x00,0x88,0x1f,0xfc,0x6c,0xff,0x82},IDOneHourData[]={0x00,0x00};  	               // 加密指令发送	 
   UINT8  IDSta[]={0x00,0x88,0x10,0x04,0x6e,0xff,0x10},IDDet[]={0x00,0x88,0x10,0x04,0x6e,0xff,0x20};       // 状态ID数组,检测ID数组 	
   PINSEL1 = (PINSEL1 & 0xffffffcc)|0x11;             // 设置P0.16为EINT0中断,开P0.18为捕获1.3
   PINSEL2 = (PINSEL2 & 0xffffffcf)|0x30;             // 设置I/O为指示灯
   PINSEL0 = (PINSEL0 & 0xFFFFFFF0)|0x05;             // 设置P0.0、P0.1连接到UART0的TXD、RXD
   TimeFlag = 0; Count = 0;    
   IO0DIR = 0x000000c0;                               // P0.6控制12V, P0.7控制5V     
   IO2DIR = IO2DIR | 0x00300000; 
   IO0SET = IO0SET | FSensorPower;                    // 风常加电
   MostWindSpeed=0; AverageWindDir=0; CanCounter=0;   // 最大风速初始化,平均风向初始化
   //TargetResetInit(); 
   AD_Init();                           // AD初始化
   UART0_Ini();						    // 初始化UART0   
   DelayNS(10);								
   ADC_Data = ADDR;					    // 读取ADC结果,并清除DONE标志位       
   I2C_Init(200000);                    // I2C初始化
   Time_Init();                         // 时钟初始化	            
   InitCAN(0);                          // CAN初始化      
   Time1Init();                         // 定时器1初始化     
   //writedate(SDDate);                 // 更新时间 手动更新应在开中断之前更新
   WDTC = 0x32a0000;                    // 设置看门狗喂狗时间120秒
   WDMOD = 0x03;                        // 设置WDT工作模式,启动WDT
   
   EXTMODE = 0x01;					// 设置EINT0中断为边沿触发模式
   EXTPOLAR = 0x00;					// 设置EINT0中断为下降沿触发     
   VICIntSelect = 0x00000000;		// 设置所有通道为IRQ中断   
   VICVectAddr1 = (int)EINT0;	    // 设置int0中断向量地址	   
   VICVectCntl1 = 0x2e;				// I2C通道分配为 IRQ slot 1,即优先级次之
   EXTINT = 0x01;                   // 清除INT0中断标志
   VICVectAddr0 = (int)CAP13; 
   VICVectCntl0 = 0x25;             // 外部匹配通道分配到IRQ slot 0,即优先级最高
   T1IR  = 0x80;                    // 复位T1CR3捕获中断标志                    
   VICIntEnable = (1<<14) | (1<<5); // 使能int0中断  
       
   while(1) 
   {                    
      if(CanCounter >= 5000)
      CanCounter = 0; 
      IO2SET = IO2SET | 0x00100000;      // 关秒中断指示灯

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -