📄 msp430fwc.c
字号:
/****2003.1.12编写************************************************************/
/***采用MSP430F147(现在临时用MSP430F149)*************************************/
/***FLASH的最后4个存储段用作远程升级的程序和中断向量的存储区********************/
/***后面的存储区分成两份,一份作主程序存储区,另一份作为升级时的 备份程序*********/
/*******************************************************************************/
/*****24C64地址安排如下*********************************************************/
//0X0000-0X003F 64个字节作为一些杂项的存储例如存储单元的个数、地址码、通信信道等
//0X0000-0X0001------表示现在存储单元的个数(每10个字节为1个存储单元)
//OX0002 ------等于0X55表示无线模块已经初始化了,否则没有初始化过
//0X0003 ------表示当前设备的信道 1表示信道1,2表示信道2......
//0X0004 ------表示当前设备的地址
//0X0005 ------表示当前设备功能的代码
//0X0006 ------表示当前设备功能的代码的编号,可能是1,2,3等,可能存在几项相同的测试项目
//0X0040-0X1FFF作为存储每项单元的存储区(每12个字节为1个存储单元可以存储677组数据)
/****************显示字符含义***************************************************/
//---1显示---1表示正在进行写地址操作
//---2显示---2表示正在进行写无线模块的信道
//---3显示---3表示清除存储器的全部数据
//---4显示---4表示清除存储器的全部数据
//---5显示---5表示向上位机发送存储器的全部数据
//---6
//---7显示---7表示接收错误
//---8显示---8表示将以前的数据覆盖完毕
#include <msp430x14x.h>
#define uchar unsigned char
#define uint unsigned int
#define ICID_W 0xa0 /*写卡器件地址*/
#define ICID_R 0xa1 /*读卡器件地址 */
#define IC_ID_W 0xa2 /*写器件地址*/
#define IC_ID_R 0xa3 /*读器件地址 */
#define SDA430 0X04 //SDA为P3.2
#define SCL430 0X08 //SCL为P3.3
#define SDA64 0X01 //SDA为P4.0
#define SCL64 0X02 //SCL为P4.1
////////////////////////////////////////
#define FYS_save0 0x17
#define FYS_save1 0x18
#define FYS_flag 0x69
#define NUM0 0x00
#define NUM1 0x01
#define PASS0 0x7c
#define PASS1 0x7d
#define SEX 0x7e
#define AGE 0x7f /*内部资源*/
////////////////////////////////////////
void HEX_BCD(unsigned long dd); //16进制数转换10进制数
void ycsjre64(void);
void wxmkcsh(void); //初始化
void sound_s(void);
void sound_star(void); //声音
uchar re1byte(uint addr);
void wr1byte(uint addr,uchar shu);
uchar IC_read(uchar address); //从24c02的地址address中读取一个字节数据
void IC_write(uchar address,uchar info); //向24c02的address地址中写入一字节数据info
void delay1(uchar x); //延时2402
void nop(); //延时
void start(); //24c02起始位
void stop(); //24c02停止位
void writex(uchar j); //写卡
uchar readx(); //读卡
void clock(); //24c02 时钟
void readicid(void); /*************读取卡号****************/
void r232cl(void);
void csszjc(const uchar * data);
void ycsj(void) @ "MYLOATION";
void flashmain(void) @ "MYLOATION";
void flashmaintry(void) @ "MYLOATION";
void delay(uint time) @ "MYLOATION";
void disp_lcd(uchar d1,uchar d2,uchar d3,uchar d4,uchar dot) @ "MYLOATION"; //显示 电源 数据 地 时钟
void flashmaintry(void) @ "MYLOATION"; //延时
void rxdatatry(void) @ "MYLOATION";
void rxdata(void) @ "MYLOATION";
void txready(void) @ "MYLOATION";
void eraseseg(uchar n) @ "MYLOATION";
void flashfinish(void) @ "MYLOATION";
void flashcsh(void) @ "MYLOATION";
void checkcard(void);
void xsjg(void);
void init(void);
void jcqy(void);
//sbit key = P1^4; //按键
//sbit data_selet = P3^0; //数据采集
/*sbit sound = P1^4;
sbit scl = P1^7;
sbit sda = P1^6;
sbit card_sw = P1^5;*/
//sbit card_pow = P1^5;
/*sbit incard_led = P3^4; //请插卡
sbit prep_led = P3^5; //准备测试
sbit test_led = P3^6; //测试中
sbit testend_led = P3^7; //测试结束
sbit input1_p = P3^2; //光电管位置 左上右下
sbit input2_p = P3^3;*/
//sbit disp_1 = P1^0; //LED_1
//sbit disp_2 = P1^1; //LED_2
//sbit disp_3 = P1^2; //LED_3
//sbit disp_4 = P1^3;
/*sbit clk = P1^0;
sbit dat = P1^1;*/
//LED_4
uchar disp1,disp2,disp3,subf,repeatestf; //显示缓存
uchar IC_error,testnum,jishi1,dotime = 0;
//bit int0f,int1f,timeoverf;
volatile uchar FLAG; //flag.6对应int0f,flag.7对应int1f,flag.5对应对应timeoverf,flag.4对应firstnum
//flag.3对应在测插卡的状态
//FLAG.0表示无线模块串口处于正常接收状态
//FLAG.1表示无线模块串口处于设置检查状态
//FLAG.2表示无线模块串口处于远程升级状态
const uchar ledtab[15] = {0x88,0xBB,0xC1,0x91,0xB2,0x94,0x84,0xB9,0x80,0x90,0xA0,0xA8,0xC4,0xf7,0xff};
//0 1 2 3 4 5 6 7 8 9 A N E -
const uchar leddottab[11]={0x08,0x3b,0x41,0x11,0x32,0x14,0x04,0x39,0x00,0x10,0x7f};
// 0 1 2 3 4 5 6 7 8 9
const uchar rsbaud[]={'R','S','B','A','U','D',':','9','6','0','0','N',0X0D,0X0A,'\0'}; //设置RSBAUD:9600N
const uchar rfbaud[]={'R','F','B','A','U','D',':','1','9','2','0','0',0X0D,0X0A,'\0'}; //设置RFBAUD:19200
const uchar ch[]={'C','H',':','\0'};
uchar BCD[8]; //
uint disp_dat;
uint tljish,resultnum,breaknum; //显示暂存
//signed long tljish;
uchar cl;
uchar bl;
/*uint dis[6]=0;*/
uchar a,m;
uint b,prenum;
uchar c=0;
//signed long b;
uint i = 0,j = 0;
uchar r232buf[41]; //串口通讯缓存区
uchar startjsq; //串口做为启示位定时器
uchar tempmem; //串口接收的数据临时存储器
uchar tempmem1; //作为接收发送字节数据的个数
uchar tempmem2; //作为串口的检验和存储单元
uchar tempmem3; //临时存储器
volatile uchar FLAG1; //FLAG1.0=1表示找到起始位
//FLAG1.1=1表示接收到完整的命令侦
//FLAG1.2
//FLAG1.3
//FLAG1.4
//FLAG1.5=1表示读错误
//FLAG1.6=1表示写错误
//FLAG1.7=1表示校验错误
//
volatile uchar FLAG2; //FLAG2.0=1表示有数据测试完毕,可以进行发送
//FLAG2.1=1表示正在处于设置无线信道状态,并且现处于非测试状态
//用于串口中断时判别是上位机发的还是无线模块发的数据
//FLAG2.2=1表示和无线模块通讯时传输到"friendcom....."正确
//FLAG2.3=1表示现在为空闲状态,可远程升级,写地址,写信道,读存储器器数据
//FLAG2.4=1表示没有插卡
//FLAG2.5=1表示准备测试
//FLAG2.6=1表示测试中
//FLAG2.7=1表示测试结束
volatile uchar FLAG3; //FLAG3.0=1表示上位机要写机器地址
//FLAG3.1=1表示上位机要写通讯信道
//FLAG3.2=1表示上位机要清除所有存储的测试数据
//FLAG3.3=1表示上位机要进行远程升级
//FLAG3.4=1表示上位机读取存储器的数据
//FLAG3表示的是要花费时间较长的操作标志寄存器,不要在测试中进行
volatile uchar FLAG3BAK; //作为FLAG3的备份
volatile uchar FLAG4; //FLAG4.0=1表示读当前的测试数据
//FLAG4.1=1表示读机器地址
//FLAG4.2=1表示读通讯信道
//FLAG4.3=1表示读存储器状态
volatile uchar FLAG4BAK; //作为FLAG4的备份
uchar FLASHFLAG; //FLASHFLAG.0=1表示有接收到数据
//FLASHFLAG.1=1表示上位机传输结束
uchar icidbuf[8]; //卡号存储区,存储当前的卡号
volatile uchar result[4]; //测试结果存储区,一般是两个字节,用四个字节为了兼容身高体重
//uchar flashbuf[33]; //flashbuf可以作为接收远程升级每次的接收数据,接收完毕后写入FLASH中
//flashbuf[0]作为要写入数据的第几位
uchar xmdmbuf; //项目代码缓存区
//uchar xmdmadrbuf; //项目代码地址缓存区
uchar deviceadr; //机器地址
uchar devicexd; //无线通信的信道
volatile uint at64count; //存储在6264中未发送的数据的个数
uint bytejs; //从上位机到下位机编程的字节数
uint bytejs1; //已经写入FLASH的个数
uint byteadd; //编程所有字节的累加和
volatile uint exitjsq; //在测试状态按键按下超过2秒钟则退出测试
uint lsbuf;
uchar ii;
uchar temp;
uint inti;
volatile uint txjsq;
volatile uint ywqzjsq;
volatile uchar FLAG5;
uint loatad;
uint byte32jsq; //发送32个字节进行延时
uchar xhjsq;
uint loatjsq; //欠压计数器
uint loatad;
uint loatadbuf;
void msp430csh(void) //MSP430初始化
{ uint i;
WDTCTL=WDTPW+WDTHOLD; //口令及关闭看门狗,测试用,正常时不要此句
BCSCTL1|=XTS+XT2OFF; //LFXT1工作于高频
BCSCTL2|=SELM1+SELM0; //MCLK的时钟源为SELS
P1OUT=0X01; //P1.0输出高电平
P1DIR=0X01; //P1口均为输入口,P1.0为输出口
P1OUT=0X01; //P1.0输出高电平
P2OUT=0XFF; //P2口预置为0XFF
P2DIR=0X3C; //P2口P2.2,P2.3,P2.4,P2.5为输出口
P3OUT=0XFF; //P3口预置为0XFF
P3DIR=0X5D; //P3口P3.6,P3.4,P3.3,P3.2,P3.0为输出口
P4OUT=0X7F; //P4口预置为0X7F,P4.7控制485口为接收状态
P4DIR=0XDF;
P5OUT=0Xff; //P5口预置为0XFF
P5DIR=0XFF; //P5口
P6DIR=0X00; //P6口均为输入口
IFG1 &= ~OFIFG; // Clear OSCFault flag
do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for(i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG) != 0);// OSCFault flag still set?
BCSCTL2 |= SELM1+SELM0; // MCLK = LFXT1 (safe)
UCTL0=CHAR; //设置为8位数据位,一个停止位,无校验
UTCTL0 = SSEL0; // UCLK = ACLK
UBR00 = 0xA0; // 3.58Mhz/9600 - 372
UBR10 = 0x01; // 4Mhz/9600 - 416.6666666667
UMCTL0 = 0x6B;
ME1 |= UTXE0 + URXE0; // Enable USART0 TXD/RXD
/*IE1 |= URXIE0;*/ // Enable USART0 RX interrupt
P3SEL |= 0xF0; // P3.4,5 = USART0 TXD/RXD
UCTL1=CHAR; //设置串口1为8位数据位,一个停止位,无校验
UTCTL1 = SSEL0; // UCLK = ACLK
UBR01 = 0xA0; // 3.58Mhz/9600 - 372
UBR11 = 0x01; // 4Mhz/9600 - 416.6666666667
UMCTL1 = 0x6B;
ME2 |= UTXE1 + URXE1; // Enable USART1 TXD/RXD
/*IE2 |= UTXIE1 + URXIE1;*/ // Enable USART1 RX interrupt
IE2 |= URXIE1; //开始允许接收中断
P3SEL|=0XF0; //P3.4.5.6.7为USART0和USART1
P6SEL=0X80; //选择A7为转换通道
/*ADC12CTL0 = ADC12ON+SHT0_15+REFON+REF2_5V+MSC;*/ //Turn on and set up ADC12,N=15
ADC12CTL0 = ADC12ON+SHT0_8+REFON+REF2_5V;
ADC12CTL1 = SHP+CONSEQ_0; // Use sampling timer,ADCLOCK5分频,单通道单次
ADC12MCTL0|= SREF_1+INCH_7; // Vr+=Vref+ 用第七通道
/*ADC12IE = 0x01;*/ // Enable ADC12IFG.0
ADC12CTL0 |= ENC; // Enable conversions
/*_EINT();*/ // Enable interrupts
for (i=0;i<0x3600;i++) // 延时,使基准电压稳定
{
}
ADC12CTL0 |= ADC12SC; // Start conversion
}
void init(void)
{
uchar temp1;
uchar temp2;
/*sound=0;*/
P5OUT&=~BIT7; //关闭蜂鸣器
/*incard_led = 1;*/
P5OUT&=~BIT3;
/*prep_led = 1;*/
P5OUT&=~BIT2;
/*test_led = 1;*/
P5OUT&=~BIT1;
/*testend_led = 1;*/
P5OUT&=~BIT0;
TAR=0X3caf;
TACTL = TASSEL0 + ID1; // ACLK, clear TAR 使用ACLK作为时钟源,4分屏,工作于连续计数模式
TBR=0XFC17; //1MS定时
TBCTL =TBSSEL0 + ID1 + MC1; //ACLK, clear TBR 使用ACLK作为时钟源,4分屏,工作于连续计数模式
P2IES = 0XFF; //电平从高到低触发中断
P2IFG = 0X00; //清标志位
IC_error = 0; //初始化IC卡没有问题
subf = 0xb0;
FLAG = 0X00; //初始化状态寄存器
FLAG1= 0X00;
FLAG2= 0X00;
FLAG3= 0X00;
FLAG4= 0X00;
P4OUT&=~BIT2; //将24C64的WP置低电平,取消写保护
devicexd=re1byte(0x0003); //读取无线通信信道
delay(50);
deviceadr=re1byte(0x0004); //读取该设备的地址
//deviceadr=0; //????????????????????????????????????????????????///
temp1=re1byte(0x0000);
temp2=re1byte(0x0001); //读取存储器的存储数据的个数
at64count=temp1*256+temp2; //已存储数据的个数
//at64count=500; //?????????????????????????????????????????????????
xmdmbuf=0xcc; //项目代码为俯卧撑
TBR=0XFC17; //1MS定时
//TBCCR0=0XFC17;
TBCCR0=0XFC17;
}
void jcqy(void)
{
unsigned long su=0;
loatad=0;
loatjsq=0; //欠压计数器清零
waitloop:
su=0;
for(ii=0;ii<250;ii++)
{
ADC12CTL0|=ADC12SC;
while ((ADC12IFG & ADC12BUSY)==0); // ADC12BUSY?
loatad=ADC12MEM0;
loatadbuf=loatad;
su=su+loatad;
}
loatad=su/250;
if(loatad>3270)P4OUT&=~BIT2;
else P4OUT|=BIT2;
if(loatad<3200)
{
disp_lcd(0x08,0x08,0x08,0x08,0);
sound_s();
delay(255);
delay(255);
FLAG5|=BIT4;
}
if(loatjsq>65500)
{
disp_lcd(0x0e,0x0e,0x0e,0x0e,0);
P5OUT&=~BIT7; //关闭蜂鸣器
/*incard_led = 1;*/
P5OUT&=~BIT0;
/*prep_led = 1;*/
P5OUT&=~BIT1;
/*test_led = 1;*/
P5OUT&=~BIT2;
/*testend_led = 1;*/
P5OUT&=~BIT3;
P3OUT&=~BIT0; //关断外部电源
P4OUT&=~BIT3; //关断外部电源
P4OUT&=~BIT2;
LPM4; //如果欠电超过2分钟,进入超低功耗状态
}
if(loatadbuf<3200) goto waitloop;
if((loatad>3200)&&(FLAG5&BIT4)!=0)
{
loatjsq=0; //欠压计数器清零
disp_lcd(0xd,0xd,0xd,0xd,0x0);
checkcard();
FLAG5&=~BIT4;
}
}
void xsjg(void)
{
a = IC_read(FYS_save0);
disp1 = a;
a = IC_read(FYS_save1);
disp2 = a>>4;
a = a<<4;
disp3 = a >> 4;
disp_lcd(0,disp1,disp2,disp3,0);
/*incard_led = 1;*/
//P5OUT&=~BIT0;
/*test_led = 1;*/
//P5OUT&=~BIT2;
/*incard_led = 1;*/
//P5OUT&=~BIT0;
/*testend_led = 0;*/
//P5OUT|=BIT3;
///P5OUT&=~BIT1;
}
void main(void)
{
/*bit firstnum;*/
disp_lcd(0x08,0x08,0x08,0x08,0);
tljish = 0;
msp430csh(); //MSP430进行初始化
P5OUT&=~BIT7; //关闭蜂鸣器
wxmkcsh();
init(); //外部初始化
disp_lcd(0x8,0x8,0x8,0x8,0x0);
/*incard_led = 0;*/
P5OUT|=BIT3;
disp_lcd(0xd,0xd,0xd,0xd,0x0);
/////////////////////////////////////////////////////////////////////////////
IE2 &= ~UTXIE1;
ME2 |= UTXE1 + URXE1; // Enable USART1 TXD/RXD
IE2 |= URXIE1;
_EINT();
/////////////////////////////////////////////////////////////////////////////
//while(1)
//{
////while((IFG2&URXIFG1)==0); //如果没有接收到数据时,等待
////r232buf[0]=RXBUF1;
////while ((IFG2 & UTXIFG1) == 0); //USART1 TX buffer ready?
////TXBUF1=0x55;
////ycsjre64();
//IE2&=~URXIE1; //
//_DINT();
//delay(255);
//disp_lcd(0x0d,0x0d,0x0d,0x04,0); //显示---4表示清除存储器的全部数据
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -