发新帖我要提问
123
返回列表
打印
[应用相关]

使用STM32与labview设计的太阳能跟踪系统_原创作品

[复制链接]
楼主: wangjiahao88
手机看帖
扫描二维码
随时随地手机跟帖
41
wangjiahao88|  楼主 | 2018-11-4 12:55 | 只看该作者 回帖奖励 |倒序浏览
任务

#include "main.h"

void Get_ChipID(void)
{
    ChipUniqueID[0] = *(__IO u32 *)(0X1FFFF7F0); // 高字节
    ChipUniqueID[1] = *(__IO u32 *)(0X1FFFF7EC); //
    ChipUniqueID[2] = *(__IO u32 *)(0X1FFFF7E8); // 低字节
}

//MB_系统参数监控
void MB_Sys_monitor(void)
{
    //版本号
    usSRegHoldBuf[0]=SYS_SN;

    usSRegHoldBuf[1]=rtc.year;
    usSRegHoldBuf[2]=rtc.month;
    usSRegHoldBuf[3]=rtc.day;
    usSRegHoldBuf[4]=rtc.hour;
    usSRegHoldBuf[5]=rtc.minute;
    usSRegHoldBuf[6]=rtc.second;

    usSRegHoldBuf[10]=Key_Scan(LED_RUN_GPIO_PORT,LED_RUN_GPIO_PIN);

    //光电传感器1..8
    usSRegHoldBuf[11]=ADC_filter[0];
    usSRegHoldBuf[12]=ADC_filter[1];
    usSRegHoldBuf[13]=ADC_filter[2];
    usSRegHoldBuf[14]=ADC_filter[3];
    usSRegHoldBuf[15]=ADC_filter[4];
    usSRegHoldBuf[16]=ADC_filter[5];
    usSRegHoldBuf[17]=ADC_filter[6];
    usSRegHoldBuf[18]=ADC_filter[7];

    //风力传感器
    usSRegHoldBuf[19]=ADC_ConvertedValue[8];
    //拉力传感器
    usSRegHoldBuf[20]=ADC_ConvertedValue[9];
    //方位电机电流
    usSRegHoldBuf[21]=ADC_ConvertedValue[10];
    //俯仰电机电流
    usSRegHoldBuf[22]=ADC_ConvertedValue[11];

    //手自动选择
    usSRegHoldBuf[23]=SW_AM;
    //方位东
    usSRegHoldBuf[24]=Button_Dong;
    //方位西
    usSRegHoldBuf[25]=Button_Xi;
    //俯仰上
    usSRegHoldBuf[26]=Button_Shang;
    //俯仰下
    usSRegHoldBuf[27]=Button_Xia;
    //方位东
    usSRegHoldBuf[28]=XW_Dong;
    //方位西
    usSRegHoldBuf[29]=XW_Xi;
    //俯仰上
    usSRegHoldBuf[30]=XW_Shang;
    //俯仰下
    usSRegHoldBuf[31]=XW_Xia;
    //方位电机编码器
    usSRegHoldBuf[40]=0;
    //俯仰电机编码器
    usSRegHoldBuf[41]=0;
    //方位电机
    usSRegHoldBuf[42]=FW_M_Stateus;
    //俯仰电机
    usSRegHoldBuf[43]=FY_M_Stateus;

    //RF射频卡
    usSRegHoldBuf[50]=RF_STEP;
    usSRegHoldBuf[51]=RF_SN[0];
    usSRegHoldBuf[52]=RF_SN[1];
    usSRegHoldBuf[53]=RF_SN[2];
    usSRegHoldBuf[54]=RF_SN[3];
    usSRegHoldBuf[55]=RF_SEMI;

    usSRegHoldBuf[60]=SYS_STEP_Auto;
    usSRegHoldBuf[61]=SYS_STEP_Man;

    usSRegHoldBuf[62]=YQ_Stateus;
    usSRegHoldBuf[63]=Track_Calc_cnt_tmp;

    usSRegHoldBuf[64]=abs(FY_Sensor_chazhi);
    usSRegHoldBuf[65]=abs(FW_Sensor_chazhi);

}

//MB_LED设置
void MB_Led_set(void)
{
    LED1(!usSRegHoldBuf[101]);
    LED2(!usSRegHoldBuf[102]);
    LED3(!usSRegHoldBuf[103]);
    LED4(!usSRegHoldBuf[104]);
    LED5(!usSRegHoldBuf[105]);
    LED6(!usSRegHoldBuf[106]);
    LED7(!usSRegHoldBuf[107]);
    LED8(!usSRegHoldBuf[108]);
}

//MB_设置时钟
void MB_Rtc_set(void)
{
    if(usSRegHoldBuf[100]==1)
    {
        rtc.year=usSRegHoldBuf[101];
        rtc.month=usSRegHoldBuf[102];
        rtc.day=usSRegHoldBuf[103];
        rtc.hour=usSRegHoldBuf[104];
        rtc.minute=usSRegHoldBuf[105];
        rtc.second=usSRegHoldBuf[106];
        P8563_Set_Time();

        usSRegHoldBuf[100]=0;
        usSRegHoldBuf[101]=0;
        usSRegHoldBuf[102]=0;
        usSRegHoldBuf[103]=0;
        usSRegHoldBuf[104]=0;
        usSRegHoldBuf[105]=0;
        usSRegHoldBuf[106]=0;
    }
}

//实时时钟的读取
void Rtc_read(void)
{
    if(T_RTC_FLAG) /* 1000 * 1 ms = 1s 时间到 */
    {
        P8563_Read_Time();
        //等于2..,21电池板复位
        if(Calc_time_stateus()==2)SYS_STEP_Auto=Auto_track_reset_star;
    }
}

//LED运行的状态
void LED_RUN_STATEUS(void)
{
    LED_RUN(T_RTC_FLAG);
}

//MB_电机控制
void MB_FW_Motor_ctrl(void)
{
    //方位电机控制
    switch(usSRegHoldBuf[101])
    {
    case 0:
        FW_STOP();
        break;
    case 1:
        if(usSRegHoldBuf[102]==0)FW_Dong();
        if(usSRegHoldBuf[102]==1)FW_Xi();
        break;
    }
}

//俯仰电机的MB控制
void MB_FY_Motor_ctrl(void)
{
    //俯仰电机控制
    switch(usSRegHoldBuf[101])
    {
    case 0:
        FY_STOP();
        break;
    case 1:
        if(usSRegHoldBuf[102]==0)FY_Shang();
        if(usSRegHoldBuf[102]==1)FY_Xia();
        break;
    }
}

//手动控制系统中
void Man_Motor_ctrl(void)
{
    switch(SW_AM)
    {
    case 0:
        Man_track();
        break;
    }
}

//自动控制系统中
void Auto_Motor_ctrl(void)
{
    switch(SW_AM)
    {
    case 1:
        Auto_track();//自动跟踪任务
        break;
    }
}

//MB_自动_手动控制
void MB_Auto_Man_Ctrl(void)
{
    switch(usSRegHoldBuf[100])
    {
    case 0:
        Man_Motor_ctrl();                //手动控制
        Auto_Motor_ctrl();        //自动控制
        break;

    case 1://表示链接上了软件,可以进性软件交互
        MB_Rtc_set();//MB_设置时钟
        break;

    case 2://设定LED状态
        MB_Led_set();//MB_LED设置
        break;

    case 3://方位电机控制
        if(SW_AM==0)
        {
            MB_FW_Motor_ctrl();
        }
        break;

    case 4://俯仰电机控制
        if(SW_AM==0)
        {
            MB_FY_Motor_ctrl();
        }
        break;

    case 5://设置序列号
        Write_RF_SEMI();//设置序列号
        break;

    case 6://软件复位
        __disable_fault_irq();
        NVIC_SystemReset();
        break;
    }
}





使用特权

评论回复
42
wangjiahao88|  楼主 | 2018-11-4 12:55 | 只看该作者
电机任务

#include "main.h"

void MOTOR_GPIO_Config(void)
{
    /*定义一个GPIO_InitTypeDef类型的结构体*/
    GPIO_InitTypeDef GPIO_InitStructure;

    /*开启LED相关的GPIO外设时钟*/
    RCC_APB2PeriphClockCmd(
        FW_EN_GPIO_CLK|
        FY_EN_GPIO_CLK,ENABLE);

    GPIO_InitStructure.GPIO_Pin = FW_EN_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(FW_EN_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = FY_EN_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(FY_EN_GPIO_PORT, &GPIO_InitStructure);

    GPIO_ResetBits(FW_EN_GPIO_PORT, FW_EN_GPIO_PIN);
    GPIO_ResetBits(FY_EN_GPIO_PORT, FY_EN_GPIO_PIN);
}

static void GENERAL_TIM_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);        //使能定时器4时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
    GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); //Timer4部分重映射  TIM4_CH2->PD13

    // 输出比较通道1 GPIO 初始化
    GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM_CH1_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure);
    // 输出比较通道2 GPIO 初始化
    GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM_CH2_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GENERAL_TIM_CH2_PORT, &GPIO_InitStructure);
    // 输出比较通道3 GPIO 初始化
    GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM_CH3_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GENERAL_TIM_CH3_PORT, &GPIO_InitStructure);
    // 输出比较通道4 GPIO 初始化
    GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM_CH4_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GENERAL_TIM_CH4_PORT, &GPIO_InitStructure);
}

static void GENERAL_TIM_Mode_Config(void)
{


    // 开启定时器时钟,即内部时钟CK_INT=72M
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);        //使能定时器3时钟

    /*--------------------时基结构体初始化-------------------------*/
    // 配置周期,这里配置为100K

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period;
    // 驱动CNT计数器的时钟 = Fck_int/(psc+1)
    TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler;
    // 时钟分频因子 ,配置死区时间时需要用到
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    // 计数器计数模式,设置为向上计数
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    // 重复计数器的值,没用到不用管
    TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
    // 初始化定时器
    TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);


    TIM_OCInitTypeDef  TIM_OCInitStructure;
    // 配置为PWM模式1
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    // 输出使能
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    // 输出通道电平极性配置
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    /*--------------------输出比较结构体初始化-------------------*/
    // 占空比配置
    uint16_t CCR1_Val = 1000;
    uint16_t CCR2_Val = 1000;
    uint16_t CCR3_Val = 1000;
    uint16_t CCR4_Val = 1000;


    // 输出比较通道 1
    TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
    TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);

    // 输出比较通道 2
    TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
    TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);

    // 输出比较通道 3
    TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
    TIM_OC3Init(GENERAL_TIM, &TIM_OCInitStructure);
    TIM_OC3PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);

    // 输出比较通道 4
    TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
    TIM_OC4Init(GENERAL_TIM, &TIM_OCInitStructure);
    TIM_OC4PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);

    // 使能计数器
    TIM_Cmd(GENERAL_TIM, ENABLE);

    TIM_SetCompare1(TIM4,1000);
    TIM_SetCompare2(TIM4,1000);
    TIM_SetCompare3(TIM4,1000);
    TIM_SetCompare4(TIM4,1000);
}

void MOTOR_TIM_Init(void)
{
    GENERAL_TIM_GPIO_Config();
    GENERAL_TIM_Mode_Config();
}

static void FW_CW(TIM_TypeDef* TIMx, uint16_t Compare1)
{
    /* Check the parameters */
    assert_param(IS_TIM_LIST8_PERIPH(TIMx));
    /* Set the Capture Compare1 Register value */
    TIMx->CCR2 = Compare1;
}
static void FW_CCW(TIM_TypeDef* TIMx, uint16_t Compare1)
{
    /* Check the parameters */
    assert_param(IS_TIM_LIST8_PERIPH(TIMx));
    /* Set the Capture Compare1 Register value */
    TIMx->CCR4 = Compare1;
}

static void FY_CW(TIM_TypeDef* TIMx, uint16_t Compare1)
{
    /* Check the parameters */
    assert_param(IS_TIM_LIST8_PERIPH(TIMx));
    /* Set the Capture Compare1 Register value */
    TIMx->CCR1 = Compare1;
}
static void FY_CCW(TIM_TypeDef* TIMx, uint16_t Compare1)
{
    /* Check the parameters */
    assert_param(IS_TIM_LIST8_PERIPH(TIMx));
    /* Set the Capture Compare1 Register value */
    TIMx->CCR3 = Compare1;
}

//正转并且设置速率,MP是设置的速率
void FW_STAT_CW(unsigned char MP)
{
    if(MP<1)MP=4;
    if(MP>4)MP=4;
    FW_CW(TIM4,200*MP);
    FW_CCW(TIM4,1000);
    FW_MOTOR_ON;
    LED8(ON);
    LED7(OFF);
    FW_M_Stateus=1;
}
//倒转并且设置速率,MP是设置的速率
void FW_STAT_CCW(unsigned char MP)
{
    if(MP<1)MP=4;
    if(MP>4)MP=4;
    FW_CW(TIM4,1000);
    FW_CCW(TIM4,200*MP);
    FW_MOTOR_ON;
    LED8(OFF);
    LED7(ON);
    FW_M_Stateus=2;
}
//停止状态
void FW_STOP(void)
{
    FW_CW(TIM4,1000);
    FW_CCW(TIM4,1000);
    FW_MOTOR_OFF;
    LED7(OFF);
    LED8(OFF);
    FW_M_Stateus=0;
}

//正转并且设置速率
void FY_STAT_CW(unsigned char MP)
{
    if(MP<1)MP=4;
    if(MP>4)MP=4;

    FY_CW(TIM4,200*MP);
    FY_CCW(TIM4,1000);
    FY_MOTOR_ON;

    LED6(ON);
    LED5(OFF);

    FY_M_Stateus=1;

}
//倒转并且设置速率
void FY_STAT_CCW(unsigned char MP)
{
    if(MP<1)MP=4;
    if(MP>4)MP=4;
    FY_CW(TIM4,1000);
    FY_CCW(TIM4,200*MP);
    FY_MOTOR_ON;

    LED6(OFF);
    LED5(ON);

    FY_M_Stateus=2;

}
//停止状态
void FY_STOP(void)
{
    FY_CW(TIM4,1000);
    FY_CCW(TIM4,1000);
    FY_MOTOR_OFF;

    LED6(OFF);
    LED5(OFF);

    FY_M_Stateus=0;

}

void FW_Dong(void)
{
    if(XW_Dong==0)FW_STAT_CW(1);
    if(XW_Dong==1)FW_STOP();
}

void FW_Xi(void)
{
    if(XW_Xi==0)FW_STAT_CCW(1);
    if(XW_Xi==1)FW_STOP();
}

void FY_Shang(void)
{
    if(XW_Shang==0)FY_STAT_CW(1);
    if(XW_Shang==1)FY_STOP();
}

void FY_Xia(void)
{
    if(XW_Xia==0)FY_STAT_CCW(1);
    if(XW_Xia==1)FY_STOP();
}
/*********************************************END OF FILE**********************/

使用特权

评论回复
43
wangjiahao88|  楼主 | 2018-11-4 12:55 | 只看该作者
RC 522

#include "main.h"
#include "string.h"

void RC522_Delay(unsigned short int Delay_Time)
{
    unsigned short int i, j;
    for (i = 200; i > 0; i--)
    {
        for (j = Delay_Time; j > 0; j--);
    }
}

void RC522_IO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RC522_SCK_GPIO_CLK | RC522_MISO_GPIO_CLK | RC522_MOSI_GPIO_CLK
                           | RC522_NSEL_GPIO_CLK | RC522_RESET_GPIO_CLK
                           | RC522_IRQ_GPIO_CLK, ENABLE);

    /* Configure PD0 and PD2 in output pushpull mode */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Pin = (RC522_SCK_PIN);
    GPIO_Init(RC522_SCK_GPIO_PORT, &GPIO_InitStructure);      //sck

    GPIO_InitStructure.GPIO_Pin = (RC522_MOSI_PIN);           //mosi
    GPIO_Init(RC522_MOSI_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = (RC522_NSEL_PIN);          //nsel
    GPIO_Init(RC522_NSEL_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = (RC522_RESET_PIN);         //reset
    GPIO_Init(RC522_RESET_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_InitStructure.GPIO_Pin = RC522_MISO_PIN;
    GPIO_Init(RC522_MISO_GPIO_PORT, &GPIO_InitStructure);        //   配置为输入

    GPIO_InitStructure.GPIO_Pin = RC522_IRQ_PIN;
    GPIO_Init(RC522_IRQ_GPIO_PORT, &GPIO_InitStructure);        //    配置为输入

}

void RC522_IO_Test(void)
{
    RC522_SCK_RESET();
    RC522_MOSI_RESET();
    RC522_NSEL_RESET();
    RC522_RESET_RESET();
}

/////////////////////////////////////////////////////////////////////
//功    能:寻卡
//参数说明: req_code[IN]:寻卡方式
//                0x52 = 寻感应区内所有符合14443A标准的卡
//                0x26 = 寻未进入休眠状态的卡
//          pTagType[OUT]:卡片类型代码
//                0x4400 = Mifare_UltraLight
//                0x0400 = Mifare_One(S50)
//                0x0200 = Mifare_One(S70)
//                0x0800 = Mifare_Pro(X)
//                0x4403 = Mifare_DESFire
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdRequest(unsigned char req_code, unsigned char *pTagType)
{
    unsigned char status;
    unsigned short int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ClearBitMask(Status2Reg, 0x08);
    WriteRawRC(BitFramingReg, 0x07);
    SetBitMask(TxControlReg, 0x03);

    ucComMF522Buf[0] = req_code;

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 1, ucComMF522Buf,
                         &unLen);
    if ((status == MI_OK) && (unLen == 0x10))
    {
        *pTagType = ucComMF522Buf[0];
        *(pTagType + 1) = ucComMF522Buf[1];
    }
    else
    {
        status = MI_ERR;
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdAnticoll(unsigned char *pSnr)
{
    unsigned char status;
    unsigned char i, snr_check = 0;
    unsigned short int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ClearBitMask(Status2Reg, 0x08);
    WriteRawRC(BitFramingReg, 0x00);
    ClearBitMask(CollReg, 0x80);

    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x20;

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 2, ucComMF522Buf, &unLen);

    if (status == MI_OK)
    {
        for (i = 0; i < 4; i++)
        {
            Delay(200);//加入了一个延时
            *(pSnr + i) = ucComMF522Buf[i];
            snr_check ^= ucComMF522Buf[i];
        }
        if (snr_check != ucComMF522Buf[i])
        {
            status = MI_ERR;
        }
    }

    SetBitMask(CollReg, 0x80);
    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:选定卡片
//参数说明: pSnr[IN]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdSelect(unsigned char *pSnr)
{
    unsigned char status;
    unsigned char i;
    unsigned short int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x70;
    ucComMF522Buf[6] = 0;
    for (i = 0; i < 4; i++)
    {
        Delay(200);

        ucComMF522Buf[i + 2] = *(pSnr + i);
        ucComMF522Buf[6] ^= *(pSnr + i);
    }
    CalulateCRC(ucComMF522Buf, 7, &ucComMF522Buf[7]);

    ClearBitMask(Status2Reg, 0x08);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 9, ucComMF522Buf,
                         &unLen);

    if ((status == MI_OK) && (unLen == 0x18))
    {
        status = MI_OK;
    }
    else
    {
        status = MI_ERR;
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:验证卡片密码
//参数说明: auth_mode[IN]: 密码验证模式
//                 0x60 = 验证A密钥
//                 0x61 = 验证B密钥
//          addr[IN]:块地址
//          pKey[IN]:密码
//          pSnr[IN]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdAuthState(unsigned char auth_mode, unsigned char addr, unsigned char *pKey, unsigned char *pSnr)
{
    unsigned char status;
    unsigned short int unLen;
    unsigned char i, ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = auth_mode;
    ucComMF522Buf[1] = addr;
    for (i = 0; i < 6; i++)
    {
        Delay(200);
        ucComMF522Buf[i + 2] = *(pKey + i);
    }
    for (i = 0; i < 6; i++)
    {
        Delay(200);

        ucComMF522Buf[i + 8] = *(pSnr + i);
    }

    status = PcdComMF522(PCD_AUTHENT, ucComMF522Buf, 12, ucComMF522Buf, &unLen);
    if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
    {
        status = MI_ERR;
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:读取M1卡一块数据
//参数说明: addr[IN]:块地址
//          p [OUT]:读出的数据,16字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdRead(unsigned char addr, unsigned char *pData)
{
    unsigned char status;
    unsigned short int unLen;
    unsigned char i, ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_READ;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf,
                         &unLen);
    if ((status == MI_OK) && (unLen == 0x90))
    {
        for (i = 0; i < 16; i++)
        {
            Delay(200);

            *(pData + i) = ucComMF522Buf[i];
        }
    }
    else
    {
        status = MI_ERR;
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:写数据到M1卡一块
//参数说明: addr[IN]:块地址
//          p [IN]:写入的数据,16字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdWrite(unsigned char addr, unsigned char *pData)
{
    unsigned char status;
    unsigned short int unLen;
    unsigned char i, ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_WRITE;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf,
                         &unLen);

    if ((status != MI_OK) || (unLen != 4)
            || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = MI_ERR;
    }

    if (status == MI_OK)
    {
        for (i = 0; i < 16; i++)
        {
            Delay(200);

            ucComMF522Buf[i] = *(pData + i);
        }
        CalulateCRC(ucComMF522Buf, 16, &ucComMF522Buf[16]);

        status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 18, ucComMF522Buf,
                             &unLen);
        if ((status != MI_OK) || (unLen != 4)
                || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
        {
            status = MI_ERR;
        }
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:扣款和充值
//参数说明: dd_mode[IN]:命令字
//               0xC0 = 扣款
//               0xC1 = 充值
//          addr[IN]:钱包地址
//          pValue[IN]:4字节增(减)值,低位在前
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdValue(unsigned char dd_mode, unsigned char addr, unsigned char *pValue)
{
    unsigned char status;
    unsigned short int unLen;
    unsigned char i, ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = dd_mode;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf,
                         &unLen);

    if ((status != MI_OK) || (unLen != 4)
            || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = MI_ERR;
    }

    if (status == MI_OK)
    {
        for (i = 0; i < 16; i++)
        {
            ucComMF522Buf[i] = *(pValue + i);
        }
        CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);
        unLen = 0;
        status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf,
                             &unLen);
        if (status != MI_ERR)
        {
            status = MI_OK;
        }
    }

    if (status == MI_OK)
    {
        ucComMF522Buf[0] = PICC_TRANSFER;
        ucComMF522Buf[1] = addr;
        CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

        status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf,
                             &unLen);

        if ((status != MI_OK) || (unLen != 4)
                || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
        {
            status = MI_ERR;
        }
    }
    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:备份钱包
//参数说明: sourceaddr[IN]:源地址
//          goaladdr[IN]:目标地址
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr)
{
    unsigned char status;
    unsigned short int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_RESTORE;
    ucComMF522Buf[1] = sourceaddr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf,
                         &unLen);

    if ((status != MI_OK) || (unLen != 4)
            || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = MI_ERR;
    }

    if (status == MI_OK)
    {
        ucComMF522Buf[0] = 0;
        ucComMF522Buf[1] = 0;
        ucComMF522Buf[2] = 0;
        ucComMF522Buf[3] = 0;
        CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);

        status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf,
                             &unLen);
        if (status != MI_ERR)
        {
            status = MI_OK;
        }
    }

    if (status != MI_OK)
    {
        return MI_ERR;
    }

    ucComMF522Buf[0] = PICC_TRANSFER;
    ucComMF522Buf[1] = goaladdr;

    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf,
                         &unLen);

    if ((status != MI_OK) || (unLen != 4)
            || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = MI_ERR;
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:命令卡片进入休眠状态
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdHalt(void)
{
    //unsigned char status;
    unsigned short int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_HALT;
    ucComMF522Buf[1] = 0;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    //status =
    PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

    return MI_OK;
}

/////////////////////////////////////////////////////////////////////
//用MF522计算CRC16函数
/////////////////////////////////////////////////////////////////////
void CalulateCRC(unsigned char *pIndata, unsigned char len,
                 unsigned char *pOutData)
{
    unsigned char i, n;
    ClearBitMask(DivIrqReg, 0x04);
    WriteRawRC(CommandReg, PCD_IDLE);
    SetBitMask(FIFOLevelReg, 0x80);
    for (i = 0; i < len; i++)
    {
        WriteRawRC(FIFODataReg, *(pIndata + i));
    }
    WriteRawRC(CommandReg, PCD_CALCCRC);
    i = 0xFF;
    do
    {
        n = ReadRawRC(DivIrqReg);
        i--;
    } while ((i != 0) && !(n & 0x04));
    pOutData[0] = ReadRawRC(CRCResultRegL);
    pOutData[1] = ReadRawRC(CRCResultRegM);
}

/////////////////////////////////////////////////////////////////////
//功    能:复位RC522
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
unsigned char PcdReset(void)
{
    RC522_RESET_SET();     //RST522_1;
    RC522_Delay(10);  //_NOP();
    RC522_RESET_RESET();   //RST522_0;
    RC522_Delay(60000);  //_NOP();_NOP();
    RC522_RESET_SET();     //RST522_1;RST522_1;
    RC522_Delay(500);  //_NOP();_NOP();
    WriteRawRC(CommandReg, PCD_RESETPHASE);
    RC522_Delay(2000);  //_NOP();_NOP();

    WriteRawRC(ModeReg, 0x3D);            //?Mifare???,CRC???0x6363
    WriteRawRC(TReloadRegL, 30);         //?30?????
    WriteRawRC(TReloadRegH, 0);
    WriteRawRC(TModeReg, 0x8D);
    WriteRawRC(TPrescalerReg, 0x3E);
    WriteRawRC(TxAutoReg, 0x40);

    ClearBitMask(TestPinEnReg, 0x80);         //off MX and DTRQ out
    WriteRawRC(TxAutoReg, 0x40);

    return MI_OK;
}

/////////////////////////////////////////////////////////////////////
//功    能:读RC632寄存器
//参数说明:Address[IN]:寄存器地址
//返    回:读出的值
/////////////////////////////////////////////////////////////////////
unsigned char ReadRawRC(unsigned char Address)
{
    unsigned char i, ucAddr;
    unsigned char ucResult = 0;

    RC522_SCK_RESET();    //SCK522_0;
    RC522_NSEL_RESET();   //NSS522_0;
    ucAddr = ((Address << 1) & 0x7E) | 0x80;

    for (i = 8; i > 0; i--)
    {

        Delay(200);

        if ((ucAddr & 0x80) == 0x80)
        {
            RC522_MOSI_SET();   //SI522_1;
        }
        else
        {
            RC522_MOSI_RESET();  //SI522_0;
        }
        RC522_SCK_SET();   //SCK522_1;
        ucAddr <<= 1;
        RC522_SCK_RESET();  //SCK522_0;
    }

    for (i = 8; i > 0; i--)
    {
        Delay(200);

        RC522_SCK_SET();     //SCK522_1;
        ucResult <<= 1;
        ucResult |= RC522_MISO_STATUS;  //SO522;
        RC522_SCK_RESET();   //SCK522_0;
    }

    RC522_NSEL_SET();    //NSS522_1;
    RC522_SCK_SET();     //SCK522_1;
    return ucResult;
}

/////////////////////////////////////////////////////////////////////
//功    能:写RC632寄存器
//参数说明:Address[IN]:寄存器地址
//          value[IN]:写入的值
/////////////////////////////////////////////////////////////////////
void WriteRawRC(unsigned char Address, unsigned char value)
{
    unsigned char i, ucAddr;

    RC522_SCK_RESET();     //SCK522_0;
    RC522_NSEL_RESET();   //NSS522_0;
    ucAddr = ((Address << 1) & 0x7E);

    for (i = 8; i > 0; i--)
    {
        Delay(200);

        if ((ucAddr & 0x80) == 0x80)
        {
            RC522_MOSI_SET();    //SI522_1;
        }
        else
        {
            RC522_MOSI_RESET();  //SI522_0;
        }
        RC522_SCK_SET();       //SCK522_1;
        ucAddr <<= 1;
        RC522_SCK_RESET();     //SCK522_0;
    }

    for (i = 8; i > 0; i--)
    {
        Delay(200);
        if ((value & 0x80) == 0x80)
        {
            RC522_MOSI_SET();  //SI522_1;
        }
        else
        {
            RC522_MOSI_RESET();  //SI522_0;
        }
        RC522_SCK_SET();     //SCK522_1;
        value <<= 1;
        RC522_SCK_RESET();   //SCK522_0;
    }
    RC522_NSEL_SET();    //NSS522_1;
    RC522_SCK_SET();     //SCK522_1;
}

/////////////////////////////////////////////////////////////////////
//功    能:置RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:置位值
/////////////////////////////////////////////////////////////////////
void SetBitMask(unsigned char reg, unsigned char mask)
{
    unsigned char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp | mask);  // set bit mask
}

/////////////////////////////////////////////////////////////////////
//功    能:清RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:清位值
/////////////////////////////////////////////////////////////////////
void ClearBitMask(unsigned char reg, unsigned char mask)
{
    unsigned char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp & ~mask);  // clear bit mask
}

/////////////////////////////////////////////////////////////////////
//功    能:通过RC522和ISO14443卡通讯
//参数说明:Command[IN]:RC522命令字
//          pIn [IN]:通过RC522发送到卡片的数据
//          InLenByte[IN]:发送数据的字节长度
//          pOut [OUT]:接收到的卡片返回数据
//          *pOutLenBit[OUT]:返回数据的位长度
/////////////////////////////////////////////////////////////////////
unsigned char PcdComMF522
(
    unsigned char Command,
    unsigned char *pInData,
    unsigned char InLenByte,
    unsigned char *pOutData,
    unsigned short int *pOutLenBit
)
{
    unsigned char status = MI_ERR;
    unsigned char irqEn = 0x00;
    unsigned char waitFor = 0x00;
    unsigned char lastBits;
    unsigned char n;
    unsigned short int i;
    switch (Command)
    {
    case PCD_AUTHENT:
        irqEn = 0x12;
        waitFor = 0x10;
        break;
    case PCD_TRANSCEIVE:
        irqEn = 0x77;
        waitFor = 0x30;
        break;
    default:
        break;
    }

    WriteRawRC(ComIEnReg, irqEn | 0x80);
    ClearBitMask(ComIrqReg, 0x80);
    WriteRawRC(CommandReg, PCD_IDLE);
    SetBitMask(FIFOLevelReg, 0x80);

    for (i = 0; i < InLenByte; i++)
    {
        WriteRawRC(FIFODataReg, pInData[i]);
    }
    WriteRawRC(CommandReg, Command);

    if (Command == PCD_TRANSCEIVE)
    {
        SetBitMask(BitFramingReg, 0x80);
    }

    i = 800; //600;//????????,??M1???????25ms
    do
    {
        n = ReadRawRC(ComIrqReg);
        i--;
    } while ((i != 0) && !(n & 0x01) && !(n & waitFor));
    ClearBitMask(BitFramingReg, 0x80);

    if (i != 0)
    {
        if (!(ReadRawRC(ErrorReg) & 0x1B))
        {
            status = MI_OK;
            if (n & irqEn & 0x01)
            {
                status = MI_NOTAGERR;
            }
            if (Command == PCD_TRANSCEIVE)
            {
                n = ReadRawRC(FIFOLevelReg);
                lastBits = ReadRawRC(ControlReg) & 0x07;
                if (lastBits)
                {
                    *pOutLenBit = (n - 1) * 8 + lastBits;
                }
                else
                {
                    *pOutLenBit = n * 8;
                }
                if (n == 0)
                {
                    n = 1;
                }
                if (n > MAXRLEN)
                {
                    n = MAXRLEN;
                }
                for (i = 0; i < n; i++)
                {
                    pOutData[i] = ReadRawRC(FIFODataReg);
                }
            }
        }
        else
        {
            status = MI_ERR;
        }
    }
    SetBitMask(ControlReg, 0x80);           // stop timer now
    WriteRawRC(CommandReg, PCD_IDLE);
    return status;
}

//开启天线
//每次启动或关闭天险发射之间应至少有1ms的间隔
void PcdAntennaOn(void)
{
    unsigned char i;
    i = ReadRawRC(TxControlReg);
    if (!(i & 0x03))
    {
        SetBitMask(TxControlReg,0x03);
    }
}

//关闭天线
void PcdAntennaOff(void)
{
    ClearBitMask(TxControlReg, 0x03);
}

void RC522_Config(unsigned char Card_Type)
{
    ClearBitMask(Status2Reg, 0x08);
    WriteRawRC(ModeReg, 0x3D);           //3F
    WriteRawRC(RxSelReg, 0x86);           //84
    WriteRawRC(RFCfgReg, 0x7F);   //4F
    WriteRawRC(TReloadRegL, 30); //tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
    WriteRawRC(TReloadRegH, 0);
    WriteRawRC(TModeReg, 0x8D);
    WriteRawRC(TPrescalerReg, 0x3E);
//           WriteRawRC(TxAutoReg,0x40);//???
    RC522_Delay(5000);   //delay_10ms(1);

    PcdAntennaOn();
}

void RC522_init(void)
{
    RC522_IO_Init();
    RC522_IO_Test();
    PcdReset();
    PcdAntennaOff();
    RC522_Delay(2000);
    PcdAntennaOn();

}
void Read_RF_id(void)
{
    if(T1_Count2 > 100 ) /* 1000 * 1 ms = 1s 时间到 */
    {
        T1_Count2 = 0;
        RF_status=PcdRequest(0x52,RF_CT);//寻卡,输出为卡类型
        if(RF_status==MI_OK) //寻卡成功
        {
            RF_STEP=1;
            RF_status = PcdAnticoll(RF_SN);  //防冲撞处理,输出卡片序列号,4字节--第0扇区第0块前4个字节是UID(序列号)
        }

        if(RF_status==MI_OK) //防冲撞成功
        {
            RF_STEP=2;
            RF_status = PcdSelect(RF_SN);  //选卡
        }

        if(RF_status==MI_OK) //选卡成功
        {
            RF_STEP=3;
            RF_status = PcdAuthState(0x60, 5, RF_Card_KEY, RF_SN);//验证卡
        }

        if(RF_status==MI_OK) //验证卡成功
        {
            RF_STEP=4;

            RF_ADD=RF_SN[0]+RF_SN[1]+RF_SN[2]+RF_SN[3];

            RF_SEMI=Read_RF_SEMI(RF_ADD);
        }
    }
}

//读取序列号
unsigned char Read_RF_SEMI(unsigned int Add)
{
    unsigned char SEMI_tmp;

    SEMI_tmp=AT24C64_Read_Byte(SYS_ADDR,Add);

    return SEMI_tmp;

}

//写入序列号
void Write_RF_SEMI(void)
{
    if(usSRegHoldBuf[100]==5)//..等于2的时候写入序列号
    {

        AT24C64_Write_Byte(SYS_ADDR,usSRegHoldBuf[102],usSRegHoldBuf[101]);

        usSRegHoldBuf[100]=0;
        usSRegHoldBuf[101]=0;
        usSRegHoldBuf[102]=0;
    }
}

//检测是不是新卡
void Test_new_RF_Card(void)
{
    if(T1S_FLAG)
    {
        if(RF_SEMI!=RF_SEMI_old)
        {
            RF_SEMI_old=RF_SEMI;
            RF_SEMI_change_flag=1;
        }
    }
}

使用特权

评论回复
44
wangjiahao88|  楼主 | 2018-11-4 12:56 | 只看该作者
#include "main.h"

//跟踪计算开始,也就是获取了一次比较的标志位,每X_min分钟后跟踪一次。
//自由设定跟踪比较的时间
unsigned int Track_Calc_start(unsigned int X_min)
{
    if(T_1000ms_FLAG_calc)
    {
        T_1000ms_FLAG_calc=0;

        if(++Track_Calc_cnt_tmp>(60*X_min))
        {
            Track_Calc_cnt_tmp=0;
            return 1;
        }
        else
        {
            return 0;
        }
    }


}

//阴天状态下,方位与俯仰自动走时的计算函数,秒单位
//例如 设定10秒,十秒已到,返回1,未到返回0
unsigned int Track_Calc_run_time(unsigned int run_s)
{
    if(T_1000ms_FLAG)
    {
        T_1000ms_FLAG=0;

        if(++A_track_cnt_tmp_Y>run_s)
        {
            A_track_cnt_tmp_Y=0;
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

//  计算时间与状态;
//0 时间不到,继续等待;
//1 时间已到,开始工作;
//2 时间到了,复位位置电池板的状态;

unsigned char Calc_time_stateus(void)
{
    switch(rtc.hour)
    {
    //1.2.3.4.5.20.22.23.属于停止时间.
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        return 0;
        break;

    //6.7.8.9.10.11.12.13.14.15.16.17.18.19属于正常工作的时间
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17:
    case 18:
    case 19:
        return 1;
        break;

    //21属于找限位,归位的时间
    case 21:
    case 22:
    case 23:
    case 20:
        return 2;
        break;
    }
}

//手动跟踪
void Man_track(void)
{

    switch(SYS_STEP_Man)
    {
    case 0://通电与上电的工作,LED依次闪烁
        //方位电机的动作与按键控制
        if(Button_Dong==1)FW_Dong();
        if(Button_Xi==1)  FW_Xi();
        if((Button_Dong==0)&&(Button_Xi==0))FW_STOP();
        //方位电机的动作与按键控制
        if(Button_Shang==1)FY_Shang();
        if(Button_Xia==1)  FY_Xia();
        if((Button_Shang==0)&&(Button_Xia==0))FY_STOP();


        /*标签的标志位清零*/
        RF_SEMI_change_flag=0;
        /*自动跟踪的状态清零*/
        SYS_STEP_Auto=Auto_track_sys_init;
        break;
    }
}

//自动跟踪
void Auto_track(void)
{

    //全自动跟踪的状态机
    switch(SYS_STEP_Auto)
    {

    /*通电与上电的工作,LED依次闪烁*/
    case Auto_track_sys_init:

        /*RF标签清零*/
        RF_SEMI=0;

        /*新标签的标志位清零*/
        RF_SEMI_change_flag=0;

        /*LED闪烁*/
        Led_welcome();

        /*跳转到任务开始*/
        SYS_STEP_Auto=Auto_track_motor_init;
        break;

    /*电机初始化,也就是全部停止的状态*/
    case Auto_track_motor_init:

        /*电机停止转动*/
        FW_STOP();

        /*电机停止转动*/
        FY_STOP();

        /*跳转到任务开始*/
        SYS_STEP_Auto=Auto_track_get_rtc;
        break;

    /*判断时间,决定是初始化,还是工作的状态*/
    case Auto_track_get_rtc:

        if(T100mS_FLAG)
        {
            /*LED闪烁*/
            LED5(T1S_FLAG);
            LED6(T1S_FLAG);
            LED7(T1S_FLAG);
            LED8(T1S_FLAG);
            /*读取时间*/
            P8563_Read_Time();

            /*计算时间与状态*/
            //等于0..,1.2.3.4.5.20.22.23.继续等待
            if(Calc_time_stateus()==0)SYS_STEP_Auto=Auto_track_get_rtc;

            //等于1..,6.7.8.9.10.11.12.13.14.15.16.17.18.19开始工作
            if(Calc_time_stateus()==1)SYS_STEP_Auto=Auto_track_begin;

            //等于2..,21电池板复位
            if(Calc_time_stateus()==2)SYS_STEP_Auto=Auto_track_reset_star;

            /*LED全灭*/
            LED5(OFF);
            LED6(OFF);
            LED7(OFF);
            LED8(OFF);
        }
        break;

    case Auto_track_begin:
        switch(rtc.hour)
        {
        /*
        当前的小时在6点与7点之间,进入倒转找限位的过程.
        */
        case 6:
            SYS_STEP_Auto=Auto_track_find_fwxw_star;//寻找方位限位
            break;

        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
        case 16:
        case 17:
        case 18:
        case 19:
            SYS_STEP_Auto=Auto_track_find_RF_new_star;//寻找一个新的标签
            break;

        }
        break;


    /*向东转动,寻找限位*/
    case Auto_track_find_fwxw_star:
        SYS_STEP_Auto=Auto_track_find_fwxw_pd;
        break;
    /*向东寻找限位*/
    case Auto_track_find_fwxw_pd:
        FW_Dong();
        FY_Xia();

        /*已经找到两个限位,进入下一环节*/
        if((XW_Dong==1)&&(XW_Xia==1)) SYS_STEP_Auto=Auto_track_find_fwxw_ok;

        /*
        1 如何找不到限位,则判断一下标签是不是等于100,这里的100这个标签是设定值
        2 这里读取标签的作用是防止方位限位的失效
        */
        if(RF_SEMI==RF_star_track)//如果没有找到起始标签,返回原状态,继续转动
        {
            SYS_STEP_Auto=Auto_track_find_fwxw_ok;
        }
        break;
    /*向东寻找限位,找到限位之后停转*/
    /*限位等到下一步操作...........*/
    case Auto_track_find_fwxw_ok:
        /*方位停转*/
        FW_STOP();
        FY_STOP();
        SYS_STEP_Auto=FW_Move_over;//方位动作完毕
        break;


    case Auto_track_find_RF_new_star://向西转动,寻找最近的一个标签
        SYS_STEP_Auto=Auto_track_find_RF_new;
        break;

    case Auto_track_find_RF_new://判断新标签
        FW_Xi();
        if(RF_SEMI_change_flag==0)//如果没有找到新的标签,返回原状态,继续转动
        {
            SYS_STEP_Auto=Auto_track_find_RF_new;
        }
        if(RF_SEMI_change_flag==1)//如果已经找到新的标签,则进入下一步骤
        {
            RF_SEMI_change_flag=0;
            SYS_STEP_Auto=Auto_track_find_RF_new_ok;
        }
        break;

    case Auto_track_find_RF_new_ok://找到标签之后停转
        /*方位先停转*/
        /*进入下一步的判断*/
        SYS_STEP_Auto=Auto_track_find_RF_pd_star;
        break;

    /*
    1 判断标签与时间是否合适
    2 时间段与标签合适,这时候才进入下一环节,进行俯仰的动作
    3 时间段与标签不合适,继续寻找
    4 寻找的方法,例如:rtc.hour=12;标签应该是在11 12 13 之间
    5 公式也就是:{ [rtc.hour-1] < RF_REMI < [rtc.hour+1] }
    6 Tim_track_offset:取值为标签与时间的范围
    */
    case Auto_track_find_RF_pd_star:

        //转动的时候,如果找到了限位,直接停止
        if(XW_Dong==1) SYS_STEP_Auto=Auto_track_find_RF_pd_ok;
        if(XW_Xi==1)   SYS_STEP_Auto=Auto_track_find_RF_pd_ok;

        //判断,当前标签小于时间,例如标签是10,时间是13,向西转动,找到一个合适的标签
        if(RF_SEMI<rtc.hour)
        {
            FW_Xi();
            SYS_STEP_Auto=Auto_track_find_RF_pd_star;
        }
        //判断,当前标签大于时间,例如标签是10,时间是8,向东,找到一个合适的标签
        if(RF_SEMI>rtc.hour)
        {
            FW_Dong();
            SYS_STEP_Auto=Auto_track_find_RF_pd_star;
        }
        //判断,当前标签合适,则停止判断!
        if(RF_SEMI==rtc.hour)
        {
            SYS_STEP_Auto=Auto_track_find_RF_pd_ok;
        }

        break;

    //自动找标签判断完毕,说明找到了一个合适的标签
    case Auto_track_find_RF_pd_ok:
        FW_STOP();
        SYS_STEP_Auto=FW_Move_over;//方位动作完毕
        break;


    //1 俯仰的跟踪动作.
    //2 跟踪完成,返回1,未完成,返回0.
    //3 跟踪的结果是 两个数值之差小于两个数据最大值或者和的.
    //4 动作方式1:光电上>光电下,向下转动;光电上<光电下,向上转动.
    //5 动作方式2:如果(光电上-光电下)差值,不超过两者最大值的一个百分比X%,则停止转动.
    //6 动作完毕后,进入下一环节,就是方位的对比.
    //范围:500.501.502.503.504.505.
    case FW_Move_over:
        SYS_STEP_Auto=Autotrackstar;
        break;

    //开始自动跟踪
    case Autotrackstar:
        if(Get_Day_YQ())
        {
            SYS_STEP_Auto=Autotrackstar_Q;   //晴天
        }

        if(!Get_Day_YQ())
        {
            SYS_STEP_Auto=Autotrackstar_Y;   //阴天
        }
        break;

    //晴天的跟踪开始
    case Autotrackstar_Q:
        SYS_STEP_Auto=Auto_fy_omp_Q;
        break;
    //如果是晴天,先转动了俯仰,再转动方位
    //在晴天,进行光电的判断
    case Auto_fy_omp_Q:
        //如果上传感器的数值-下传感器的数值之差,大于100,上大于下,向下转动
        if(FY_Sensor_chazhi>(Sensor_Q_omp))
        {
            SYS_STEP_Auto=A_track_FY_X_Q;
        }

        //如果上传感器的数值-下传感器的数值之差,小于-100,下大于上,向上转动
        if(FY_Sensor_chazhi<(-Sensor_Q_omp))
        {
            SYS_STEP_Auto=A_track_FY_S_Q;
        }

        if(abs(FY_Sensor_chazhi)<(int)(Sensor_Q_omp))
        {
            SYS_STEP_Auto=A_track_FY_T_Q;
        }

        break;

    /*
    1 俯仰动作,向下转动,表示为上大于下超过了50.50是阈值的设定值,可以随意的更改,下面的传感器可能被阴影遮挡.
    2 俯仰动作,向上转动,表示为下大于上超过了50.50是阈值的设定值,可以随意的更改,上面的传感器可能被阴影遮挡.
    3 俯仰动作停止,差值小于了50.50是阈值的设定值,可以随意的更改.
    */
    case A_track_FY_X_Q: //晴天,俯仰下动,晴天
        FY_Xia();
        /*没有找到限位,返回继续转动*/
        if(XW_Xia==0)SYS_STEP_Auto=Auto_fy_omp_Q;
        /*已经找到限位,进入下一环节*/
        if(XW_Xia==1)SYS_STEP_Auto=A_track_FY_T_Q;
        break;
    case A_track_FY_S_Q: //晴天,俯仰上动,阴天
        FY_Shang();
        /*没有找到限位,返回继续转动*/
        if(XW_Shang==0)SYS_STEP_Auto=Auto_fy_omp_Q;
        /*已经找到限位,进入下一环节*/
        if(XW_Shang==1)SYS_STEP_Auto=A_track_FY_T_Q;
        break;
    case A_track_FY_T_Q:   //晴天,俯仰停止,晴天,进入方位的比较
        FY_STOP();
        SYS_STEP_Auto=Auto_fw_omp_Q;
        break;

    //如果是晴天,先转动了俯仰,再转动方位
    //晴天,进行光电的判断
    case Auto_fw_omp_Q:

        //如果上传感器的数值-下传感器的数值之差,大于50,东大于西,向西转动
        if(abs(FW_Sensor_chazhi)>(Sensor_Q_omp))
        {
            SYS_STEP_Auto=A_track_FW_D_Q;
        }

        //如果上传感器的数值-下传感器的数值之差,小于-50,下大于上,向上转动
        if(FW_Sensor_chazhi<(-Sensor_Q_omp))
        {
            SYS_STEP_Auto=A_track_FW_X_Q;
        }

        if(abs(FW_Sensor_chazhi)<(Sensor_Q_omp))
        {
            SYS_STEP_Auto=A_track_FW_T_Q;
        }
        break;

    /*
    1 俯仰动作,向下转动,表示为上大于下超过了50.50是阈值的设定值,可以随意的更改,下面的传感器可能被阴影遮挡.
    2 俯仰动作,向上转动,表示为下大于上超过了50.50是阈值的设定值,可以随意的更改,上面的传感器可能被阴影遮挡.
    3 俯仰动作停止,差值小于了50.50是阈值的设定值,可以随意的更改.
    */
    case A_track_FW_D_Q: //方位东动,晴天
        FW_Dong();
        /*没有找到限位,返回继续转动*/
        if(XW_Dong==0)SYS_STEP_Auto=Auto_fw_omp_Q;
        /*已经找到限位,进入下一环节*/
        if(XW_Dong==1)SYS_STEP_Auto=A_track_FW_T_Q;
        break;
    case A_track_FW_X_Q: //晴天,方位西动,阴天
        FW_Xi();
        /*没有找到限位,返回继续转动*/
        if(XW_Xi==0)SYS_STEP_Auto=Auto_fw_omp_Q;
        /*已经找到限位,进入下一环节*/
        if(XW_Xi==1)SYS_STEP_Auto=A_track_FW_T_Q;
        break;
    case A_track_FW_T_Q://晴天,方位停止,晴天
        FW_STOP();
        SYS_STEP_Auto=Autotrackwait_Q;
        break;

    case Autotrackwait_Q://晴天
        Track_Calc_start_stateus=Track_Calc_start(Calc_loop);
        if(Track_Calc_start_stateus==0)SYS_STEP_Auto=Autotrackwait_Q;
        if(Track_Calc_start_stateus==1)SYS_STEP_Auto=Autotrackstar;
        break;

    //阴天的动作,阴天动作的开始
    //1 6--18:        方位一直往西转动
    //2 6--12:        俯仰向下,转动
    //3 12--20:俯仰向上,转动
    case Autotrackstar_Y:
        switch(rtc.hour)
        {
        case 6:
            SYS_STEP_Auto=A_track_FY_S_Y;
            break;
        case 7:
            SYS_STEP_Auto=A_track_FY_S_Y;
            break;
        case 8:
            SYS_STEP_Auto=A_track_FY_S_Y;
            break;
        case 9:
            SYS_STEP_Auto=A_track_FY_S_Y;
            break;
        case 10:
            SYS_STEP_Auto=A_track_FY_S_Y;
            break;
        case 11:
            SYS_STEP_Auto=A_track_FY_S_Y;
            break;
        case 12:
            SYS_STEP_Auto=A_track_FY_S_Y;
            break;
        case 13:
            SYS_STEP_Auto=A_track_FY_S_Y;
            break;
        case 14:
            SYS_STEP_Auto=A_track_FY_X_Y;
            break;
        case 15:
            SYS_STEP_Auto=A_track_FY_X_Y;
            break;
        case 16:
            SYS_STEP_Auto=A_track_FY_X_Y;
            break;
        case 17:
            SYS_STEP_Auto=A_track_FY_X_Y;
            break;
        case 18:
            SYS_STEP_Auto=A_track_FY_X_Y;
            break;
        }
        break;

    case A_track_FY_S_Y://俯仰上./..转动几分钟以后,进入方位西转动
        FY_Shang();
        A_track_cnt_stateus=Track_Calc_run_time(FY_run_time_Y);
        if(A_track_cnt_stateus==0)SYS_STEP_Auto=A_track_FY_S_Y;
        if(A_track_cnt_stateus==1)SYS_STEP_Auto=A_track_FY_T_Y;

        /*已经找到限位,进入下一环节*/
        if(XW_Shang==1)SYS_STEP_Auto=A_track_FY_T_Y;
        break;

    case A_track_FY_X_Y://俯仰下./..转动几分钟以后,进入方位西转动
        FY_Xia();
        A_track_cnt_stateus=Track_Calc_run_time(FY_run_time_Y);
        if(A_track_cnt_stateus==0)SYS_STEP_Auto=A_track_FY_X_Y;
        if(A_track_cnt_stateus==1)SYS_STEP_Auto=A_track_FY_T_Y;

        /*已经找到限位,进入下一环节*/
        if(XW_Xia==1)SYS_STEP_Auto=A_track_FY_T_Y;
        break;

    case A_track_FY_T_Y://阴天,俯仰停./..转动几分钟以后,进入方位西转动
        FY_STOP();
        SYS_STEP_Auto=A_track_FW_X_Y;
        break;

    case A_track_FW_X_Y://阴天,方位西./..转动几分钟以后,进入方位西转动
        FW_Xi();
        A_track_cnt_stateus=Track_Calc_run_time(FY_run_time_Y);
        if(A_track_cnt_stateus==0)SYS_STEP_Auto=A_track_FW_X_Y;
        if(A_track_cnt_stateus==1)SYS_STEP_Auto=A_track_FW_T_Y;

        /*已经找到限位,进入下一环节*/
        if(XW_Xi==1)SYS_STEP_Auto=A_track_FW_T_Y;

        break;

    case A_track_FW_D_Y://阴天,方位东./..转动几分钟以后,进入方位西转动
        FW_Dong();
        if(A_track_cnt_stateus==0)SYS_STEP_Auto=A_track_FW_D_Y;
        if(A_track_cnt_stateus==1)SYS_STEP_Auto=A_track_FW_T_Y;

        /*已经找到限位,进入下一环节*/
        if(XW_Dong==1)SYS_STEP_Auto=A_track_FW_T_Y;
        break;

    case A_track_FW_T_Y://阴天,方位停.
        FW_STOP();
        SYS_STEP_Auto=Autotrackwait_Y;
        break;

    //阴天,自动跟踪的等待到5停止;
    case Autotrackwait_Y:
        Track_Calc_start_stateus=Track_Calc_start(Calc_loop);
        if(Track_Calc_start_stateus==0)SYS_STEP_Auto=Autotrackwait_Y;
        if(Track_Calc_start_stateus==1)SYS_STEP_Auto=Autotrackstar;
        break;



    //自动复位,21点复位
    //自动复位,先是方位复位,然后是俯仰复位
    /*方位复位,可以通过限位来触发,也可以通过读取到【100号】标签来触发*/
    case Auto_track_reset_star:
        SYS_STEP_Auto=FW_find_xw_ccw;
        break;

    //方位倒转找限位
    case FW_find_xw_ccw:
        FW_Dong();
        SYS_STEP_Auto=FW_find_xw_pd;
        break;
    //判断是不是找到了限位
    case FW_find_xw_pd:
        /*没有找到限位,返回继续转动*/
        if(XW_Dong==0)SYS_STEP_Auto=FW_find_xw_pd;
        /*已经找到限位,进入下一环节*/
        if(XW_Dong==1)SYS_STEP_Auto=FW_find_xw_ok;
        /*
        1 如何找不到限位,则判断一下标签是不是等于100,这里的100这个标签是设定值
        2 这里读取标签的作用是防止方位限位的失效
        */
        if(RF_SEMI==RF_star_track)
        {
            SYS_STEP_Auto=FW_find_xw_ok;
        }
        break;
    case FW_find_xw_ok:
        /*
        1 方位找到限位或者找到标签之后停止,转入下一环节
        2 下一环节就是找俯仰的限位
        */
        FW_STOP();
        SYS_STEP_Auto=FY_find_xw_ccw;
        break;


    case FY_find_xw_ccw://俯仰水平状态
        FY_Shang();
        SYS_STEP_Auto=FY_find_xw_pd;
        break;

    case FY_find_xw_pd:
        /*已经找到限位,进入下一环节*/
        if(XW_Shang==1)SYS_STEP_Auto=FY_find_xw_ok;
        break;

    case FY_find_xw_ok:
        /*
        1 方位找到限位或者找到标签之后停止,转入下一环节
        2 下一环节就是找俯仰的限位
        */
        FY_STOP();
        SYS_STEP_Auto=Auto_track_reset_over;
        break;

    case Auto_track_reset_over:
        SYS_STEP_Auto=Auto_track_motor_init;
        break;

    }
}


使用特权

评论回复
45
wangjiahao88|  楼主 | 2018-11-4 12:56 | 只看该作者
#include "main.h"

unsigned char Led_Error_Report(void)
{

}

unsigned char Amp_Error_Report(void)
{

}

unsigned char Sensor_Error_Report(void)
{

}

unsigned char XW_Error_Report(void)
{

}

使用特权

评论回复
46
wangjiahao88|  楼主 | 2018-11-4 12:56 | 只看该作者
modbus

#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"

#include "stm32f10x.h"

#include "bsp_usart.h"


void prvvUARTTxReadyISR( void );
void prvvUARTRxISR( void );

/* ----------------------- Start implementation -----------------------------*/
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
    if (xRxEnable)  //接收使能
    {
        USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);  //使能接收中断
    }
    else  //失能
    {
        USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, DISABLE);  //失能接收中断
    }

    if (xTxEnable)  //发送使能
    {
        USART_ITConfig(DEBUG_USARTx, USART_IT_TXE, ENABLE);  //使能
    }
    else  //失能
    {
        USART_ITConfig(DEBUG_USARTx, USART_IT_TXE, DISABLE);  //失能
    }
}

BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;

    (void)ucPORT;  //不修改串口号
    (void)ucDataBits;  //不修改数据位长度
    (void)eParity;  //不修改检验格式

    // 打开串口GPIO的时钟
    DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
    // 打开串口外设的时钟
    DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

    // 将USART Tx的GPIO配置为推挽复用模式
    GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

    // 将USART Rx的GPIO配置为浮空输入模式
    GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

    // 配置串口的工作参数
    // 配置波特率
    USART_InitStructure.USART_BaudRate = ulBaudRate;
    // 配置 针数据字长
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    // 配置停止位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    // 配置校验位
    USART_InitStructure.USART_Parity = USART_Parity_No ;
    // 配置硬件流控制
    USART_InitStructure.USART_HardwareFlowControl =
        USART_HardwareFlowControl_None;
    // 配置工作模式,收发一起
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    // 完成串口的初始化配置
    USART_Init(DEBUG_USARTx, &USART_InitStructure);

    // 串口中断优先级配置
    NVIC_Configuration();

    // 使能串口
    USART_Cmd(DEBUG_USARTx, ENABLE);


    return TRUE;
}

BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
    USART_SendData(DEBUG_USARTx, ucByte);  //发送一个字节
    return TRUE;
}

BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
    *pucByte = USART_ReceiveData(DEBUG_USARTx);  //接收一个字节
    return TRUE;
}
void prvvUARTTxReadyISR( void )
{
    pxMBFrameCBTransmitterEmpty(  );//在发送完成中断调用该函数
}
void prvvUARTRxISR( void )
{
    pxMBFrameCBByteReceived(  );//在接收中断函数调用该函数
}

/**
  *****************************************************************************
  * @name   : 串口中断服务函数
  *
  * @Brief  : none
  *
  * @Input  : none
  *
  * @output : none
  *
  * @return : none
  *****************************************************************************
**/
void  USART1_IRQHandler(void)
{
    if (USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) == SET)  //接收中断
    {
        prvvUARTRxISR();
        USART_ClearITPendingBit(DEBUG_USARTx, USART_IT_RXNE);
    }

    if (USART_GetITStatus(DEBUG_USARTx, USART_IT_TXE) == SET)  //发送中断
    {
        prvvUARTTxReadyISR();
        USART_ClearITPendingBit(DEBUG_USARTx, USART_IT_TXE);
    }
}

使用特权

评论回复
47
wangjiahao88|  楼主 | 2018-11-4 12:57 | 只看该作者
MB 定时器

#include "port.h"
#include "mb.h"
#include "mbport.h"

#include "stm32f10x.h"

/* ----------------------- static functions ---------------------------------*/
void prvvTIMERExpiredISR( void );

/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{
//    return FALSE;

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    NVIC_InitTypeDef        NVIC_InitStructure;

    uint16_t PrescalerValue = 0;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    //
    //HCLK为72MHz
    //时基频率72 / (1 + Prescaler) = 20KHz
    //
    PrescalerValue = (uint16_t)((SystemCoreClock / 20000) - 1);
    //
    //初始化定时器参数
    //
    TIM_TimeBaseStructure.TIM_Period = (uint16_t)usTim1Timerout50us;
    TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    //
    //使能预装
    //
    TIM_ARRPreloadConfig(TIM2, ENABLE);

    //
    //初始化中断优先级
    //
    NVIC_InitStructure.NVIC_IRQChannel                   = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
    TIM_Cmd(TIM2, DISABLE);

    return TRUE;
}


void
vMBPortTimersEnable(  )
{
    /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    TIM_SetCounter(TIM2, 0x00000000);
    TIM_Cmd(TIM2, ENABLE);
}

void
vMBPortTimersDisable(  )
{
    /* Disable any pending timers. */

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
    TIM_SetCounter(TIM2, 0x00000000);
    TIM_Cmd(TIM2, DISABLE);
}

/* Create an ISR which is called whenever the timer has expired. This function
* must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
* the timer has expired.
*/
void prvvTIMERExpiredISR( void )
{
    ( void )pxMBPortCBTimerExpired(  );
}

/**
  *****************************************************************************
  * @Name   : 定时器4中断服务函数
  *
  * @Brief  : none
  *
  * @Input  : none
  *
  * @Output : none
  *
  * @Return : none
  *****************************************************************************
**/
void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        prvvTIMERExpiredISR();
    }
}

使用特权

评论回复
48
wangjiahao88|  楼主 | 2018-11-4 12:57 | 只看该作者
#include "user_mb_app.h"

/* ----------------------- Variables ---------------------------------*/
//Slave mode use these variables
//开关输入状态
USHORT   usSDiscInStart                             = S_DISCRETE_INPUT_START;
UCHAR    ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8];
//线圈状态
USHORT   usSCoilStart                               = S_COIL_START;
UCHAR    ucSCoilBuf[S_COIL_NCOILS/8]                ;
//输入寄存器内容
USHORT   usSRegInStart                              = S_REG_INPUT_START;
USHORT   usSRegInBuf[S_REG_INPUT_NREGS]             ;
//保持寄存器内容
USHORT   usSRegHoldStart                            = S_REG_HOLDING_START;
USHORT   usSRegHoldBuf[S_REG_HOLDING_NREGS]         ;

//******************************输入寄存器回调函数**********************************
//函数定义: eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
//描    述:输入寄存器相关的功能(读、连续读)
//入口参数:pucRegBuffer : 回调函数将Modbus寄存器的当前值写入的缓冲区
//                        usAddress    : 寄存器的起始地址,输入寄存器的地址范围是1-65535。
//                        usNRegs      : 寄存器数量
//出口参数:eMBErrorCode : 这个函数将返回的错误码
//备    注:Editor:Armink 2010-10-31    Company: BXXJS
//**********************************************************************************
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;
    USHORT *        pusRegInputBuf;
    UCHAR           REG_INPUT_START;
    UCHAR           REG_INPUT_NREGS;
    UCHAR           usRegInStart;


    pusRegInputBuf = usSRegInBuf;
    REG_INPUT_START = S_REG_INPUT_START;
    REG_INPUT_NREGS = S_REG_INPUT_NREGS;
    usRegInStart = usSRegInStart;

    if( ( usAddress >= REG_INPUT_START )
            && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegInStart );
        while( usNRegs > 0 )
        {
            *pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}
//******************************保持寄存器回调函数**********************************
//函数定义: eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
//描    述:保持寄存器相关的功能(读、连续读、写、连续写)
//入口参数:pucRegBuffer : 如果需要更新用户寄存器数值,这个缓冲区必须指向新的寄存器数值。
//                         如果协议栈想知道当前的数值,回调函数必须将当前值写入这个缓冲区
//                        usAddress    : 寄存器的起始地址。
//                        usNRegs      : 寄存器数量
//          eMode        : 如果该参数为eMBRegisterMode::MB_REG_WRITE,用户的应用数值将从pucRegBuffer中得到更新。
//                         如果该参数为eMBRegisterMode::MB_REG_READ,用户需要将当前的应用数据存储在pucRegBuffer中
//出口参数:eMBErrorCode : 这个函数将返回的错误码
//备    注:Editor:Armink 2010-10-31    Company: BXXJS
//**********************************************************************************
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;
       
       
    USHORT *        pusRegHoldingBuf;
    UCHAR           REG_HOLDING_START;
    UCHAR           REG_HOLDING_NREGS;
    UCHAR           usRegHoldStart;

    pusRegHoldingBuf = usSRegHoldBuf;
    REG_HOLDING_START = S_REG_HOLDING_START;
    REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
    usRegHoldStart = usSRegHoldStart;

    if( ( usAddress >= REG_HOLDING_START ) &&
            ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegHoldStart );
        switch ( eMode )
        {
        /* Pass current register values to the protocol stack. */
        case MB_REG_READ:
            while( usNRegs > 0 )
            {
                                                       
                *pucRegBuffer++ = ( unsigned char )( pusRegHoldingBuf[iRegIndex] >> 8 );
                *pucRegBuffer++ = ( unsigned char )( pusRegHoldingBuf[iRegIndex] & 0xFF );
                iRegIndex++;
                usNRegs--;
            }
            break;

        /* Update current register values with new values from the
         * protocol stack. */
        case MB_REG_WRITE:
            while( usNRegs > 0 )
            {
                pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
                pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
                iRegIndex++;
                usNRegs--;
                                                       
                                                       
            }
            break;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }
    return eStatus;
}
//****************************线圈状态寄存器回调函数********************************
//函数定义: eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
//描    述:线圈状态寄存器相关的功能(读、连续读、写、连续写)
//入口参数:pucRegBuffer : 位组成一个字节,起始寄存器对应的位处于该字节pucRegBuffer的最低位LSB。
//                         如果回调函数要写这个缓冲区,没有用到的线圈(例如不是8个一组的线圈状态)对应的位的数值必须设置位0。
//                        usAddress    : 第一个线圈地址。
//                        usNCoils     : 请求的线圈个数
//          eMode        ;如果该参数为eMBRegisterMode::MB_REG_WRITE,用户的应用数值将从pucRegBuffer中得到更新。
//                         如果该参数为eMBRegisterMode::MB_REG_READ,用户需要将当前的应用数据存储在pucRegBuffer中
//出口参数:eMBErrorCode : 这个函数将返回的错误码
//备    注:Editor:Armink 2010-10-31    Company: BXXJS
//**********************************************************************************
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex , iRegBitIndex , iNReg;
    UCHAR *         pucCoilBuf;
    UCHAR           COIL_START;
    UCHAR           COIL_NCOILS;
    UCHAR           usCoilStart;
    iNReg =  usNCoils / 8 + 1;        //占用寄存器数量

    pucCoilBuf = ucSCoilBuf;
    COIL_START = S_COIL_START;
    COIL_NCOILS = S_COIL_NCOILS;
    usCoilStart = usSCoilStart;

    if( ( usAddress >= COIL_START ) &&
            ( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) )
    {
        iRegIndex    = ( int )( usAddress - usCoilStart ) / 8 ;    //每个寄存器存8个
        iRegBitIndex = ( int )( usAddress - usCoilStart ) % 8 ;           //相对于寄存器内部的位地址
        switch ( eMode )
        {
        /* Pass current coil values to the protocol stack. */
        case MB_REG_READ:
            while( iNReg > 0 )
            {
                *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++] , iRegBitIndex , 8);
                iNReg --;
            }
            pucRegBuffer --;
            usNCoils = usNCoils % 8;                        //余下的线圈数
            *pucRegBuffer = *pucRegBuffer <<(8 - usNCoils); //高位补零
            *pucRegBuffer = *pucRegBuffer >>(8 - usNCoils);
            break;

        /* Update current coil values with new values from the
         * protocol stack. */
        case MB_REG_WRITE:
            while(iNReg > 1)                                                                         //最后面余下来的数单独算
            {
                xMBUtilSetBits(&pucCoilBuf[iRegIndex++] , iRegBitIndex  , 8 , *pucRegBuffer++);
                iNReg--;
            }
            usNCoils = usNCoils % 8;                            //余下的线圈数
            if (usNCoils != 0)                                  //xMBUtilSetBits方法 在操作位数量为0时存在bug
            {
                xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
                               *pucRegBuffer++);
            }
            break;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }
    return eStatus;
}
//****************************离散输入寄存器回调函数********************************
//函数定义: eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
//描    述:离散输入寄存器相关的功能(读、连续读)
//入口参数:pucRegBuffer : 用当前的线圈数据更新这个寄存器,起始寄存器对应的位处于该字节pucRegBuffer的最低位LSB。
//                         如果回调函数要写这个缓冲区,没有用到的线圈(例如不是8个一组的线圈状态)对应的位的数值必须设置为0。
//                        usAddress    : 离散输入的起始地址
//                        usNDiscrete  : 离散输入点数量
//出口参数:eMBErrorCode : 这个函数将返回的错误码
//备    注:Editor:Armink 2010-10-31    Company: BXXJS
//**********************************************************************************
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex , iRegBitIndex , iNReg;
    UCHAR *         pucDiscreteInputBuf;
    UCHAR           DISCRETE_INPUT_START;
    UCHAR           DISCRETE_INPUT_NDISCRETES;
    UCHAR           usDiscreteInputStart;
    iNReg =  usNDiscrete / 8 + 1;        //占用寄存器数量


    pucDiscreteInputBuf = ucSDiscInBuf;
    DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
    DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
    usDiscreteInputStart = usSDiscInStart;

    if( ( usAddress >= DISCRETE_INPUT_START )
            && ( usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES ) )
    {
        iRegIndex    = ( int )( usAddress - usDiscreteInputStart ) / 8 ;    //每个寄存器存8个
        iRegBitIndex = ( int )( usAddress - usDiscreteInputStart ) % 8 ;           //相对于寄存器内部的位地址
        while( iNReg > 0 )
        {
            *pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++] , iRegBitIndex , 8);
            iNReg --;
        }
        pucRegBuffer --;
        usNDiscrete = usNDiscrete % 8;                     //余下的线圈数
        *pucRegBuffer = *pucRegBuffer <<(8 - usNDiscrete); //高位补零
        *pucRegBuffer = *pucRegBuffer >>(8 - usNDiscrete);
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}



使用特权

评论回复
49
wangjiahao88|  楼主 | 2018-11-4 12:58 | 只看该作者
上传一下 工程文件!

希望对大家能够有帮助!

2017年8月21日.zip

461.17 KB

使用特权

评论回复
50
wangjiahao88|  楼主 | 2018-11-4 12:58 | 只看该作者
受国家 光伏发电 政策的影响 估计很多都拿不到补贴了

使用特权

评论回复
51
keaibukelian| | 2018-11-7 12:42 | 只看该作者
请问如何追踪太阳能的角度呢

使用特权

评论回复
52
labasi| | 2018-11-7 12:45 | 只看该作者
精度能达到多少呀

使用特权

评论回复
53
paotangsan| | 2018-11-7 12:50 | 只看该作者
是用电机进行跟踪的吗

使用特权

评论回复
54
wangjiahao88|  楼主 | 2018-11-12 15:07 | 只看该作者
paotangsan 发表于 2018-11-7 12:50
是用电机进行跟踪的吗

是的 。用的是 直流有刷电机。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则