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

📄 070403.c

📁 电压表
💻 C
📖 第 1 页 / 共 5 页
字号:
#include  <msp430x14x.h>
#include  <in430.h>
#include  "main.h"
#include  "comm.c"
///////////////////////////////////////////////////////////////////////////////
	            //主循环
///////////////////////////////////////////////////////////////////////////////
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;//Stop WDT  
    _DINT();
    cs_initial();//系统初始化              
    INI_SET();//系统参数初始化(读取铁电存储器的系统参数)
    UART_INIT(systembuf[0x02],systembuf[0x01]);
    RTCInitial();//时钟初始化 
    _EINT();//开中断 
    while(1)
    {
        WDI_1;
        ErrCOUNT1++;
        if(ErrCOUNT1>0x05)
        {
                _DINT();
                cs_initial();//初始化              
                INI_SET();
                UART_INIT(systembuf[0x02],systembuf[0x01]);
                RTCInitial();//初始化 
                _EINT();//开中断 
        }
        Emendationpro();//滤波校正子程序
        compare();
        Timeeventpro();//读8025的时间    //zd 060925
        WDI_0;
        overrunpro();//超限处理子程序
        Keydealpro();//按键处理子程序
        Timeeventpro();
        menudisppro();//菜单显示和设置 
        commpro();//通讯处理子程序
        lamppro();//指示灯子程序
    }
}
///////////////////////////////////////////////////////////////////////////////
        //系统初始化
///////////////////////////////////////////////////////////////////////////////
void cs_initial(void)
{
        WDTCTL = WDTPW + WDTHOLD; //Stop WDT
        IFG1 = 0x00;
        IFG2 = 0x00;
        BCSCTL1&=0x7F;//0x77 打开XT2
        do                                //测试直到XT2稳定
        {
                IFG1 &= ~OFIFG;           //Clear OSC fault flag 
        }while(OFIFG&IFG1);               //OSC fault flag set? 
        delay(0xff);                         //delay(0xFF);
        IFG1 &= ~OFIFG;                   //Clear OSC fault flag 
        BCSCTL2 = SELS + SELM1;           //XT2 作为MCLK,SMCLK 时钟源8M
        
        P1SEL=0x00;//P1为I/O口
        P1DIR=0x1F;//P1.0-P1.4输出,P1.5-P1.7输入 
        P1OUT=0x00;
        P1IES=0x20;//P1.5
        P1IE =0x20;//开键盘中断
        
        P2SEL=0x00;//P2普通I/O口,
        P2DIR=0xFF;//P2.0-7输出
        P2OUT=0x00;               
        
        P3SEL=0x30;//P3.4-5作为UART,其他都是I/O   
        P3DIR=0xDF;
        P3OUT=0x00;
        DIR_0;//初始化485为接收
        SDA_1;
        
        P4SEL=0x00;//P4为I/O口
        P4DIR=0xFF;//P4输出
        P4OUT=0x00;//
        SCL_1;
        
        P5SEL=0x00;//P5为I/O口
        P5DIR=0xFF;//P5输出
        P5OUT=0x00;
        
        P6SEL=0xFF;//80;//P6.7作为AD转换模块功能
        P6DIR=0x00;//7F; //P6.7作为输入,其余为输出 
        P6OUT=0x00; 
        
        //定时器A初始化//
        TACTL=0x0204;//SMCLK 定时器暂停 时钟直通
        TACCR0=1000;//0xffff;//7999; 
        TACCR1=500;//1000;//2000;
     	TACCTL0=0x0090;
        TACCTL1=0x0060;
        TAR=0;
        TACTL|=MC0;//增计数到TACCR0
       
        //ADC12初始化//
        ADC12CTL0 &= ~ENC;                          
        ADC12CTL0=0x6690;                          
        ADC12CTL1 =0x0632; 
        ADC12MCTL0 = 0xE7;                         
        ADC12IE|=BIT0;                              
        ADC12CTL0 |= ENC;                          
}
///////////////////////////////////////////////////////////////////////////////
                  //延时
/////////////////////////////////////////////////////////////////////////////// 
void  delay(unsigned int timer)     
{
    unsigned int i;
    for(i=timer;i>0;i--)
    {     
         _NOP();
    }
} 
///////////////////////////////////////////////////////////////////////////////
                //AD SAMPLE
///////////////////////////////////////////////////////////////////////////////
interrupt [0x0E] void ADC_INT(void)
{   
       SAMPLEVALUE=ADC12MEM0;
       SAMPFLAG=1;
       ADC12CTL0 &= ~ENC;                         //改变设置前停止AD转换    
       ADC12CTL0 |= ENC; 
       ErrCOUNT1 = 0;
} 
///////////////////////////////////////////////////////////////////////////////
                //P1口中断
///////////////////////////////////////////////////////////////////////////////
interrupt [0x08] void p1porty(void)
{      
       //Timeeventpro();
       millisecondcount=0;
       
       if(Run_Flag==0)
       {
         Run_Flag=1;
         displaybuf[12]|=0x04;
        }
        else
       {
         Run_Flag=0;
         displaybuf[12]&=0x0fb;
        }
       
       P1IFG = 0;
}           
///////////////////////////////////////////////////////////////////////////////	
		//INTERRUPT TIMERA
/////////////////////////////////////////////////////////////////////////////// 
interrupt[0x0C] void Timer_A3(void) 
{  
    disp_count1++;
    if(disp_count1>0x10)
    {
        disp_count1=0;
        disp_count++;//设置参数时闪烁
    }         
}
///////////////////////////////////////////////////////////////////////////////	
		//INTERRUPT TIMERB
///////////////////////////////////////////////////////////////////////////////                   
interrupt[0x1A] void Timer_B7(void) //1ms进一次中断 
{ 
    displaypro();//1ms显示缓冲区里的一位数据
    millisecondcount++;//毫秒计数器
  
    disp_scan++;
    
    savecount1++;//U1的记录时间间隔
    if(savecount1>=systembuf[0x11])
    {
        savecount1=0;
        if((recordflagU1==1 || recordflagU11==1)&&memoryCountU12<16)//超过报警点一后记录16个数据
        {
            CHAOXIANBUF1[0x43+4*memoryCountU12]=VOLTAGE;//测量值
            CHAOXIANBUF1[0x40+4*memoryCountU12]=(MODBUS[0x00]&0xff)*256+(MODBUS[0x01]&0xff00)/256;//月、日
            CHAOXIANBUF1[0x41+4*memoryCountU12]=(MODBUS[0x01]&0xff)*256+(MODBUS[0x02]&0xff00)/256;//时、分
            CHAOXIANBUF1[0x42+4*memoryCountU12]=(MODBUS[0x02]&0xff)*256+(int)(millisecondcount/10);//秒、毫秒
            memoryCountU12++;
        }
        else if(recordflagU1==0)//平时记录16个数据
        {
            CHAOXIANBUF1[0x03+4*memoryCountU11]=VOLTAGE;//测量值
            CHAOXIANBUF1[0x00+4*memoryCountU11]=(MODBUS[0x00]&0xff)*256+(MODBUS[0x01]&0xff00)/256;//月、日
            CHAOXIANBUF1[0x01+4*memoryCountU11]=(MODBUS[0x01]&0xff)*256+(MODBUS[0x02]&0xff00)/256;//时、分
            CHAOXIANBUF1[0x02+4*memoryCountU11]=(MODBUS[0x02]&0xff)*256+(int)(millisecondcount/10);//秒、毫秒
            memoryCountU11++;
            memoryCountU11&=0x0f;
        }
    }
    savecount2++;//U2的记录时间间隔
    
}
///////////////////////////////////////////////////////////////////////////////
             //以下为判断测量值所处的范围为超限记录做准备
///////////////////////////////////////////////////////////////////////////////
void compare(void)
{
    unsigned int temp;
    int temp1;
    temp1=VOLTAGE;
    temp1 &=0x8000;
    if( temp1==0)//正电压才做记录比较
    {
        temp=VOLTAGE;
        if(temp<systembuf[0x0f])// u<90v
        {
            warnflag=0;//报警指示灯1
            recordflagU1=0;
            recordflagU2=0;
            recordflagU3=0;
        }
        if(temp>=systembuf[0x0f]&&temp<systembuf[0x12])  //90v<u<150v
        {
            warnflag=1;//报警指示灯1亮
            recordflagU2=0;
            recordflagU3=0;
        }
        if(temp>=systembuf[0x12]&&temp<systembuf[0x15])  //150v<u<600v
        {
            warnflag=1;//报警指示灯1
            recordflagU3=0;
        }
        if(temp>=systembuf[0x15])   //u>600v
        {
            warnflag=1;//报警指示灯1
        }
        
        
        if(recordflagU1==0)//U1 超限后恢复正常   <90
        {
            if(temp>=systembuf[0x0f])
            {
                recordflagU1=1;    //启动超限计时器
                memoryCountU12=0;  //大于U1的数据存储计数器
                ttU1=0;            //=00 可以写铁电
                recordflagU2=0;
                recordflagU3=0;
                recordflagU11=1;
                recordflagU21=0;
                recordflagU31=0;
            }
        }
        else if(recordflagU2==0)//U2 超限后恢复正常  <150v
        {
            if(temp>=systembuf[0x12])
            {
                recordflagU2=1;    //启动超限计时器
                memoryCountU22=0;  //大于U2的数据存储计数器
                ttU2=0;            //=00 可以写铁电
                recordflagU1=2;
                recordflagU3=0;
                recordflagU21=1;
                recordflagU11=0;
                recordflagU31=0;
            }
        }
        else if(recordflagU3==0)//U3 超限后恢复正常  <600v
        {
            if(temp>=systembuf[0x15])
            {
                recordflagU3=1;//启动超限计时器
                memoryCountU32=0;
                ttU3=0;
                recordflagU1=3;
                recordflagU2=2;
                recordflagU31=1;
                recordflagU11=0;
                recordflagU21=0;
            }
        }
    }
    else warnflag=0;//如果为负电压,报警指示灯1熄灭
}
///////////////////////////////////////////////////////////////////////////////
              //超限存储子程序
///////////////////////////////////////////////////////////////////////////////
void overrunpro(void)
{
    unsigned char i;
    if(memoryCountU12>=16&&ttU1==0)
    {
        overflowcount++;//第几次超限变量自加
        if(overflowcount>10)overflowcount=1;
        systembuf[0x1D]=overflowcount;
        for(i=0;i<30;i++)//写超限记录的次数到铁电存储器
        {
            writc64buf[2*i]=systembuf[i]&0x00ff;
            writc64buf[2*i+1]=(systembuf[i]&0x0ff00)/256;
        }
        CRC_check=CRC16(&writc64buf[0],60); // 求校验码 
        writc64buf[60]=CRC_check&0xff;																									                
        writc64buf[61]=(CRC_check&0xff00)/256;
        c64_wrnbyt(0xa0,0x1000,62);//写铁电
        c64_rdnbyt(0xa0,0x1000,62);
        save_1(CHAOXIANBUF1,memoryCountU11);//写第一报警点超限记录的32个数据到铁电存储器
        ttU1=11;
        //recordflagU11=0;
    }
   
    if(memoryCountU32>=16&&ttU3==0)
    {
        overflowcount++;//第几次超限变量自加
        if(overflowcount>10)overflowcount=1;
        systembuf[0x1D]=overflowcount;
        for(i=0;i<30;i++)//写铁电存储器
        {
            writc64buf[2*i]=systembuf[i]&0x00ff;
            writc64buf[2*i+1]=(systembuf[i]&0x0ff00)/256;
        }
        CRC_check=CRC16(&writc64buf[0],60); // 求校验码 
        writc64buf[60]=CRC_check&0xff;																									                
        writc64buf[61]=(CRC_check&0xff00)/256;
        c64_wrnbyt(0xa0,0x1000,62);//写铁电
        c64_rdnbyt(0xa0,0x1000,62);
        save_1(CHAOXIANBUF3,memoryCountU31);//写第三报警点超限记录的32个数据到铁电存储器
        ttU3=11;
        //recordflagU31=0;
    }
}
///////////////////////////////////////////////////////////////////////////////
             //超限数据保存到铁电存储器
///////////////////////////////////////////////////////////////////////////////
void save_1(unsigned int array[128],unsigned char array_loca)
{
    unsigned char i;  
    unsigned char m;
    m=overflowcount;
    m-=1;  
    //if(overflowcount==1)
    {
        for(i=0;i<8;i++)//写铁电存储器
        {
            writc64buf[8*i]=array[4*array_loca]&0xff;
            writc64buf[8*i+1]=(array[4*array_loca]&0xff00)/256;
            writc64buf[8*i+2]=array[4*array_loca+1]&0xff;
            writc64buf[8*i+3]=(array[4*array_loca+1]&0xff00)/256;     
            writc64buf[8*i+4]=array[4*array_loca+2]&0xff;
            writc64buf[8*i+5]=(array[4*array_loca+2]&0xff00)/256;
            writc64buf[8*i+6]=array[4*array_loca+3]&0xff;
            writc64buf[8*i+7]=(array[4*array_loca+3]&0xff00)/256;                    
            //c64_wrnbyt(0xa0,0x0000,64);
            array_loca++;            
            array_loca&=0x0f;
        }
        c64_wrnbyt(0xa0,0x100*m+0x0000,64);
        for(i=0;i<8;i++)
        {
            writc64buf[8*i]=array[4*array_loca]&0xff;
            writc64buf[8*i+1]=(array[4*array_loca]&0xff00)/256;
            writc64buf[8*i+2]=array[4*array_loca+1]&0xff;
            writc64buf[8*i+3]=(array[4*array_loca+1]&0xff00)/256;     
            writc64buf[8*i+4]=array[4*array_loca+2]&0xff;
            writc64buf[8*i+5]=(array[4*array_loca+2]&0xff00)/256;
            writc64buf[8*i+6]=array[4*array_loca+3]&0xff;
            writc64buf[8*i+7]=(array[4*array_loca+3]&0xff00)/256;                    
            //c64_wrnbyt(0xa0,0x0040,64);
            array_loca++;            
            array_loca&=0x0f;
        }
        c64_wrnbyt(0xa0,0x100*m+0x0040,64);
        for(i=0;i<32;i++)
        {
            writc64buf[2*i]=array[0x40+i]&0xff;
            writc64buf[2*i+1]=(array[0x40+i]&0xff00)/256;
            //c64_wrnbyt(0xa0,0x0080,64);
        }
        c64_wrnbyt(0xa0,0x100*m+0x0080,64);
        for(i=0;i<32;i++)
        {
            writc64buf[2*i]=array[0x60+i]&0xff;
            writc64buf[2*i+1]=(array[0x60+i]&0xff00)/256;
            //c64_wrnbyt(0xa0,0x00c0,64);
        }
        c64_wrnbyt(0xa0,0x100*m+0x00c0,64);
    }
}
///////////////////////////////////////////////////////////////////////////////
             //按键扫描子程序
///////////////////////////////////////////////////////////////////////////////
void scankey(void)
{
    if((P1IN&0x40)==0x00)//有键按下
    {
        if(keypress==0)
        {
            P4OUT |= 0x01; if((P1IN&0x40)==0x40) {k1_flag=1; P4OUT &= 0xfe;}
            P4OUT |= 0x02; if((P1IN&0x40)==0x40) {k2_flag=1; P4OUT &= 0xfd;} 
            P4OUT |= 0x04; if((P1IN&0x40)==0x40) {k3_flag=1; P4OUT &= 0xfb;}
            P4OUT |= 0x08; if((P1IN&0x40)==0x40) {k4_flag=1; P4OUT &= 0xf7;} 
            keypress=1;
        }  
    }
    else
    {
        keypress=0;
    }
}
///////////////////////////////////////////////////////////////////////////////
             //按键处理子程序
///////////////////////////////////////////////////////////////////////////////
void	Keydealpro(void)
{
	unsigned int j;
	unsigned char i,n[4];
// k1_flag=1  bs    P4OUT=1
// k2_flag=2  up    P4OUT=2
// k3_flag=3  down  P4OUT=3
// k4_flag=4  st    P4OUT=4
    if((k1_flag==0) && (k2_flag==0) && (k3_flag==0) && (k4_flag==0))return;
    //if(minute_1>0x96)//按键处理后隔0.15S再进入按键处理,减少多判按键的次数
    //{
        if(lay==0&&lay0==0)//测量和显示时、分、秒
        {
            if(k1_flag)
            {
                k1_flag=0;
                lay0=0;
            }
            else if(k2_flag)
            {
                k2_flag=0;
                lay0=1;
            }
            else if(k3_flag)
            {
                k3_flag=0;
                lay0=1;

⌨️ 快捷键说明

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