📄 can_ad.c
字号:
#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 + -