📄 msp430.c
字号:
//========================================================================
// MSP430F135主程序(szb,2006.1.20编写)
//========================================================================
#ifndef _MSP430
#define _MSP430
#include "datastru.h"
#include "func.h"
#endif
//-----------------------------------------------------------------------
void main(void)
{
systeminit();//系统上电初始化
BeeSoldEnable = BEESOLDCN;
BeeSing(&BeeSoldEnable,30);
while (1)
{
ScanDoor(); //扫描柜门开启事件,函数中直接包含写入FRAM过程
ScanPower();//扫描系统工作电压,堵转电压等相关电压量
if (SwitchFlag)
{
SOE_Write(SwitchNote);
SwitchFlag = OFF;
}
if (DoorFlag)
{
SOE_Write(DoorNote);
DoorFlag = OFF;
}
if (MotorRunEnable)
{
MotorRun();
//MotorRunEnable = OFF;
}
if (MotorStopEnable)
{
MotorStop();//关闭电机
MotorStopEnable = OFF;
}
if(BeeSoldEnable)
{
BeeSing(&BeeSoldEnable,BEELENGTH);//BeeSold();
}
if (BeeAlarmEnable)
{
BeeSing(&BeeAlarmEnable,BEELENGTH);//BeeAlarm();
}
COMM485(); //通信代码,去掉通信代码里的switch语句
COMM232(); //通信代码,去掉通信代码里的switch语句
WDctrl();//看门狗计数器清零 关闭内部看门狗,启用外部看门狗
}
}
void systeminit(void)
{
_DINT(); //关闭中断
sckinit();// 设置系统时钟
portsinit();//端口初始化
FramInit();//Fram初始化,采用I/O模拟模式
TAinit();//时钟初始化
TBinit();//时钟初始化
RS485comminit();// 设置波特率,输入输出端口,发送/接收寄存器
RS232comminit();// 清空232收发队列
ADC12Init ();//AD转换模块初始化
Variableinit ();
WDctrl();//看门狗计数器清零
_EINT();
}
void sckinit(void) //时钟初始化,有待进一步调整
{
unsigned int i;
WDTCTL = WDTPW + WDTHOLD; // 停止WDT
BCSCTL1 &= ~(XT2OFF + XTS + XT5V); // 启动晶振,禁止LFXT1
BCSCTL2 |= SELS + DIVS1 + DIVS0; // SMCLK = XT2,divider = 8;
BCSCTL2 |= SELM1; // MCLK = XT2
do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志位
for (i = 0xFF; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // OSCFault标志位是否置位?
}
void portsinit(void) //端口初始化
{
P1SEL = 0;
P1DIR = 0;//P1.0~P1.3作为地址输入,P1.4作为烟柜类型选择输入,P1.5作为红外传感器信号输入,
//P1.6用于门信号输入,P1.7用于电机转向信号输入
P1IE = 0x20;//允许1.5端口中断
P1IES = 0x20;//下降沿触发
P1IFG = 0;//没有待处理的中断
P2SEL = 0;
P2DIR = 0xF7;//P2.0端口用于蜂鸣器输出,P2.1端口用电机11列输出,P2.2端口用于和CPU2模拟传信通信发送,
//P2.3端口用于和CPU2模拟传信通信接收,其他端口作为电机列输出
P2OUT = 0x04;//将2.2端口电平拉高,表示没有数据
P2IE = 0x08;//允许2.3端口中断
P2IES = 0x08;//下降沿触发
P2IFG = 0;//没有待处理的中断
P3SEL = 0x30;
P3DIR = 0xDB;//P3.0用于铁电存储器片选输出,P3.1~P3.3用于和铁电存储器I/O模拟通信,P3.4~P3.5用于
//作为串行通信,P3.6作为看门狗清零信号,P3.7用于电机6列输出
P3OUT = BIT0; //禁止FRAM写入
P4SEL = 0;
P4DIR = 0xFF;//电机控制信号行列输出
P4OUT = 0;//继电器处于常开状态
P5SEL = 0;
P5DIR = 0xFF;//电机控制信号行输出
P5OUT = 0;//继电器处于常开状态
P6SEL = 0xFF;//启用该端口的AD采样功能,检测电机的工作电流和供电电压
P6DIR = 0;//作为按键的列扫描信号输出
}
void Variableinit (void) //变量初始化
{
int i;
for (i=0;i<8;i++) //初始化事件记录数组
{
SwitchNote[i] = 0;
DoorNote[i] = 0;
}
SlaveAddress = P1IN & 0x0F;//读取计数板地址(4位)
Door = OFF;//柜门数由4个变为一个
DoorNum = 0;//初始化开门计数数组
SwitchFlag = OFF;
DoorFlag = OFF;
MotorRunEnable = OFF;
MotorStopEnable = OFF;
MotorForbid = OFF;
MotorForbidNum = 125;//电机工作电压检测滤波计数
MotorStopNum = 0;//电机堵转电压检测计数
MotorRunNum = 0;//电机启动检测计数
//MotorPushNum =255;//电机正向推烟时间计数
//CBFNum=255;//确认键防抖计数
MotorStopSec=255;//电机停转时间(0.1秒)
BeeSoldEnable = OFF;
BeeAlarmEnable = OFF;
OnSaleRow = 0;//将要驱动的电机行,置为100只是将其置于一个不存在的行列,以防发生电机勿动
OnSaleCol = 0;//将要驱动的电机列
FilterEnable = OFF;//没有数据,禁止滤波
BeeNum = 0;
BeeCount = 0;
if (Clocktime[0] > 40 || Clocktime[1] > 12 || Clocktime[1] == 0 || Clocktime[2] > 31 || Clocktime[2] == 0 || Clocktime[3] > 23 || Clocktime[4] > 59 || Clocktime[5] > 59 || Clocktime[6] > 9)
{
Clocktime[0] = 7;
Clocktime[1] = 1;
Clocktime[2] = 1;
Clocktime[3] = 0;
Clocktime[4] = 0;
Clocktime[5] = 0;
Clocktime[6] = 0;
}
if (P1IN & BIT4)
{
MaxMeasure = 2200; //堵转与工作电压上限值 4000=4095*3.22/3.3
MPBoundMeasure = 780; //正转堵转电压下限值830 2000=4095*1.61/3.30
MNBoundMeasure = 750; //反转堵转电压下限值800 2000=4095*1.61/3.30
MRunMeasure = 100; //电机转动检测下限值,低于该值认为电机没有转动 2000=4095*1.61/3.30
}
else
{
MaxMeasure = 4000; //堵转与工作电压上限值 4000=4095*3.22/3.30
MPBoundMeasure = 1400; //正转堵转电压下限值1500 2000=4095*1.61/3.30
MNBoundMeasure = 1100; //反转堵转电压下限值1400 2000=4095*1.61/3.30
MRunMeasure = 200; //电机转动检测下限值,低于该值认为电机没有转动 2000=4095*1.61/3.30
}
}
void WDctrl(void)
{
if (P3OUT & BIT6)
P3OUT &= ~BIT6;
else
P3OUT |= BIT6;
}
void ScanDoor(void) //门扫描函数
{
if (Door == OFF && (P1IN & BIT6))
{
DoorNum++;
if (DoorNum >= 250)
{
Door = ON;//当柜门电平由低变高时,写入FRAM记录
DoorNote[0] = Clocktime[0];
DoorNote[1] = Clocktime[1];
DoorNote[2] = Clocktime[2];
DoorNote[3] = Clocktime[3];
DoorNote[4] = Clocktime[4];
DoorNote[5] = Clocktime[5];
DoorNote[6] = 1;
DoorNote[7] = DoorSP; //默认情况下,所有记录都是允许发送的
DoorFlag = ON;
DoorNum = 0;//清零
}
}
else if (Door == ON && !(P1IN & BIT6))
{
DoorNum++;
if (DoorNum >= 250)
{
Door = OFF;//当柜门电平由高变低时,清除开门标志
DoorNum = 0;//清零
}
}
else
DoorNum = 0;//清零
}
void ScanPower(void) //电机工作电压,堵转电压,启动电压扫描
{
if (FilterEnable == ON)
{
MotorVmid = Filter(MotorVdetect);
PowerVmid = Filter(PowerVdetect);
FilterEnable = OFF;
if ((P1IN & BIT7 && MotorVmid > MNBoundMeasure || MotorVmid > MPBoundMeasure) && MotorVmid < MaxMeasure)
{
MotorStopNum++;
if (MotorStopNum > 5000) //延时30ms左右
{
MotorStop();//堵转关闭电机
MotorStopNum = 0;
if (!(P1IN & BIT7))
{
BeeAlarmEnable = BEEALARMCN;
BeeSing(&BeeAlarmEnable,BEELENGTH/2);//BeeAlarm();
}
}
}
else
MotorStopNum = 0;
if (MotorRunEnable && MotorVmid < MRunMeasure)
{
MotorRunNum++;
if (MotorRunNum > 50)
{
MotorStop();//按下按键后,0.3ms内电机未启动则停转电机
MotorRunNum = 0;
}
}
else
MotorRunNum = 0;
/*if (MotorVmid > MRunMeasure && MotorRunEnable && !(P1IN & BIT7))
{
if(Clocktime[5] - MotorPushNum > 2 || MotorPushNum > Clocktime[5] && MotorPushNum - Clocktime[5] < 60 - 2) //现在让电机正向转动2秒后停止
MotorStop();
}*/
if (PowerVmid < MaxMeasure && PowerVmid > PBOUNDMEASURE)
{
MotorForbidNum++;
if (MotorForbidNum > 175) //延时0.3ms左右
{
MotorForbid = OFF;//电源电压恢复到正常值,电机可以启动
MotorForbidNum = 125;
}
}
else if (PowerVmid <= PBOUNDMEASURE)
{
MotorForbidNum--;
if (MotorForbidNum < 75)
{
MotorForbid = ON; //电压不足,禁止电机动作
MotorForbidNum = 125;
}
}
else
MotorForbidNum = 125;
}
}
void MotorRun(void)
{
switch (OnSaleCol)
{
case 1:
MOTORCOL1_HIGH;
break;
case 2:
MOTORCOL2_HIGH;
break;
case 3:
MOTORCOL3_HIGH;
break;
case 4:
MOTORCOL4_HIGH;
break;
case 5:
MOTORCOL5_HIGH;
break;
case 6:
MOTORCOL6_HIGH;
break;
case 7:
MOTORCOL7_HIGH;
break;
case 8:
MOTORCOL8_HIGH;
break;
case 9:
MOTORCOL9_HIGH;
break;
case 10:
MOTORCOL10_HIGH;
break;
case 11:
MOTORCOL11_HIGH;
break;
case 12:
MOTORCOL12_HIGH;
break;
default:
break;
}
switch (OnSaleRow)
{
case 1:
MOTORROW1_HIGH;
break;
case 2:
MOTORROW2_HIGH;
break;
case 3:
MOTORROW3_HIGH;
break;
case 4:
MOTORROW4_HIGH;
break;
case 5:
MOTORROW5_HIGH;
break;
case 6:
MOTORROW6_HIGH;
break;
case 7:
MOTORROW7_HIGH;
break;
case 8:
MOTORROW8_HIGH;
break;
case 9:
MOTORROW9_HIGH;
break;
case 10:
MOTORROW10_HIGH;
break;
default:
break;
}
}
void MotorStop(void)
{
MOTOR0_OFF; //分四批次将电机驱动端口电压复位,从而关闭所有电机
MOTOR1_OFF;
MOTOR2_OFF;
MOTOR3_OFF;
if (MotorRunEnable && !(P1IN & BIT7))
{
MotorStopSec = 0;
}
MotorRunEnable = OFF;
}
void BeeSing(volatile unsigned char* BeeSign,unsigned char beelength)
{
if(*BeeSign %2 == 0 && BeeCount ==0)
{
P2OUT |= BIT0; //蜂鸣器发声
BeeCount = beelength;
*BeeSign = *BeeSign - 1;
}
else if (*BeeSign % 2 == 1 && BeeCount ==0)
{
P2OUT &= ~BIT0; //蜂鸣器噤声
BeeCount = beelength;
*BeeSign = *BeeSign - 1;
}
}
unsigned int Filter (unsigned int Vcomp[3]) //电压采样滤波函数
{
if (Vcomp[0] <= Vcomp[1])
{
if (Vcomp[0] > Vcomp[2])
return Vcomp[0];
else if(Vcomp[1] <= Vcomp[2])
return Vcomp[1];
else
return Vcomp[2];
}
else
{
if (Vcomp[1] > Vcomp[2])
return Vcomp[1];
else if(Vcomp[0] <= Vcomp[2])
return Vcomp[0];
else
return Vcomp[2];
}
}
interrupt[PORT1_VECTOR] void Port1_sensor (void)
{
_DINT();
if (P1IFG & BIT5)
{
if (MotorRunEnable && !(P1IN & BIT7) || 255 != MotorStopSec)
{
SwitchNote[0] = Clocktime[0];
SwitchNote[1] = Clocktime[1];
SwitchNote[2] = Clocktime[2];
SwitchNote[3] = Clocktime[3];
SwitchNote[4] = Clocktime[4];
SwitchNote[5] = Clocktime[5];
SwitchNote[6] = OnSaleRow * KEYCOLNUM + OnSaleCol; //计数点号
SwitchNote[7] = CounterSP; //默认情况下,所有记录都是允许发送的
BeeSoldEnable = BEESOLDCN;
SwitchFlag = ON;
MotorStopEnable = ON;
MotorStopSec = 255;
}
P1IFG &= ~BIT5; //清除中断标志
}
_EINT();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -