前一段时间进行了USART2串口添加,接收协议改写的工作。这一次就可以利用之前的接收和发送代码来完成miniSTM32单片机与RFID读写器的通信,实现IC卡充值和扣费的操作。资料支持:串口通信数据的LCD显示,中断嵌套等等。
字符串显示使用 sprintf() 函数,中断嵌套修改中断优先级。
demo2功能:IC卡设置成自动返回卡号和块数据,读一次;IC卡一接触到读写器,就向读写器发送卡号和指定块数据。接收数据显示在TFTLCD上,在中断函数中,设置KEY1为加100操作,KEY0为减100操作;每一次修改数额,都将钱数刷新一次,并显示通信接收数据包。
上代码:
rfid.c
#include "rfid.h"
#include "usart.h"
#include "delay.h"
#include "lcd.h"
u16 money=0;
u8 card_id[8];
u8 Cmd_Read_money[8] = {0x01,0x08,0xA9,0x20,0x01,0x01,0x00,0x7F};
//查询命令
u8 Cmd_ADD_money[11] = {0x01,0x0B,0xA8,0x20,0x01,0x01,0x64,0x00,0x00,0x00,0x19};
//加100命令
u8 Cmd_SUB_money[11] = {0x01,0x0B,0xA7,0x20,0x01,0x01,0x64,0x00,0x00,0x00,0x16};
//减100命令
void USART2_Send_Data(u8 *buf)//发送命令函数
{
u8 i;
u8 num=buf[1];
u8 String[10];
for(i=0;i<num;i++)
{
USART2->DR=buf[i];
USART_ClearFlag(USART2,USART_FLAG_TC);
while((USART2->SR&0X40)==0);//等待发送结束
}
delay_ms(100);
money=USART_RX_BUF[5]+USART_RX_BUF[6]*256;
//两个字节的16进制,转换成10进制
LCD_ShowxNum(102,100,money,4,24,0);
sprintf((char*)String,"%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",USART_RX_BUF[0],USART_RX_BUF[1],USART_RX_BUF[2],USART_RX_BUF[3],USART_RX_BUF[4],USART_RX_BUF[5],USART_RX_BUF[6],USART_RX_BUF[7],USART_RX_BUF[8],USART_RX_BUF[9]);
//显示通信数据,sprintf转成字符串,再LCD_ShowString
LCD_ShowString(30,180,200,12,12,String);
}
void Receive_One(void)//第一次接收显示卡号,余额
{
if(count==1){
sprintf((char*)card_id,"%2X%2X%2X%2X",USART_RX_BUF[7],USART_RX_BUF[8],USART_RX_BUF[9],USART_RX_BUF[10]);
money=USART_RX_BUF[11]+USART_RX_BUF[12]*256;
}
// Read_money(Cmd_Read_money[8]);
//USART_RX_BUF[0]==4
}
exti.c
void EXTI9_5_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY0==0) {
USART2_Send_Data(Cmd_SUB_money);//减操作
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE5上的中断标志位
}
void EXTI15_10_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY1==0) {
USART2_Send_Data(Cmd_ADD_money);//加操作
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line15); //清除LINE15线路挂起位
}
main.c
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "rfid.h"
#include "exti.h"
int main(void)
{
u8 times=0;
delay_init(); //延时函数初始化
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2,已写在usart.c里。
uart_init(9600); //串口初始化为9600
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init();
EXTIX_Init();
LCD_Clear(WHITE);
POINT_COLOR=RED;
LCD_ShowString(30,40,200,24,24,"Mini STM32 ^_^");
LCD_ShowString(30,70,120,24,24,"CardID:");
LCD_ShowString(30,100,200,24,24,"money:");
LCD_ShowString(30,130,200,24,24,"count:");
while(1)
{
Receive_One();
LCD_ShowString(115,75,120,16,16,card_id);
LCD_ShowxNum(102,100,money,4,24,0);
LCD_ShowxNum(102,130,count,2,24,0);
times++;
if(times%300==0)
{ LED0=!LED0;//闪烁LED,提示系统正在运行.
times=0;
}
delay_ms(10);
}
}
这只是部分核心代码,在实际文件里,USART接收中断抢占优先级设为0x02,按键中断优先级为0x01(优先级高),这样按键中断执行不会被串口接收数据影响,不然程序会出问题,我也是尝试了多次才解决这个问题。那么到这里我们已经完成RFID钱包的大部分功能,还要加上数字键盘,实现任意输入数字充值扣费。