📄 射频程序.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 + -