因学校比赛原因接触到RFID技术,并结合STM32单片机开发一卡通系统。由于需要和RFID读写器通信,以及上位机软件通信,所以添加USART2串口,并根据RFID数据包改写中断接收协议。资料支持:《不完全手册》《中文手册》端口通用与复用,APB1外设,串口寄存器,中断配置
阶段一:demo程序功能:通过串口USART2接收数据包,并把数据再发回去。RFID型号M3650A-HA 数据包第二个数据为数据包的长度,使用str接收长度,USART_RX_STA bit15置1 表示接收结束。
上代码
void uart_init(u32 bound){ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure1; //定义数据结构体USART1 NVIC_InitTypeDef NVIC_InitStructure2; //定义数据结构体USART2 NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//将中断矢量放到Flash的0地址 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//设置优先级配置的模式,详情请阅读原材料中的文章 USART_InitStructure.USART_BaudRate = bound;//串口波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能USART1,GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); // <!-- USART2属于APB1外设 --> //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //USART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //USART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置 NVIC_InitStructure1.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority=0x01 ;//抢占优先级3 NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 0x01; //子优先级3 NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure1); //根据指定的参数初始化VIC寄存器 //Usart1 NVIC 配置 NVIC_InitStructure2.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure2.NVIC_IRQChannelPreemptionPriority=0x01 ;//抢占优先级3 NVIC_InitStructure2.NVIC_IRQChannelSubPriority = 0x00; //子优先级3 NVIC_InitStructure2.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure2); //根据指定的参数初始化VIC寄存器 //USART 初始化设置 USART_Init(USART1, &USART_InitStructure); //初始化串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART1, ENABLE); //使能串口1 //USART 初始化设置 USART_Init(USART2, &USART_InitStructure); //初始化串口1 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART2, ENABLE); //使能串口1 } #if EN_USART1_RX //如果使能了接收 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. u16 USART_RX_STA=0; //接收状态标记 u8 str=3; // <!--变量用于保存RFID通信数据包的第二个数据,为数据包的长度--> // <!--头文件声明extern u8 str;便于外部引用--> void USART2_IRQHandler(void) //串口2中断服务程序 { u8 Res; #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS. OSIntEnter(); #endif if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断 { Res =USART_ReceiveData(USART2); //读取接收到的数据 USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; USART_RX_STA++; if((USART_RX_STA&0x3FFF)==2) str = Res; if((USART_RX_STA&0X3FFF)==str) USART_RX_STA|=0x8000; } #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS. OSIntExit(); #endif } #endif ----------------------------------------------- main.c int main(void) { u8 t; u8 len=0; u8 times=0; int money=100; //<!--整形易于显示--> delay_init(); //延时函数初始化 //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2 uart_init(9600); //串口初始化为9600 LED_Init(); //初始化与LED连接的硬件接口 LCD_Init(); LCD_Clear(WHITE); POINT_COLOR=RED; LCD_ShowString(30,40,200,24,24,"Mini STM32 ^_^"); LCD_ShowString(30,70,120,24,24,"LEN:"); LCD_ShowxNum(78,70,len,2,24,0); LCD_ShowString(30,100,200,24,24,"money:"); LCD_ShowxNum(102,100,money,4,24,0); while(1) { if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度 LCD_ShowxNum(78,70,len,2,24,0); money+=100; LCD_ShowxNum(102,100,money,4,24,0); for(t=0;t<len;t++) { USART2->DR=USART_RX_BUF[t]; USART_ClearFlag(USART2,USART_FLAG_TC); //<!-- 防止第一个数据丢失,有多种方式 --> while((USART2->SR&0X40)==0);//等待发送结束 } USART_RX_STA=0; } times++; if(times%300==0) {LED0=!LED0;//闪烁LED,提示系统正在运行. } delay_ms(10); } }