//======================================================================
//文件名称：main.c（应用工程主函数）
//框架提供：SD-Arm（sumcu.suda.edu.cn）
//版本更新：20191108-20200419
//功能描述：见本工程的..\01_Doc\Readme.txt
//移植规则：【固定】
//======================================================================
#define GLOBLE_VAR
#include "includes.h"      //包含总头文件

//----------------------------------------------------------------------
//声明使用到的内部函数
//main.c使用的内部函数声明处
uint8_t GPIO_Tsi(uint16_t port_pin);
void Delay_ms(uint16_t u16ms);
float TempRegression(uint16_t tmpAD);  //环境温度AD值转为实际温度
float TempTrans(uint16_t mcu_temp_AD); //mcu温度AD值转为实际温度



//----------------------------------------------------------------------
//主函数，一般情况下可以认为程序从此开始运行（实际上有启动过程，参见书稿）
int main(void)
{
    //（1）======启动部分（开头）==========================================
    //（1.1）声明main函数使用的局部变量
    //uint32_t mMainLoopCount;  //主循环次数变量
    //uint8_t  mFlag;           //灯的状态标志
    uint32_t mCount;			//延时的次数
    uint32_t i;					//循环变量
    uint16_t mcu_temp_AD;	
    float mcu_temp;				//芯片温度
    uint16_t temp_AD;		
    float temp;					//温度传感器温度
    float preTemp;				//上一次温度传感器温度
    //（1.2）【不变】关总中断
    DISABLE_INTERRUPTS;
    
    //（1.3）给主函数使用的局部变量赋初值
    //mMainLoopCount=0;    //主循环次数变量
    //mFlag='A'; 
    
    mCount=0;//记次数
    preTemp = 0;
    
    //（1.4）给全局变量赋初值
    
    //（1.5）用户外设模块初始化
    gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF);	//初始化蓝灯
    gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF);	//初始化绿灯
    gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);	//初始化红灯
    adc_init(AD_MCU_TEMP,0);					   //初始化AD芯片温度模块
    adc_init(AD_TEMP,0);					   //初始化AD芯片温度模块
    emuart_init(UART_User,115200);
    //（1.6）使能模块中断
    uart_enable_re_int(UART_User);
    
    //（1.7）【不变】开总中断
    ENABLE_INTERRUPTS;
    
    //（1）======启动部分（结尾）==========================================
    
    //（2）======主循环部分（开头）========================================
    for(;;)   //for(;;)（开头）
    {
        //（2.1）主循环次数变量+1
        //mMainLoopCount++;
        //（2.2）未达到主循环次数设定值，继续循环
        //延时1秒
        Delay_ms(1000);
        //if (mMainLoopCount<=12888999)  continue;
        //（2.3）达到主循环次数设定值，执行下列语句，进行灯的亮暗处理
        //（2.3.1）清除循环次数变量
        //mMainLoopCount=0;
        printf("------------------------\r\n\n");
        
        mcu_temp_AD = adc_read(AD_MCU_TEMP);       //读取mcu温度通道AD值
        mcu_temp=TempTrans(mcu_temp_AD);           //温度回归
        printf("芯片内部温度为:%6.2f℃\r\n",mcu_temp);
        temp_AD = adc_read(AD_TEMP);
        temp=TempRegression(temp_AD);
        if(temp==-274)
        {
        	printf("热敏电阻温度AD值异常，请检查相关硬件\n");
        }
        else
        {
            printf("热敏电阻温度为:%6.2f℃\r\n",temp);
        }
        
        //【20201106】RJ添加触摸温度传感器闪烁黄灯的功能
        if(preTemp > 0 && (temp > preTemp) && (temp - preTemp >= 1))
        {       
            preTemp = temp;//记录下上次的温度
            printf("触摸温度传感器！！！！！\n"); 
            //只有当灯原来是亮的情况下才将灯置灭
            //保证灯是灭的
            if ((mCount / 5) % 2)
            gpio_reverse(LIGHT_RED);	
            if ((mCount / 10) % 2)
            gpio_reverse(LIGHT_GREEN);
            if ((mCount / 20) % 2)
            gpio_reverse(LIGHT_BLUE);
            //闪烁黄灯
            printf("指示灯颜色为【黄色】");
            for (i = 0; i <= 2; i++)
            {
                gpio_reverse(LIGHT_RED);
                gpio_reverse(LIGHT_GREEN);
                Delay_ms(1000);
                gpio_reverse(LIGHT_RED);
                gpio_reverse(LIGHT_GREEN);
                Delay_ms(1000);
            }
            //将灯恢复之前的状态
            if ((mCount / 5) % 2)
            gpio_reverse(LIGHT_RED);
            if ((mCount / 10) % 2)
            gpio_reverse(LIGHT_GREEN);
            if ((mCount / 20) % 2)
            gpio_reverse(LIGHT_BLUE);
            continue;
        } 
        else
        {
            preTemp = temp;//记录下上次的温度
        } 
        //【20201106】RJ添加触摸TSI闪烁白灯的功能
//        if(GPIO_Tsi(GPIO_TSI)==1) //如果判断到有触摸动作
//        {
//            printf("触摸Tsi！！！！！\n"); 
//            //只有当灯原来是亮的情况下才将灯置灭
//            //保证灯是灭的
//            if ((mCount / 5) % 2)
//            gpio_reverse(LIGHT_RED);	
//            if ((mCount / 10) % 2)
//            gpio_reverse(LIGHT_GREEN);
//            if ((mCount / 20) % 2)
//            gpio_reverse(LIGHT_BLUE);
//            //闪烁白灯
//            printf("指示灯颜色为【白色】");
//            for (i = 0; i <= 2; i++)
//            {
//                gpio_reverse(LIGHT_RED);
//                gpio_reverse(LIGHT_GREEN);
//                gpio_reverse(LIGHT_BLUE);
//                Delay_ms(1000);
//                gpio_reverse(LIGHT_RED);
//                gpio_reverse(LIGHT_GREEN);
//                gpio_reverse(LIGHT_BLUE);
//                Delay_ms(1000);
//            }
//            //将灯恢复之前的状态
//            if ((mCount / 5) % 2)
//            gpio_reverse(LIGHT_RED);
//            if ((mCount / 10) % 2)
//            gpio_reverse(LIGHT_GREEN);
//            if ((mCount / 20) % 2)
//            gpio_reverse(LIGHT_BLUE);
//            
//            continue;
//        }
        
        mCount++;
        //当秒数40秒时，重新开始计数
        //避免一直累加
        if (mCount >= 40)
        {
            mCount=0;
            printf("指示灯颜色为【暗色】");
        }
        //（2.3.2）如灯状态标志mFlag为'L'，灯的闪烁次数+1并显示，改变灯状态及标志
        if(mCount%5==0)
        {
          gpio_reverse(LIGHT_RED);
          printf(" LIGHT_RED:reverse--\n");   //串口输出灯的状态
          if(mCount/5==1)
          {
            printf("指示灯颜色为【红色】");
           }
           else if(mCount/5==3)
           {
            printf("指示灯颜色为【黄色】");
           }
           else if(mCount/5==5)
           {
            printf("指示灯颜色为【紫色】");
           }
           else if(mCount/5==7)
           {
            printf("指示灯颜色为【白色】");
           }
        }
        if (mCount%10==0)                    //判断灯的状态标志
        {
            gpio_reverse(LIGHT_GREEN);
            printf(" LIGHT_GREEN:reverse--\n");   //串口输出灯的状态
            if(mCount/10==1)
            {
             printf("指示灯颜色为【绿色】");
            }
            else if(mCount/10==3)
           {
            printf("指示灯颜色为【青色】");
           }
        }
        if (mCount%20==0)                    //判断灯的状态标志
        {
            gpio_reverse(LIGHT_BLUE);				
            printf(" LIGHT_BLUE:reverse--\n");   //串口输出灯的状态
            if(mCount/20==1)
            {
            printf("指示灯颜色为【蓝色】");
            }
        }
        
    }  //for(;;)结尾
    //（2）======主循环部分（结尾）========================================
}   //main函数（结尾）


//======以下为主函数调用的子函数===========================================
//======================================================================
//函数名称：Delay_ms
//函数返回：无
//参数说明：近似毫秒
//功能概要：延时 - 毫秒级
//======================================================================
void Delay_ms(uint16_t u16ms)
{
    for(volatile uint32_t i = 0; i < 8000*u16ms; i++) __ASM("NOP");
}

//======================================================================
//功能概要：连续判断三次GPIO的输入引脚，大部分为0，则认为有触摸
//参数说明：GPIO引脚
//函数返回：1：有触摸，0：无触摸
//原理概要：当GPIO引脚被定义为无上下拉输入功能时，容易收到外界干扰，本程序
//         把这个特性转为有用的功能，由于人体相当于一个大电阻，手触摸这个
//         引脚会使得引脚状态发生随机性改变，利用这种变化可以被视为有触摸，
//         实现了无触摸功能引脚的触摸功能
//======================================================================

uint8_t GPIO_Tsi(uint16_t port_pin)
{
    //（1）声明局部变量
    int i,j,m;
    //（2）初始化Tsi引脚
    gpio_init(port_pin,GPIO_INPUT,1);   
    //（3）判断是否有触摸
    for (j=0;j<3;j++)
    {
        
        for(uint32_t  i = 0; i < 5000*50; i++) __asm ("NOP");
        m=0;
        for (i=0;i<3000;i++) m=m+gpio_get(port_pin);
        if (m<2500)
        continue;
        else
        return 0;  	
    }
    return 1;
}


//============================================================================
//函数名称：TempRegression
//功能概要：将读到的环境温度AD值转换为实际温度
//参数说明：tmpAD：通过adc_read函数得到的AD值
//函数返回：实际温度值
//============================================================================
float TempRegression(uint16_t tmpAD)
{
    float Vtemp,Rtemp,temp;
    if(tmpAD<=72)
    {
       return -274;
    }
    Vtemp = (tmpAD*3300.0)/4096;
    Rtemp = Vtemp/(3300.0 - Vtemp)*10000.0;
    temp = (1/(log(Rtemp/10000.0)/3950.0 + (1/(273.15 + 25)))) - 273.15 + 0.5; 
    return temp; 
}


//============================================================================
//函数名称：TempTrans
//功能概要：将读到的mcu温度AD值转换为实际温度
//参数说明：mcu_temp_AD：通过adc_read函数得到的AD值
//函数返回：实际温度值
//============================================================================
float TempTrans(uint16_t mcu_temp_AD)
{
	float mcu_temp_result;
	mcu_temp_result=(float)(55+(100*((float)(mcu_temp_AD) - AD_CAL1))/(AD_CAL2 - AD_CAL1));
	return mcu_temp_result;
}


//========================================================================
/*
知识要素：
（1）main.c是一个模板，该文件所有代码均不涉及具体的硬件和环境，通过调用构件
实现对硬件的干预。
（2）本文件中对宏GLOBLE_VAR进行了定义，所以在包含"includes.h"头文件时，会定
义全局变量，在其他文件中包含"includes.h"头文件时，
编译时会自动增加extern
*/





