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

📄 main.c

📁 《MSP430单片机常用模块与综合系统实例精讲》整书的源代码有30个
💻 C
字号:
#include <msp430xw42x.h>
#include "s3530a.h"
#include "24AA64.h"
#include "x76f100.h"
#include "scanif.h"
#include "i2c.h"
#include "lcd.h"

#define IC_READ_PASS    0x00
#define IC_WRITE_PASS   0x08
#define IC_DATA         0x00
#define K               1000

#define DAY_ADDR        0x30

void Init_Sys(void);
void alarm(void);
unsigned int WaitCounter;
unsigned int V1;
unsigned int V2;
unsigned int V3;
unsigned int V4;

int count;
//小数的第2位
int fract2;
//小数的第1位
int fract1;
//整数
int value1;
int value2;
int value3;

int count_day;

//测量标志
int scan_flag;
const unsigned char PSMCalib[] = 
{
    0x00,     
    0x00,    
    0x00,
    0x00,
};

void main(void)
{ 
    char pBuf[32];
    char pReadPassBuf[8];
    char pWritePassBuf[8];
    int ic_data;
    int scan_data;
    int old_day;
    int count_time;

    //初始化
    Init_Sys();
    //端口初始化
    P1OUT = 0x00;
    P1DIR = 0xFF;
    P2DIR = 0x7F;
    P3DIR = 0xFF; 
    P4DIR = 0xFF;
    P5DIR = 0xFF;
    P6DIR = 0xFF;
    I2C_Initial();
    
    count = 0;
    value1 = 0;
    value2 = 0;
    value3 = 0;
    fract1 = 0;
    fract2 = 0;
    scan_flag = 0;
    count_day = 0;
    old_day = 0;
    count_time = 0;
    
    //P2.7设置为SIFCLKG
    P2SEL |= BIT7;
    
    //校正DAC的门限
    SIFCalib(); 
    //初始化SCAN IF
    InitScanIF();
    
    //中断使能
    _EINT();
    
    //IC卡读密码
    readPage24AA64(IC_READ_PASS,pReadPassBuf,8);
    //IC卡写密码
    readPage24AA64(IC_WRITE_PASS,pWritePassBuf,8);
    
    for(;;)
    {
        //有数据
        if(scan_flag == 1)
        {
            scan_flag = 0;
            pBuf[0] = fract2;
            pBuf[1] = fract1;
            pBuf[2] = value1;
            pBuf[3] = value2;
            pBuf[4] = value3;
            //显示数据
            dispData(pBuf,5,0);
            
            scan_data = value3 * 10000 + value2 * 1000
              + value1 * 100 + fract2 * 10 + fract1;           
            openX76F100();
            //读出卡里的数据
            readX76F100(IC_DATA,pReadPassBuf,pBuf);
            //计算卡里的内容
            ic_data = pBuf[4] * 10000 + pBuf[3] * 1000
              + pBuf[2] * 100 + pBuf[1] * 10 + pBuf[0];
            ic_data -= scan_data;
            if(ic_data <= 10)
            {
                //小于0.1时,告警
                alarm();
                //关闭阀门,以后增加
                //退出处理
                break;
            }
            //新的数据
            pBuf[4] = ic_data / 10000;
            ic_data -= pBuf[4] * 10000;
            pBuf[3] = ic_data / 1000;
            ic_data -= pBuf[3] * 1000;
            pBuf[2] = ic_data / 100;
            ic_data -= pBuf[2] * 100;
            pBuf[1] = ic_data / 10;
            ic_data -= pBuf[1] * 10;
            pBuf[0] = ic_data;
            //写入数据
            writeX76F100(IC_DATA,pWritePassBuf,pBuf);
            closeX76F100();
            
            //以下只是演示代码
            count_time++;
            if(count_time >= 100)
            {
                count_time = 0;
                //读出时间
                I2C_Read(pBuf);
                if(pBuf[2] != old_day)
                { 
                    //新的一天
                    //往卡里写入数据
                    pBuf[3] = 0xaa;
                    pBuf[4] = fract2;
                    pBuf[5] = fract1;
                    pBuf[6] = value1;
                    pBuf[7] = value2;
                    pBuf[8] = value3;
                    pBuf[9] = 0xaa;
                    pBuf[10] = 0xaa;

                    writePage24AA64(DAY_ADDR + count_day * 32,pBuf,32);
                    count_day += 1;
                    //记录60天的数据
                    if(count_day >= 60)
                    {
                        count_day = 0;
                    }
                }
                old_day = pBuf[2];
            }
        }
    }
}
void Init_Sys(void)
{
    int i;
    //指向LCD存储器
    char *pLCD = (char *)&LCDM1;
    
    //停止看门狗
    WDTCTL = WDTPW + WDTHOLD; 
    //设置电容
    FLL_CTL0 |= XCAP10PF;    
  
    //清除LCD存储器
    for (i = 0; i < 20; i++) *pLCD++ = 0;
    
    //LCD采用4复用的模式,段为0~23
    LCDCTL = LCDSG0_3 + LCD4MUX + LCDON;
    //设置LCD频率
    BTCTL = BT_fLCD_DIV128 + BTDIV + BT_fCLK2_DIV64;  
}
void alarm(void)
{
    int i = 0;
    int j = 0;
    P1DIR |= BIT4;
    P2DIR |= BIT1;
    //SHUT管脚拉低
    P2OUT &=~BIT1;
    //发出10次单音信号
    for(i = 0;i < 10;i++)
    {
        //高电平
        P1OUT |= BIT4;
        //持续一段时间
        for(j = 100;j > 0;j--) ;
      
        //低电平
        P1OUT &= ~(BIT4);
        //持续一段时间
        for(j = 100;j > 0;j--) ;
    }
    //SHUT管脚拉高
    P2OUT |=BIT1;
}


void SIFCalib(void)
{
    int i;
    WDTCTL = WDT_ADLY_1000;
    _EINT();
    IE1 |= WDTIE;
    WaitCounter=5;
  
    //等待5秒后开始校正
    while (WaitCounter>0);  
    //看门狗禁止
    WDTCTL = WDTPW + WDTHOLD;
  
    //设置SCAN IF 通道
    P6SEL |= BIT0;
    P6SEL |= BIT1;
    //定时状态机初始化
    //DAC关闭, CA关闭, 31个SMCLK周期(为两个LC传感器延迟一点个时间)
    SIFTSM0 = 0x8800;
  
    //DAC关闭, CA关闭, 1个SMCLK,激励SIFCH.0
    SIFTSM1 = 0x000C; 
    //DAC关闭, CA关闭, 1个ACLK,SIFCH.0
    SIFTSM2 = 0x0404;
    //DAC打开, CA打开, 4个SMCLK,SIFCH.0
    SIFTSM3 = 0x1914;
    //DAC打开, CA打开, 9个SMCLK,SIFCH.0
    SIFTSM4 = 0x4114; 
    //DAC打开, CA打开, 5个SMCLK,测试,SIFCH.0
    SIFTSM5 = 0x2154;
    //DAC关闭, CA关闭, 1个SMCLK,激励SIFCH.1
    SIFTSM6 = 0x000D;
    //DAC关闭, CA关闭, 1个ACLK,SIFCH.1
    SIFTSM7 = 0x0405;
    //DAC打开, CA打开, 4个SMCLK,SIFCH.1
    SIFTSM8 = 0x1915;
    //DAC打开, CA打开, 9个SMCLK,SIFCH.1
    SIFTSM9 = 0x4115;
    //DAC打开, CA打开, 5个SMCLK,测试,SIFCH.1
    SIFTSM10= 0x2155;
    //停止
    SIFTSM11 = 0x0200; 
  
    //初始化DAC的值
    //设置SIFCH.0最大的值
    SIFDACR0 = 0x03FF;
    SIFDACR1 = 0x03FF;
    //设置SIFCH.1最大的值
    SIFDACR2 = 0x03FF;
    SIFDACR3 = 0x03FF;

    //初始化控制寄存器
    //DAC和比较器由SIFTSMx控制
    SIFCTL2 = 0x0140;
    //延迟一点时间
    for (i = 0;i <= 857;i++) ;
    //S1为SIF0OUT,S2为SIF1OUT
    SIFCTL3 = 0x4000;  
    //设置SIFCNT
    SIFCTL4 = 0x0120;
    //打开SIFCLK
    SIFCTL5 = 0x0047;
    //信号处理状态地址
    SIFPSMV = (unsigned int) &PSMCalib; 
    //SIF_EN设置为1
    SIFCTL1 |= 0x0001;
  
    // 传感器1、
    // 测试1
    while (!(SIFCTL3 & 0x01))
    {  
        for(i = 0;i <= 100;i++) ;
        SIFDACR0=SIFDACR0-1;
        SIFDACR1=SIFDACR1-1;
    }
    V1 = SIFDACR1;  
    SIFDACR0 = 0x200;
    SIFDACR1 = 0x200;  
    //测试2
    while (SIFCTL3&0x01)
    {
        for(i = 0;i <= 100;i++) ;
        SIFDACR0=SIFDACR0+1;
        SIFDACR1=SIFDACR1+1;
    }
    V2 = SIFDACR1;
  
    //平均值
    SIFDACR0 = (V2 + V1) / 2;
    SIFDACR1 = SIFDACR0;
  
    SIFDACR0 = SIFDACR0 + 30;
    SIFDACR1 = SIFDACR1 - 30;
    
    //传感器2
    //测试1
    while (!(SIFCTL3 & 0x02))
    {  
        for(i = 0;i <= 100;i++);
        SIFDACR2=SIFDACR2-1;
        SIFDACR3=SIFDACR3-1;
    }
    V1 = SIFDACR2;
  
    SIFDACR2 = 0x200;
    SIFDACR3 = 0x200;
    //测试2
    while (SIFCTL3&0x02)
    {
        for(i = 0;i <= 100;i++);
        SIFDACR2=SIFDACR2+1;
        SIFDACR3=SIFDACR3+1;
    }
    V2 = SIFDACR3;
    //平均值
    SIFDACR2 = (V2 + V1) / 2; 
    SIFDACR3 = SIFDACR2;
    
    SIFDACR2 = SIFDACR2 + 30;
    SIFDACR3 = SIFDACR3 - 30;
}

#if __VER__ < 200
    interrupt [SCANIF_VECTOR] void ISR_ScanIF(void)
#else
    #pragma vector=SCANIF_VECTOR
    __interrupt void ISR_ScanIF(void)
#endif
{
    if((SIFCTL1 & SIFIFG3) || (SIFCTL1 & SIFIFG4))
    {
        SIFCTL1 &= ~0x0060;  
        //以下代码需要调整或者重写
        //这里只是起演示作用
        count += 1;
        if(count >= K)
        {
            scan_flag = 1;
            count = 0;
            fract2 += 1;
            if(fract2 >= 10)
            {
                 fract2 = 0;
                 fract1 += 1;
                 if(fract1 >= 10)
                 {
                      fract1 = 0;
                      value1 += 1;
                      if(value1 >= 10)
                      {
                           value1 = 0;
                           value2 += 1;
                           if(value2 >= 10)
                           {
                                value2 = 0;
                                value3 += 1;
                                if(value3 >= 10)
                                {
                                     value1 = 0;
                                     value2 = 0;
                                     value3 = 0;
                                     fract1 = 0;
                                     fract2 = 0;
                                }
                           }
                      }
                 }
            }
        }
    }
}

#if __VER__ < 200
    interrupt [WDT_VECTOR] void ISR_WDT(void)
#else
    #pragma vector=WDT_VECTOR
    __interrupt void ISR_WDT(void)
#endif
{
    WaitCounter = WaitCounter - 1;
}

⌨️ 快捷键说明

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