[STM32F4] 【Nucleo设计分享】一种新型泊车计费系统的设计

[复制链接]
2001|8
聿怀嘿嘿 发表于 2015-2-26 18:58 | 显示全部楼层 |阅读模式
本帖最后由 聿怀嘿嘿 于 2015-2-26 18:58 编辑



1.目的
       近年来,随着人们生活水平的提高以及我国城镇化进程的加快,我国机动车的保有量急剧上升,但停车位的规划却相对落后,停车难问题逐渐呈。
2.基本思路
       停车问题日益突出,某些车主因为一时找不到车位,贪图方便等原因路边随便停放车辆,造成马路秩序的混乱,对此某些城市根据路段的实际情况,在城市的若干道路两旁设立的咪表停车位,来缓解停车难问题。然而,在某些停车需求较大的区域停车,往往需要花费一定的时间来寻找空闲车位。对此,提出了一种新型的泊车计费系统的设计。
QQ截图20150224165907.bmp
    该设计采用RFID射频识别技术,识别泊车系统的一卡通,方式持有城市一卡通的用户,均可在此泊车系统内停车,车辆信息,卡内余额通过加密后存放在一卡通的某个块中,出入匝时,通过RFID识别读取,并通过stm32的rtc模块来计时扣费写卡,并将所有信息显示在TFT液晶上。于此同时每一个装有该泊车系统的停车场地均可通过联网,将停车场地的实时信息上传云平台。在停车场地的液晶显示屏上显示空闲车位。急需寻找停车场地的车主也可以通过web或者手机app来查询附近哪些停车场地有空闲车位,这将会大大方便车主,并减少城市随地停车的现象。

3.实现功能

智能一卡通识别
停车场地一体化
收费标准可调整
TFT显示车辆缴费信息
TFT显示空闲车位
TFT滚动显示当前日期
联网同步
手机APP实时查询
WEB平台实时查询
4.效果图片
IMG_20150226_143402.jpg
待机页面显示当前空闲车位、并在屏幕上方滚动显示日期、广告等信息
IMG_20150226_143506.jpg
IMG_20150226_143511.jpg
刷卡扣费页面
IMG_20150226_143539.jpg
通过yeelink平台web查询显示当前空闲车位
QQ截图20150226175845.bmp
5.程序
应用主程序:
  1. void App_main(void)   
  2. {
  3.   ili_LCD_Init();        //初始化屏幕
  4.   InitializeSystem();  //初始化RFID
  5.   rtcinit();                //初始化RTC
  6.   USART1_Config();
  7.   tft();
  8.   while(1)
  9.   {
  10.     Delay_ms(200);
  11.     findreadcard();      //读卡
  12.     rtctimeshow();     
  13.     GD_app();
  14.     if(tftsta==1)
  15.     {
  16.     tft();
  17.     texttft();
  18.     tftsta=0;
  19.     }  
  20.     if(rwcard==1)
  21.     {
  22.      if(UserBUffer[9]==0)  //Èë
  23.      {
  24.        UserBUffer[9]=1;
  25.        if(PcdWrite(arr,&UserBUffer[0])) //дʧ°Ü
  26.        {
  27.           if(PcdWrite(arr,&UserBUffer[0]))
  28.           {errortft();}      
  29.           else
  30.           {readtftin(); carnum--;}
  31.        }
  32.        else
  33.        {
  34.         readtftin();
  35.         carnum--;
  36.         
  37.        }
  38.      }
  39.      else {
  40.        UserBUffer[9]=0;   
  41.        carvalue=carvalue-payvalue;
  42.        UserBUffer[10]=carvalue%255;
  43.        UserBUffer[11]=carvalue/255;
  44.        if(PcdWrite(arr,&UserBUffer[0])) //дʧ°Ü
  45.        {
  46.         if(PcdWrite(arr,&UserBUffer[0]))
  47.         {errortft();}
  48.         else
  49.         {readtftout(); carnum++;}
  50.        }
  51.        else                              //д³É¹¦
  52.        {
  53.         readtftout();
  54.         carnum++;
  55.        }
  56.      }
  57.      tftsta=2;
  58.      rwcard=2;
  59.   } }}
寻卡验证密码:
  1. u8 findreadcard(void)
  2. {
  3.    u8 state=0;
  4.    
  5.    state = PcdRequest(0x26,&RevBuffer[0]);
  6.    if(state!=MI_OK)
  7.    {
  8.    state=PcdRequest(0x26,&RevBuffer[0]);
  9.     if(state!=MI_OK)
  10.     { rwcard=0;
  11.       if(tftsta==2) tftsta=1;
  12.       return 0xb1;}
  13.     }
  14.    
  15.    state = PcdAnticoll(&RevBuffer[2]);
  16.    if(state!=MI_OK)  return 0xb2;
  17.    
  18.    memcpy(MLastSelectedSnr,&RevBuffer[2],4);
  19.    
  20.    state=PcdSelect(MLastSelectedSnr);
  21.    if(state!=MI_OK)  return 0xb3;
  22.    
  23.    state=PcdAuthState(0x60,arr,PassWd,MLastSelectedSnr);
  24.    if(state!=MI_OK)
  25.    {
  26.    state=PcdAuthState(0x60,arr,PassWd,MLastSelectedSnr);
  27.    if(state!=MI_OK)  return 0xb4;
  28.    }      
  29.    if(rwcard==0)
  30.    {      
  31.            state=PcdRead(arr,&RevBuffer[0]);
  32.            if(state!=MI_OK)
  33.            {
  34.            state=PcdRead(arr,&RevBuffer[0]);
  35.            if(state!=MI_OK) {state=0xa1;}   
  36.            }
  37.            if(state==MI_OK)
  38.            {
  39.            memcpy(UserBUffer,&RevBuffer[0],16);
  40.            memcpy(UID,&UserBUffer[3],6);
  41.            carvalue=UserBUffer[10]+UserBUffer[11]*255;
  42.            rwcard=1;
  43.            }           
  44.    }
  45.    return state;
  46. }
配置RTC:
  1. void rtcinit(void)
  2. {
  3.   RTC_InitTypeDef  RTC_InitStructure;
  4.   RTC_TimeTypeDef  RTC_TimeStructure;
  5.   RTC_DateTypeDef   RTC_DateStructure;  
  6.    /* Enable the PWR clock */
  7.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  8.   /* Allow access to RTC */
  9.   PWR_BackupAccessCmd(ENABLE);
  10.    
  11.   /* Reset RTC Domain */
  12.   RCC_BackupResetCmd(ENABLE);
  13.   RCC_BackupResetCmd(DISABLE);

  14.   /* Enable the LSE OSC */
  15.   RCC_LSEConfig(RCC_LSE_ON);

  16.   /* Wait till LSE is ready */  
  17.   while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  18.   {
  19.   }

  20.   /* Select the RTC Clock Source */
  21.   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  22.   /* Enable the RTC Clock */
  23.   RCC_RTCCLKCmd(ENABLE);

  24.   /* Wait for RTC APB registers synchronisation */
  25.   RTC_WaitForSynchro();
  26.   
  27.   /* Configure the RTC data register and RTC prescaler */
  28.   /* ck_spre(1Hz) = RTCCLK(LSI) /(AsynchPrediv + 1)*(SynchPrediv + 1)*/
  29.   RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
  30.   RTC_InitStructure.RTC_SynchPrediv  = 0x30;
  31.   RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
  32.   RTC_Init(&RTC_InitStructure);
  33.   
  34.   /* Set the time to 00h 00mn 00s AM */
  35.   RTC_TimeStructure.RTC_H12     = RTC_H12_AM;
  36.   RTC_TimeStructure.RTC_Hours   = 18;
  37.   RTC_TimeStructure.RTC_Minutes = 2;
  38.   RTC_TimeStructure.RTC_Seconds = 0;  
  39.   RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure);
  40.   
  41.     /* Set the Date */
  42.   RTC_DateStructure.RTC_Month = RTC_Month_February;
  43.   RTC_DateStructure.RTC_Date = 26;  
  44.   RTC_DateStructure.RTC_Year = 15;
  45.   RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Thursday;
  46.   RTC_SetDate(RTC_Format_BIN, &RTC_DateStructure);
  47. }
显示时间:
  1. void rtctimeshow(void)
  2. {
  3.     RTC_TimeTypeDef  RTC_TimeStructure;
  4.     u8 timetemp[5];
  5.     RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
  6.    
  7.     timetemp[2]=':';
  8.     timetemp[0]=RTC_TimeStructure.RTC_Hours/10+0x30;   
  9.     timetemp[1]=RTC_TimeStructure.RTC_Hours%10+0x30;
  10.     timetemp[3]=RTC_TimeStructure.RTC_Minutes/10+0x30;
  11.     timetemp[4]=RTC_TimeStructure.RTC_Minutes%10+0x30;
  12.    
  13.     LCD_Fill(180,300,220,316,BLACK);
  14.     Show_Str(180,300,RED,BLACK,timetemp,16,1);
  15. }
显示滚动信息:
  1. void GD_app(void)
  2. {
  3. u8 gdapp_temp[50];
  4. RTC_DateTypeDef   RTC_DateStructure;
  5. RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);   
  6. sprintf((char *)gdapp_temp,"今天是20%01d%01d年%01d%01d月%01d%01d日",RTC_DateStructure.RTC_Year/10,
  7.                                                                     RTC_DateStructure.RTC_Year%10,
  8.                                                                     RTC_DateStructure.RTC_Month/10,
  9.                                                                     RTC_DateStructure.RTC_Month%10,
  10.                                                                     RTC_DateStructure.RTC_Date/10,
  11.                                                                     RTC_DateStructure.RTC_Date%10);
  12. Show_StrGD(RED,BLACK,gdapp_temp);  
  13. }
void Show_StrGD(u16 fc, u16 bc, u8 *str)实现信息的滚动播放、入口参赛fc为字体颜色,bc为背景颜色,str为显示字符串;
  1. int16_t GD_x=232,GD_y=13;
  2. void Show_StrGD(u16 fc, u16 bc, u8 *str)
  3. {        int16_t  x=GD_x;
  4.     int16_t  y=GD_y;   
  5.     int16_t  x0,x1,x11;
  6.     u16 y0,y1;
  7.     u8 pos,t,num,temp;
  8.         u16 colortemp=POINT_COLOR;      
  9.           u8 bHz=0,    //字符或者中文
  10.        size=16;
  11.     u8 i,j;
  12.         u16 k;
  13.         u16 HZnum;
  14.     HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);        //自动统计汉字数目
  15.     LCD_Fill(0,10,240,32,bc);
  16.     LCD_DrawLine(50, 10, 190, 10);
  17.     LCD_DrawLine(50, 32, 190, 32);
  18.     while(*str!=0)//数据未结束
  19.     {
  20.         if(!bHz)
  21.         {
  22.                 if(*str>0x80)bHz=1;//中文
  23.                 else              //字符
  24.                 {
  25.              x0=x;y0=y;               
  26.                  num=*str-' ';//得到偏移后的值
  27.             for(pos=0;pos<size;pos++)
  28.                     {
  29.                          temp=asc2_1608[num][pos];                 //调用1608字体
  30.                          for(t=0;t<size/2;t++)
  31.                      {                  
  32.                                 POINT_COLOR=fc;   
  33.                 if( ((x0+t)<(lcddev.width-size/2)) && ((x0+t)>size/2) )   
  34.                 {                    
  35.                         if(temp&0x01)ili_LCD_DrawPoint(x0+t,y0+pos);//画一个点   
  36.                 }   
  37.                         temp>>=1;   
  38.              }
  39.                      }
  40.                                         x+=size/2; //字符,为全字的一半
  41.                                     str++;      
  42.                 }
  43.         }else//中文
  44.         {           
  45.             bHz=0;//有汉字库   
  46.                         x1=x;y1=y;
  47.             x11=x1;
  48.                 for (k=0;k<HZnum;k++)
  49.                 {
  50.                   if ((tfont16[k].Index[0]==*(str))&&(tfont16[k].Index[1]==*(str+1)))
  51.                   {         
  52.                         for(i=0;i<16*2;i++)
  53.                         {
  54.                                   for(j=0;j<8;j++)
  55.                              {   
  56.                                           POINT_COLOR=fc;
  57.                       if( ((x1)<(lcddev.width-size/2)) && ((x1)>size/2) )
  58.                      {
  59.                                           if(tfont16[k].Msk[i]&(0x80>>j))        ili_LCD_DrawPoint(x1,y1);//画一个点
  60.                      }
  61.                                           x1++;
  62.                                           if((x1-x11)==16)
  63.                                           {
  64.                         x1=x11;
  65.                                                 y1++;
  66.                                                 break;
  67.                                           }
  68.                              }
  69.                                 }        
  70.                           }
  71.               continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  72.                     }                                          
  73.                
  74.         str+=2;
  75.             x+=size;//下一个汉字偏移            
  76.     }                                                
  77.     }
  78.   POINT_COLOR=colortemp;
  79.   GD_x-=3;
  80.   if(GD_x<(-100))
  81.   {GD_x=232;
  82.   }      
  83. }
下面的程序用来构造一个报文来与云平台(YEELINK)同步信息
  1. sprintf((char *)postCAR,    "POST /v1.0/device/xxxxx/sensor/xxxxx/datapoints HTTP/1.1\r\n"
  2.                             "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\n"   
  3.                             "Host: api.yeelink.net\r\n"
  4.                             "Accept: */*\r\n"
  5.                             "U-ApiKey:xxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"
  6.                             "Content-Length: 12\r\n"
  7.                             "Content-Type: application/x-www-form-urlencoded\r\n"
  8.                             "{"value":%02d}\r\n",num);
下面是工程文件
STM32.zip (830.49 KB, 下载次数: 14)
       接下来的工作是不断完善功能、改善显示界面的友好度。
最后要感谢21ic和st公司以及小跑堂、小管家哈哈、幸苦了!

王栋春 发表于 2015-2-26 19:41 | 显示全部楼层
资料不错呀,看来楼主是软件高手呀
mmuuss586 发表于 2015-2-26 20:27 | 显示全部楼层

不错;
powerful1 发表于 2015-2-26 22:03 | 显示全部楼层
有模块图,也有代码,讲的很详细
vigous1 发表于 2015-2-26 22:40 | 显示全部楼层
资料不错,值得好好借鉴学习
搞IT的 发表于 2015-2-28 18:31 | 显示全部楼层
有硬件电路分享吗??
aliceqiulijun 发表于 2015-4-21 09:41 | 显示全部楼层
看起来好强大
benbpig 发表于 2015-4-21 09:44 | 显示全部楼层
代码都码完了?!
lsdavid 发表于 2015-4-22 14:17 | 显示全部楼层
代码就只有贴出来的这些?!:L
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

451

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部