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

📄 射频程序.c

📁 一个基于MSP430F135单片机的热量计量表的C语言原码
💻 C
字号:
#include  <msp430x41x.h>
#include  <math.h>//C语言本身的库函数定义

#include  "main.h" //自己定义的必要的结构和变量
#include  "flash.h" //自己编写的读写flash的函数说明,可直接调用




//以下为有关外部计算函数
INT8U long2dec(INT32U d, INT32U * p);


//以下为初始化函数
void initial_port(void);//初始化端口

//以下为显示函数
void display_LCD_all_on(void);//点亮所有LCD段
void display_LCD_all_off(void);//熄灭所有LCD段
void display_flag_clear(void);//为了节约空间而用
void display_float(float QQ, INT8U pos);

//以下为主程序逻辑函数
void monitor_display(void);
void monitor_RF_data(void);

static struct BIT16_flag common_flag1={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
#define		is_one_second			common_flag1.b0
#define		is_display_now			common_flag1.b1
#define		is_RF_set_card_ok 		common_flag1.b2
#define		is_k2_key_ok 			common_flag1.b3

static struct BIT8_flag display_flag={0,0,0,0,0,0,0,0};
#define		is_display_set_card 	display_flag.b0
#define		is_display_usr_card 	display_flag.b1
#define		is_display_remain_buy_Q 	display_flag.b2

INT8U  	one_second=0;

INT8U  	LCD_buf[9];//LCD 缓存


//以下要保存
float 	buy_Q=0, remain_buy_Q=0;	//总热量,特定热量, 总流量,特定流量

	//////////////******////////////////////////////////////////////////////////////////////////////////////////
	unsigned int *counter;
	unsigned int *wait_half_counter;
	unsigned int *rf_flag_byte;
	INT16U rf_capture_data[14];
	INT8U  aor_address_byte;
	INT8U  rf_counter;
	INT16U address_R4;
	INT16U com_data_R5;
	INT16U com_data_R6;
	INT16U com_data_R7;//only for RF_protect_write
	INT16U com_data_R8;//only for RF_protect_write
	INT16U bit_counter_R7;
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	static struct BIT8_flag RF_flag={0,0,0,0,0,0,0,0};//需要保存
	#define	is_RF_key_ok 	RF_flag.b0          //RF键
	
	INT8U	is_RF_data_ok;        //若为1则有数据,否则没有数据	
	INT16U sec_code[2] = {0x6666, 0x6666};//密码
	void monitor_RF(void);//对RF进行监控
	extern void RF_read(void);
	extern void RF_card_initial(void);
	//将数据放在com_data_R5, com_data_R6, address_R4 后再调用该函数
	extern void RF_standard_write(void);//注一定要注意 address_R4 的写法:比如要往block2写,则address_R4=0x2000
	extern void RF_protect_write(void);//com_data_R5, com_data_R6--密码;com_data_R7, com_data_R8--数据;address_R4--地址
	extern void RF_aor_mode(void);//com_data_R5, com_data_R6--密码;
	///////////******************************//////////////////////////////////////////////////////////////////////////////////

//主函数
void main(void)
{	
	initial_port();
	_EINT();
	display_LCD_all_off();
		
	while(1){
		monitor_RF_data();
		monitor_display();
		LPM3;		
  	}
}


//32位无符号转换为BCD码,如:0xbc614e(12345678)->0x12345678
//返回字符数
INT8U long2dec(INT32U d, INT32U * p) {
	INT8U i=0, len=0;
  	INT32U temp=0;
  	
  	do {
    	temp<<=4;
    	temp |= (INT32U) (d % 10);
    	d= d / 10;
    	len++;
  	} while(d!=0);

  	(*p) =0;
  	for(i=0;i<len;i++)
  	{
  		(*p) <<=4;
  		(*p) |= (temp&0x0000000f);
  		temp >>=4;
  	}
  	
  	return len;
}

//功能:对RF数据进行处理
//描述:无
//参数:无
//返回:无
void monitor_RF_data(void)
{
	INT16U RF_card_type;
	INT16U data_16[2];
	float *ptr_float, data_float;
	
	if(is_RF_key_ok){ //有RF卡插入
		is_RF_key_ok=0;
		
		//打开电源
		P1OUT |= BIT3;
		
		RF_card_initial();
		
		
		//以下代码为标准写
		
		_DINT();
		com_data_R5 = 0x0008;//若是新卡则,则将卡设成密码方式,对有密码的卡无效
		com_data_R6 = 0x82f8;
		address_R4  = 0x0000;
		RF_standard_write();
		_EINT();	
		
		_DINT();
		com_data_R5=0x1221;
		com_data_R6=0x1331;
		com_data_R7=0x0008;//only for RF_protect_write
		com_data_R8=0x80e8;//only for RF_protect_write
		address_R4=0x0000;
		RF_protect_write();
		_EINT();
		
		RF_card_initial();
		
		_DINT();
		RF_read();
		_EINT();
		
		if(is_RF_data_ok==0x01) goto pp1;
		
		_DINT();
		com_data_R5=sec_code[0];
		com_data_R6=sec_code[1];
		com_data_R7=0x0008;//only for RF_protect_write
		com_data_R8=0x80e8;//only for RF_protect_write
		address_R4=0x0000;
		RF_protect_write();
		_EINT();
		
		RF_card_initial();
			
		_DINT();
		RF_read();
		_EINT();		
pp1:
		_DINT();
		com_data_R5 = 0x0008;//若是新卡则,则将卡设成密码方式,对有密码的卡无效
		com_data_R6 = 0x82f8;
		address_R4  = 0x0000;
		RF_standard_write();
		_EINT();	
		
		P1OUT &= ~(BIT1+BIT3);
		P1SEL &= ~BIT1;
	}
	
	//block1--卡型以及卡号
	if(is_RF_data_ok==0x01)
	{
		is_RF_data_ok=0;
		RF_card_type = rf_capture_data[0]&0xff00;//RF卡类型		
	
		if(RF_card_type==0x0100)//设置卡
		{				
			//处理block6--该表的RF密码
			sec_code[0] = rf_capture_data[10]; sec_code[1] = rf_capture_data[11];				
			
			is_RF_set_card_ok=1;//已经插过卡了
			display_flag_clear();
			is_display_set_card=1;
		}
		else if(RF_card_type==0x0200)//用户卡
		{
			if(is_RF_set_card_ok==1)//设置卡设置后才能用
			{
				//if((rf_capture_data[9] & 0x0001)==0x0000)//此卡没有用过,新卡
				//{					
					data_16[0] = rf_capture_data[5]; data_16[1] = rf_capture_data[4];				
					ptr_float = (float*) &data_16[0];
					data_float = *ptr_float;
					remain_buy_Q += data_float;//剩余量
					if(remain_buy_Q>=99999) remain_buy_Q=0;
					
					display_flag_clear();
					is_display_remain_buy_Q=1;						
			}
		}
	}
}

void display_flag_clear(void)
{
	INT8U * ptr_INT8U;
	
	ptr_INT8U = (INT8U*) &display_flag;
	*ptr_INT8U = 0;
	display_LCD_all_off();
	
	is_display_now=1;
}


void monitor_display(void)
{
	
	if(is_display_remain_buy_Q)
	{
		display_float(remain_buy_Q, 3);
	}
	
	if(is_display_set_card)
	{
		LCD_buf[6] = 0x0c;//'c'
		LCD_buf[7] = 1;//'1'
	}
	if(is_display_usr_card)
	{
		LCD_buf[6] = 0x0c;//'c'
		LCD_buf[7] = 2;//'1'
	}	
}


void display_float(float QQ, INT8U pos)//显示pos=2,3,4位小数点
{
	INT32U temp=0, temp2=0;
	INT8U i=0, len;
	INT8U pp=2;
	
	pp= pos;
	if(pos==2)
	{
		temp2 = (INT32U) (QQ*100);
		if(QQ>=0.01) goto display_1;
		else goto display_2;
	}
	if(pos==3)
	{
		temp2 = (INT32U) (QQ*1000);
		if(QQ>=0.001) goto display_1;
		else goto display_2;
	}
	if(pos==4)
	{
		temp2 = (INT32U) (QQ*10000);
		if(QQ>=0.0001) goto display_1;
		else goto display_2;
	}
	if(pos==5)
	{
		temp2 = (INT32U) (QQ*100000);
		if(QQ>=0.00001) goto display_1;
		else goto display_2;
	}
display_1:
		len = long2dec(temp2, &temp);
		if(len<=pp)//处理小数点
		{
			for(i=0;i<len;i++)
			{
				LCD_buf[7-i] = (temp&0x0000000f);
				temp>>=4;
			}
			for(i=0;i<=pp-len;i++)
			{
				LCD_buf[7-pp+i] = 0;
			}		
			for(i=0;i<=6-pp;i++)
			{
				LCD_buf[i]=16;
			}
		}
		else
		{			
			for(i=0;i<len;i++)
			{
				LCD_buf[7-i] = (temp&0x0000000f);
				temp>>=4;
			}
			for(i=0;i<(7-len);i++)
			{
				LCD_buf[i]=16;
			}
		}
		goto display_3;
display_2:
	//显示0
	for(i=0;i<=6;i++)	
	{
		LCD_buf[i] = 16;
	}
	LCD_buf[7] =0;
display_3:
    _NOP();
}


//功能:点亮所有LCD段
//描述:无
//参数:无
//返回:无
void display_LCD_all_on(void)
{
	INT8U i;
	for(i=0;i<=9;i++){//全部点亮LCD段
		LCD_buf[i] = 18;
		LCDMEM[i] |= 0xff;
	}	
}

//功能:熄灭所有LCD段
//描述:无
//参数:无
//返回:无
void display_LCD_all_off(void)
{
	INT8U i;
	for(i=0;i<=9;i++){//全部熄灭LCD段
		LCDMEM[i] = 0;
		LCD_buf[i] = 16;
	}
}




//功能:初始化有关端口
//描述:对有关端口进行设置
//参数:无
//返回:无
void initial_port(void){
	//以下为看门狗定义
	WDTCTL = WDTPW + WDTHOLD;    // Stop WDT
  	
  	//以下为口定义
  	P1DIR |= BIT3;//rf power
  	P1OUT &= ~BIT3;
  	
  	P1IES |= BIT4;//P1.4-RF干簧管,下降沿触发
  	P1IE  |= BIT4;
  	  	
  	BTCTL = BTFRFQ0 + BTSSEL+BTDIV +BTIP1;  //每1秒中断16次,只作为时钟用
	IE2 |= BTIE;              // Enable BT interrupt

	LCDCTL = LCDON + LCD4MUX + LCDSG0_2;   // STK LCD 4Mux, S0-S19
  	  	
	P2SEL |= (BIT6+BIT7);
	P3SEL =0xff;
  	P4SEL =0xff;
  	P5SEL =0xff;
  	
}



#pragma vector=BASICTIMER_VECTOR
__interrupt void INT_timer_basic(void)
{
	INT8U i;
		
	one_second++;
	if(one_second>=16){
		one_second=0;
		is_one_second=1;
	}
	
	for(i=0;i<8;i++){//如果真值表不合理比如数字的一部分在LCDMEM[1]上,另一部分在LCDMEM[2]上
					   //则需要建digit1[], digit2[]两个表,然后LCDMEM[i]   = digit1[LCD_buf[i]];
					   //								      LCDMEM[i+1] = digit2[LCD_buf[i]];
		LCDMEM[i] = digit[LCD_buf[i]];//只管显示数字			
	}
	
	
	
	if(is_display_remain_buy_Q)
	{
		if(remain_buy_Q>=0.001) point3; //显示小数点
		LCDMEM[8] |= (P6+P4);//显示剩余符号,显示热量符号		
		LCDMEM[9] |= S5;//显示KWh符号
	}	
	

	if(is_display_now){
		is_display_now=0;
		LCDCTL |= LCDON;
	}
	
	LPM3_EXIT;
}

#pragma vector=PORT1_VECTOR
__interrupt void INT_port1(void){
    	
	  	if(P1IFG & BIT4) {//P1.4
	    	is_RF_key_ok=1;//RF卡插入
	  	}
	
  	P1IFG=0;
  	LPM3_EXIT;
}


⌨️ 快捷键说明

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