多功能现代电子门锁

1.从代码入手,去理清楚思路

1.硬件的初始化,硬件的驱动

 1 void OLED_Init(void)
 2 {
 3     Spi2_Pin_Init( );
 4     OLED_Pin_Init( );//管脚初始化
 5     //复位
 6     OLED_RES=1;
 7   Delayms(100);
 8   OLED_RES=0;
 9   Delayms(100);
10   OLED_RES=1;
11   Delayms(100); 
12     
13   OLED_Send_Commond(0xAE); //关闭显示
14   OLED_Send_Commond(0xD5); //设置时钟分频因子,震荡频率
15   OLED_Send_Commond(80);   //[3:0],分频因子;[7:4],震荡频率
16   OLED_Send_Commond(0xA8); //设置驱动路数
17   OLED_Send_Commond(0X3F); //默认0X3F(1/64)
18   OLED_Send_Commond(0xD3); //设置显示偏移
19   OLED_Send_Commond(0X00); //默认为0
20 
21   OLED_Send_Commond(0x40); //设置显示开始行 [5:0],行数.
22 
23   OLED_Send_Commond(0x8D); //电荷泵设置
24   OLED_Send_Commond(0x14); //bit2,开启/关闭
25   OLED_Send_Commond(0x20); //设置内存地址模式
26   OLED_Send_Commond(0x02); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
27   OLED_Send_Commond(0xA1); //段重定义设置,bit0:0,0->0;1,0->127;
28   OLED_Send_Commond(0xC8); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
29   OLED_Send_Commond(0xDA); //设置COM硬件引脚配置
30   OLED_Send_Commond(0x12); //[5:4]配置
31 
32   OLED_Send_Commond(0x81); //对比度设置
33   OLED_Send_Commond(0xEF); //1~255;默认0X7F (亮度设置,越大越亮)
34   OLED_Send_Commond(0xD9); //设置预充电周期
35   OLED_Send_Commond(0xf1); //[3:0],PHASE 1;[7:4],PHASE 2;
36   OLED_Send_Commond(0xDB); //设置VCOMH 电压倍率
37   OLED_Send_Commond(0x30); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
38 
39   OLED_Send_Commond(0xA4); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
40   OLED_Send_Commond(0xA6); //设置显示方式;bit0:1,反相显示;0,正常显示
41   OLED_Send_Commond(0xAF); //开启显示
42     
43     OLED_CLear(0x00);//清屏
44 }
OLED_Init

 1 *
 2 函数功能:给OLED发送命令
 3 参数说明:待发送的命令
 4 注意事项:
 5 */
 6 void OLED_Send_Commond(u8 cmd)
 7 {
 8     OLED_DC=0;//选择发送命令
 9     OLED_CS=0;//片选
10     Spi2_Transfer_Byte(cmd);
11     OLED_CS=1;//取消片选
12 }
13 
14 /*
15 函数功能:给OLED发送显示数据
16 参数说明:待发送的显示数据
17 注意事项:
18 */
19 void OLED_Send_Data(u8 data)
20 {
21     OLED_DC=1;//选择发送显示数据
22     OLED_CS=0;//片选
23     Spi2_Transfer_Byte(data);
24     OLED_CS=1;//取消片选
25 }
26 /*
27 函数功能:主机发送一个字节给从机
28 注意事项:MODE0/3
29 */
30 u8 Spi2_Transfer_Byte(u8 data)
31 {
32     while(!(SPI2->SR&(0x01<<1)));
33     SPI2->DR=data;
34     while(!(SPI2->SR&(0x01<<0)));
35     return     SPI2->DR;
36 }
37 /*
38 函数功能:SPI2接口初始化
39 */
40 void Spi2_Pin_Init(void)
41 {
42     //IO功能配置
43     RCC->APB2ENR |=0x01<<3;
44     GPIOB->CRH &=~(0xFFF<<20);
45     GPIOB->CRH |=(0xB8B<<20);
46     
47     
48 //    //SPI2控制器
49 //    RCC->APB1ENR |=0x01<<14;//时钟使能
50 //    
51 //    SPI2->CR1 =0;//寄存器清零
52 //    SPI2->CR1 |=0x03<<8;//软件从设备管理
53 //    SPI2->CR1 |=0x01<<2;//主模式
54 
55 //    /*
56 //    8位数据帧格式
57 //    高位在前
58 //    */
59 //    SPI2->CR1 |=0x01<<6;//开启SPI2
60     
61     RCC->APB1ENR |=1<<14;  //SPI2时钟使能
62     SPI2->CR1 &=~(1<<11); //8位数据帧
63     SPI2->CR1 |=1<<9;  //
64     SPI2->CR1 |=1<<8;  //
65     SPI2->CR1 &=~(1<<7);  //先发高位
66     SPI2->CR1 &=~(0x7<<3);  
67     SPI2->CR1 |=0x0<<3;  //波特率
68     SPI2->CR1 |=1<<1;  //时钟空闲状态为高电平
69     SPI2->CR1 |=1<<0;  //在时钟第二个电平发送数据
70     SPI2->CR1 |=1<<2; //主SPI
71     
72     SPI2->CR1 |=1<<6;     //使能SPI
73     Spi2_Transfer_Byte(0xff);
74 }
Spi2_Pin_Init、 Spi2_Transfer_Byte、OLED_Send_Data

 1 void RFID_Init(void)
 2 {
 3      Spi2_Pin_Init( );
 4     
 5   RCC->APB2ENR |=1<<2;  //使能B时钟
 6     
 7     /*CS-----PA6*/ //推挽输出 50MHZ
 8     RFID_GPIO->CRL&=~(0xf<<RFID_CS_PIN*4);
 9     RFID_GPIO->CRL|=0X3<<(RFID_CS_PIN*4);
10     RFID_CSH;
11     
12     /*RST-----PA7*/ //推挽输出 50MHZ
13     RFID_GPIO->CRL&=~(0xf<<RFID_CS_PIN*4);
14     RFID_GPIO->CRL|=0X3<<(RFID_CS_PIN*4);
15     RFID_RSTH;
16     
17     Reset_RC522();    //开启天线
18     M500PcdConfigISOType( 'A' );
19 }
RFID_Init

 1 void WriteRawRC(u8   Address, u8   value)
 2 {  
 3     u8   ucAddr;
 4 //    u8 tmp;
 5 
 6         RFID_CSL;
 7     ucAddr = ((Address<<1)&0x7E);
 8 
 9         Spi2_Transfer_Byte(ucAddr);
10         Spi2_Transfer_Byte(value);
11         RFID_CSH;
12 
13 //         tmp=ReadRawRC(Address);
14 
15 //         if(value!=tmp)
16 //         printf("wrong
");
17 }
WriteRawRC,Spi2_Transfer_Byte
 1 * 功能描述 :   复位RC522
 2 void Reset_RC522(void)
 3 {
 4     PcdReset();       //功    能:复位RC522
 5     PcdAntennaOff();  //关闭天线
 6     PcdAntennaOn();   //开启天线
 7 }   
 8 
 9 * 功能描述 :  复位RC522
10 char PcdReset(void)
11 {
12     //PORTD|=(1<<RC522RST);
13     RFID_RSTH;
14   Delayus(2);
15 
16     //PORTD&=~(1<<RC522RST);
17     RFID_RSTL;
18    Delayus(2);
19 
20     //PORTD|=(1<<RC522RST);
21     RFID_RSTH;
22   Delayus(2);
23 
24   WriteRawRC(CommandReg,PCD_RESETPHASE);
25     WriteRawRC(CommandReg,PCD_RESETPHASE);
26   Delayus(2);
27     
28     WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363
29     WriteRawRC(TReloadRegL,30);           
30     WriteRawRC(TReloadRegH,0);
31     WriteRawRC(TModeReg,0x8D);
32     WriteRawRC(TPrescalerReg,0x3E);
33     
34     WriteRawRC(TxAutoReg,0x40);//必须要
35    
36    return MI_OK;
37 }
38 * 功能描述 :  写RC632寄存器
39  void WriteRawRC(u8   Address, u8   value)
40 {  
41     u8   ucAddr;
42 //    u8 tmp;
43 
44         RFID_CSL;
45     ucAddr = ((Address<<1)&0x7E);
46 
47         Spi2_Transfer_Byte(ucAddr);
48         Spi2_Transfer_Byte(value);
49         RFID_CSH;
50 
51 //         tmp=ReadRawRC(Address);
52 
53 //         if(value!=tmp)
54 //         printf("wrong
");
55 }
Reset_RC522、PcdReset、写RC632寄存器、

 1 void MG200Init(void)
 2 {
 3     //PC13--Detect:感应上电信号(手指触摸指纹传感器时输出高电平)
 4     //PB9---MG200_PWR
 5     
 6     RCC->APB2ENR |=0x03<<3;
 7     
 8     GPIOB->CRH &=~(0x0F<<4);
 9     GPIOB->CRH |=(0x03<<4);
10     GPIOC->CRH &=~(0x0F<<20);
11     GPIOC->CRH |=(0x04<<20);
12     MG200_PWR=1;
13     //GPIOB->ODR |=0x01<<9;
14 }
MG200Init

/*
函数功能:给MG200发送一个字节数据
参数说明:待发送的数据
返回值:
注意事项:
*/
void MG200SendByte(data)
{
while((USART2->SR & (0X01<<7))==0); //等待发送缓冲区为空
USART2->DR=data;
}

void MPR_Init()
{
    IIC_Init();   
    
     // Section A
  // This group controls filtering when data is > baseline.
  MPR_write(MPR_ADD,MHD_R, 0x01);
  MPR_write(MPR_ADD,NHD_R, 0x01);
  MPR_write(MPR_ADD,NCL_R, 0x00);
  MPR_write(MPR_ADD,FDL_R, 0x00);

  // Section B
  // This group controls filtering when data is < baseline.
  MPR_write(MPR_ADD,MHD_F, 0x01);
  MPR_write(MPR_ADD,NHD_F, 0x01);
  MPR_write(MPR_ADD,NCL_F, 0xFF);
  MPR_write(MPR_ADD,FDL_F, 0x02);
  
  // Section C
  // This group sets touch and release thresholds for each electrode
  MPR_write(MPR_ADD,ELE0_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE0_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE1_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE1_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE2_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE2_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE3_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE3_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE4_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE4_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE5_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE5_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE6_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE6_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE7_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE7_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE8_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE8_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE9_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE9_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE10_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE10_R, REL_THRESH);
  MPR_write(MPR_ADD,ELE11_T, TOU_THRESH);
  MPR_write(MPR_ADD,ELE11_R, REL_THRESH);
  
  // Section D
  // Set the Filter Configuration
  // Set ESI2
  MPR_write(MPR_ADD,FIL_CFG, 0x04);
  
  // Section E
  // Electrode Configuration
  // Enable 6 Electrodes and set to run mode
  // Set ELE_CFG to 0x00 to return to standby mode
  MPR_write(MPR_ADD,ELE_CFG, 0x0C);    // Enables all 12 Electrodes
  //write_i2c(MPR_ADD,ELE_CFG, 0x06);        // Enable first 6 electrodes
  
  // Section F
  // Enable Auto Config and auto Reconfig
  /*write_i2c(MPR_ADD,ATO_CFG0, 0x0B);
  write_i2c(MPR_ADD,ATO_CFGU, 0xC9);    // USL = (Vdd-0.7)/vdd*256 = 0xC9 @3.3V   write_i2c(MPR_ADD,ATO_CFGL, 0x82);    // LSL = 0.65*USL = 0x82 @3.3V
  write_i2c(MPR_ADD,ATO_CFGT, 0xB5);*/    // Target = 0.9*USL = 0xB5 @3.3V
}
MPR_Init()

[

void MPR_write(u8 ADD,u8 add,u8 data)
{
        IIC_Start();
        IIC_Send_Data(ADD);
        IIC_Get_ACK();
        IIC_Send_Data(add);
        IIC_Get_ACK();
        IIC_Send_Data(data);
        IIC_Get_ACK();
        IIC_Stop();
}
MPR_write,IIC_Start();

]

void VOICE_Init(void)
{
  RCC->APB2ENR |=1<<3;  //使能B时钟
    
    VOICE_GPIO->CRL &=~(0xf<<(VOICE_PIN*4)); //推挽输出 50MHz
    VOICE_GPIO->CRL |=3<<(VOICE_PIN*4);
    VOICE_GPIO->ODR &= ~(1<<VOICE_PIN);
    
    VOICE_GPIO->CRL &=~(0xf<<((BUSY)*4)); //浮空输入 
    VOICE_GPIO->CRL |=4<<((BUSY)*4);
    
}
void VoiceSend(u8 data)
{
    char i;
  VOICE_GPIO->ODR |=1<<VOICE_PIN;
    Delayms(8); 
    VOICE_GPIO->ODR &= ~(1<<VOICE_PIN);
    Delayms(1); 
    
    for(i=0;i<8;i++)
    {
        if((data&0x80)==0x80)
        {
            Hight();
        }
        else
        {
          Low();
        }
        data<<=1;
    }
    
    VOICE_GPIO->ODR &= ~(1<<VOICE_PIN);
}
VOICE_Init(void),VoiceSend(u8 data)
void LockInit()
{
  RCC->APB2ENR |=1<<2;  //使能A时钟
    
    LOCK_GPIO->CRL &=~(0xf<<((M_plus)*4)); //M+  推挽输出 50MHz
    LOCK_GPIO->CRL |=3<<((M_plus)*4);
    
    LOCK_GPIO->CRL &=~(0xf<<((M_sub)*4)); //M-   推挽输出 50MHz
    LOCK_GPIO->CRL |=3<<((M_sub)*4);
    LOCK_GPIO->ODR &=~(1<<M_sub);
    LOCK_GPIO->ODR &=~(1<<M_plus);
    
  set_lock_sta(1,0);   //先锁住把手
}
void LockInit()

 

 

DelayInit( );//定时器1延时功能初始化
Usart1Init(72,115200);
Usart2Init(36,115200);
OLED_Init( ); //OLED屏
RFID_Init(); //刷卡模块
MG200Init( ); //指纹模块
MPR_Init(); //电容按键
VOICE_Init( ); //语音
LockInit( ); //门锁

//创建第一个任务
ret=OSTaskCreate(StartTask,NULL,&START_TASK[START_STACK_LEN1],START_TASK_PRIO);

StartTask:(在这个任务之下又创建了很多任务)

OSTaskCreate(CkeyTask,NULL,&CKEY_TASK[CKEY_STACK_LEN-1],CKEY_TASK_PRIO);
OSTaskCreate(FingerTask,NULL,&FINGER_TASK[FINGER_STACK_LEN-1],FINGER_TASK_PRIO);
OSTaskCreate(RfidTask,NULL,&RFID_TASK[RFID_STACK_LEN-1],RFID_TASK_PRIO);
OSTaskCreate(AdministratorTask,NULL,&ADM_TASK[ADM_STACK_LEN-1],ADM_TASK_PRIO);

 1 void CkeyTask(void *pdata)
 2 {
 3     static u8 keybuf[7]={0};
 4     static u8 keylen=0;
 5     u8 timeout=0;
 6     
 7     u8 key=0;
 8 
 9     pdata=pdata;//防止编译器优化
10 
11     printf("Ckey task coming!!
");
12     
13     while(1)
14     {
15         if(!MPR_IRQ)
16         {
17             timeout=0;
18             key=MPR_GetKey();
19             if(key)
20             {
21                 VoiceSend(Di);
22                 OLED_Show_Aciss(4 ,20+keylen*16, key);
23                 keybuf[keylen++]=key;
24                 
25                 //printf("按下的按键为%c
",key);
26             }
27         }
28         
29         if(keylen==6)
30         {
31             Delayms(200);
32             keylen=0;
33             OLED_Show_String(4 ,20, (u8*)"            ");
34             
35             if( 0==strcmp((const char *)keybuf,(const char *)DoorKey) )//输入开门密码成功
36             {
37                 //OLED_Show_String(4 ,20, (u8*)"OPEN DOOR");
38                 set_lock_sta(0,1); //解锁门
39                 VoiceSend(DOOROPEN_SUCCESS);
40                 //while(BUSY_STATE);
41                 OSTimeDly(600);
42                 set_lock_sta(1,0); //一段时间后,锁住门
43                 //OSTimeDly(200);
44                 //OLED_Show_String(4 ,20, (u8*)"         ");
45             }
46             else if(0==strcmp((const char *)keybuf,(const char *)AdministratorKey))//输入管理员模式密码成功
47             {
48                 
49                 OSTaskSuspend (START_TASK_PRIO);            
50                 OSTaskSuspend (FINGER_TASK_PRIO);
51                 OSTaskSuspend (RFID_TASK_PRIO);
52                 OLED_CLear(0x00);//清屏
53                 OSTaskResume (ADM_WORK_TASK_PRIO);
54                 OSTaskResume(ADM_TASK_PRIO);
55                 OSTaskSuspend (OS_PRIO_SELF);
56             }
57             else
58             {
59                 VoiceSend(PASSWORD_INCONFORMITY);
60             }
61         }
62         if(keylen)//如果有按按键
63         {
64             if(++timeout>=40)//超时没有继续输入就清除
65             {
66                 keylen=0;
67                 OLED_Show_String(4 ,20, (u8*)"            ");
68             }
69         }
70         
71         
72         OSTimeDly(20);
73     }
74     
75 }
CkeyTask
 1 void FingerTask(void *pdata)
 2 {
 3     u8 ID=0;
 4     
 5     pdata=pdata;//防止编译器优化
 6 
 7     printf("Finger task coming!!
");
 8     
 9     while(1)
10     {
11         //while(!MG200_DETECT);//等待触摸
12         ID=Match1N( );//比对指纹
13         //printf("ID:::0x%x
",ID);
14         if(ID>0&&ID!=0xFF)
15         {
16             //OLED_Show_String(4 ,20, (u8*)"OPEN DOOR");
17             set_lock_sta(0,1); //解锁门
18             VoiceSend(DOOROPEN_SUCCESS);
19             //while(BUSY_STATE);
20             OSTimeDly(600);
21             set_lock_sta(1,0); //一段时间后,锁住门
22             //OSTimeDly(200);
23             //OLED_Show_String(4 ,20, (u8*)"         ");
24         }
25         else
26         {
27             VoiceSend(DOOROPEN_FAIL);
28             while(BUSY_STATE);
29         }
30             
31         OSTimeDly(20);
32     }
33     
34 }
FingerTask
 1 void RfidTask(void *pdata)
 2 {
 3     u8 i;
 4     u8 Buf[5]={0};
 5     
 6     pdata=pdata;//防止编译器优化
 7 
 8     printf("Rfid task coming!!
");
 9     
10     while(1)
11     {
12         if(MI_OK==Identificate_Card(CardType,CardId))
13         {
14             for(i=1;i<=CardSum;i++)//找出是存储的第几张卡
15             {
16                 AT24ReadBytes(Card_First_ADDR+4*(i-1),Buf,4);
17                 if(0==strcmp((const char *)CardId,(const char *)Buf))//找到了
18                     break;
19                 if(i==CardSum)//都没有找到
20                 {
21                     i=0xFF;break;
22                 }
23                     
24             }
25             if(CardSum!=0&&i!=0xFF)
26             {
27                 //OLED_Show_String(4 ,20, (u8*)"OPEN DOOR");
28                 set_lock_sta(0,1); //解锁门
29                 VoiceSend(DOOROPEN_SUCCESS);
30                 //while(BUSY_STATE);
31                 OSTimeDly(600);
32                 set_lock_sta(1,0); //一段时间后,锁住门
33                 //OSTimeDly(200);
34                 //OLED_Show_String(4 ,20, (u8*)"         ");
35             }
36             else
37             {
38                 VoiceSend(DOOROPEN_FAIL);
39                 while(BUSY_STATE);
40             }
41             
42         }
43         
44         OSTimeDly(50);
45     }
46     
47 }
RfidTask
  1 void AdministratorTask(void *pdata)
  2 {
  3 
  4     u8 key;
  5     u8 mode=0;//1修改管理员密码  2修改开门密码  3登记新门卡  4.删除门卡   5登记新指纹   6删除指定指纹   7删除所有指纹
  6              //8修改音量大小   9恢复出厂设置
  7     u8 sta=0;
  8     u8 flag=0;
  9     
 10     
 11     pdata=pdata;//防止编译器优化
 12     
 13     printf("Administrator task coming!!
");
 14     
 15     
 16     OSTaskCreate(AdministratorWorkTask,NULL,&ADM_WORK_TASK[ADM_WORK_STACK_LEN-1],ADM_WORK_TASK_PRIO);//创建修改开门密码/管理员密码任务
 17     //创建注册指纹/删除指纹任务
 18     //创建注册IC卡任务
 19     
 20     OSTaskSuspend (OS_PRIO_SELF);//挂起自己
 21 
 22 
 23     while(1)
 24     {
 25         //OSFlagPend (AdmFlag,0x3E,OS_FLAG_WAIT_CLR_ALL,0,NULL);//没有任何管理员操作
 26         
 27         if(!flag)
 28         {
 29             OLED_Show_String(0 ,0, (u8*)"Hi Administrator");
 30             OLED_Show_String(4 ,0, (u8*)"NEXT:0 ENTER:#");
 31             OLED_Show_String(6 ,0, (u8*)"LAST:8 ESC:*");
 32             flag=1;
 33         }
 34 
 35         
 36         if(!MPR_IRQ)
 37         {
 38             key=MPR_GetKey();
 39             if(key=='0')
 40             {
 41                 sta=1;
 42                 OLED_CLear(0x00);//清屏
 43                 mode++;
 44                 if(mode==10)
 45                     mode=1;
 46             }
 47             else if(key=='8')
 48             {
 49                 sta=1;
 50                 OLED_CLear(0x00);//清屏
 51                 mode--;
 52                 if(mode==0xFF||mode==0)
 53                     mode=9;
 54             }
 55             else if(key=='#')
 56             {
 57                 OLED_CLear(0x00);//清屏
 58                 switch(mode)
 59                 {
 60                     case 1:
 61                         OSSemPost(OSSem1);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 62                         break;
 63                     case 2:
 64                         OSSemPost(OSSem2);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 65                         break;
 66                     case 3:
 67                         OSSemPost(OSSem3);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 68                         break;
 69                     case 4:
 70                         OSSemPost(OSSem4);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 71                         break;
 72                     case 5:
 73                         OSSemPost(OSSem5);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 74                         break;
 75                     case 6:                    
 76                         OSSemPost(OSSem6);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 77                         break;
 78                     case 7:
 79                         OSSemPost(OSSem7);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 80                         break;
 81                     case 8:
 82                         OSSemPost(OSSem8);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 83                         break;
 84                     case 9:
 85                         OSSemPost(OSSem9);OSTaskSuspend (OS_PRIO_SELF);sta=1;
 86                         break;
 87                 }
 88             }
 89             else if(key=='*')
 90             {
 91                 while(BUSY_STATE);    
 92                 flag=0;mode=0;
 93                 OLED_CLear(0x00);//清屏
 94                 //挂起管理员操作任务
 95                 OSTaskSuspend (ADM_WORK_TASK_PRIO);
 96                 
 97                 OSTaskResume (FINGER_TASK_PRIO);
 98                 OSTaskResume (RFID_TASK_PRIO);
 99                 OSTaskResume(CKEY_TASK_PRIO);
100                 OSTaskResume (START_TASK_PRIO);            
101                 
102                 OSTaskSuspend (OS_PRIO_SELF);
103                 
104             }
105         }
106         
107         if(sta)
108         {
109             sta=0;
110             OLED_Show_String(4 ,0, (u8*)"NEXT:0 ENTER:#");
111             OLED_Show_String(6 ,0, (u8*)"LAST:8 ESC:*");
112             switch(mode)
113             {
114                 case 1:
115                     OLEDShowHz(0 ,0, (u8*)"修改管理员密码");                
116                     VoiceSend(CHANGE_ADMIN_PASSWORD);//修改管理员密码
117                     //while(BUSY_STATE);    
118                     break;
119                 case 2:
120                     OLEDShowHz(0 ,0, (u8*)"设置开门密码");
121                     VoiceSend(SET_DOOR_PASSWORD);//设置开门密码
122                     //while(BUSY_STATE);
123                     break;
124                 case 3:
125                     OLEDShowHz(0 ,0, (u8*)"登记卡片");
126                     VoiceSend(REGISTER_CARD);//登记卡片
127                     //while(BUSY_STATE);
128                     break;
129                 case 4:
130                     OLEDShowHz(0 ,0, (u8*)"删除指定门卡");
131                     VoiceSend(DELETE_ASSIGN_CARD);//删除指定门卡
132                     //while(BUSY_STATE);
133                     break;
134                 case 5:
135                     OLEDShowHz(0 ,0, (u8*)"登记指纹");
136                     VoiceSend(REGISTER_FINGER);//登记指纹
137                     //while(BUSY_STATE);
138                     break;
139                 case 6:
140                     OLEDShowHz(0 ,0, (u8*)"删除指定指纹");
141                     VoiceSend(DELETE_ASSIGN_FINGER);//删除指定指纹
142                     //while(BUSY_STATE);
143                     break;
144                 case 7:
145                     OLEDShowHz(0 ,0, (u8*)"删除所有指纹");
146                     VoiceSend(DELETE_ALLFINGER);//删除所有指纹
147                     //while(BUSY_STATE);
148                     break;
149                 case 8:
150                     OLEDShowHz(0 ,0, (u8*)"设置音量");
151                     VoiceSend(CHANGE_VOLUME);//设置音量
152                     //while(BUSY_STATE);
153                     break;
154                 case 9:
155                     OLEDShowHz(0 ,0, (u8*)"恢复出厂设置");
156                     VoiceSend(RECOVER_ALL);//恢复出厂设置
157                 //    while(BUSY_STATE);
158                     break;
159             }
160         }
161         
162         
163         
164         OSTimeDly(20);
165     }
166     
167 }
AdministratorTask
  1 void AdministratorWorkTask(void *pdata)
  2 {
  3     INT8U ret;
  4     u8 key;
  5     u8 i;
  6     static u8 keybuf[7]={0};
  7     static u8 keylen=0;
  8     
  9     pdata=pdata;//防止编译器优化
 10     
 11     printf("ChangePwd task coming!!
");
 12     
 13     
 14     
 15     while(1)
 16     {
 17         
 18         
 19         ret=OSSemAccept (OSSem1);//无等待获取信号量
 20         if(ret)//成功获取指定标志位(修改管理员密码)
 21         {
 22             OLEDShowHz(0 ,0, (u8*)"输入新密码");    VoiceSend(INPUT_NEW_PASSWORD);while(BUSY_STATE);    
 23             while(1)
 24             {            
 25                 if(!MPR_IRQ)
 26                 {
 27                     key=MPR_GetKey();
 28                     if(key&&key!='#')
 29                     {
 30                         VoiceSend(Di);
 31                         OLED_Show_Aciss(4 ,20+keylen*16, key);
 32                         keybuf[keylen++]=key;
 33                     }
 34                     else if(key=='#')
 35                     {
 36                         keylen=0;
 37                         goto m1;
 38                     }
 39                 }
 40                 if(keylen==6)
 41                 {
 42                     strcpy((char *)AdministratorKey,(const char *)keybuf);
 43                     AT24WriteBytes(Administrator_KEY_ADDR,keybuf,6);
 44                     keylen=0;
 45                     break;
 46                 }
 47             }
 48             OLEDShowHz(4 ,16, (u8*)"  操作成功  ");
 49             VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);            
 50             Delayms(200);
 51 m1:        OLED_CLear(0x00);//清屏
 52             OSTaskResume (ADM_TASK_PRIO);        
 53         }
 54         //-----------------------------------------------------------------------
 55         ret=OSSemAccept (OSSem2);//无等待获取信号量
 56         if(ret)//成功获取指定标志位(修改开门密码)
 57         {
 58             OLEDShowHz(0 ,0, (u8*)"输入新密码");    VoiceSend(INPUT_NEW_PASSWORD);while(BUSY_STATE);    
 59             while(1)
 60             {
 61     
 62                 if(!MPR_IRQ)
 63                 {
 64                     key=MPR_GetKey();
 65                     if(key&&key!='#')
 66                     {
 67                         VoiceSend(Di);
 68                         OLED_Show_Aciss(4 ,20+keylen*16, key);
 69                         keybuf[keylen++]=key;
 70                     }
 71                     else if(key=='#')
 72                     {
 73                         keylen=0;
 74                         goto m2;
 75                     }
 76                 }
 77                 if(keylen==6)
 78                 {
 79                     strcpy((char *)DoorKey,(const char *)keybuf);
 80                     AT24WriteBytes(Door_KEY_ADDR,keybuf,6);
 81                     keylen=0;
 82                     break;
 83                 }
 84             }
 85             OLEDShowHz(4 ,16, (u8*)"  操作成功  ");
 86             VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);
 87             Delayms(200);
 88 m2:        OLED_CLear(0x00);//清屏
 89             OSTaskResume (ADM_TASK_PRIO);        
 90         }
 91         //-----------------------------------------------------------------------
 92         ret=OSSemAccept (OSSem3);//无等待获取信号量
 93         if(ret)//成功获取指定标志位(登记门卡)
 94         {
 95             OLEDShowHz(0 ,0, (u8*)"请放置卡片");VoiceSend(PUTCARD);while(BUSY_STATE);    
 96             if(CardSum>=50)
 97             {
 98                 OLED_Show_String(2 ,0, (u8*)" Register full");
 99             }
100             else
101             {
102                 while(1)
103                 {
104                     if(!MPR_IRQ)
105                     {
106                         key=MPR_GetKey();
107                         if(key=='#')
108                             goto n0;
109                     }
110                     if(MI_OK==Identificate_Card(CardType,CardId))
111                     {
112                         CardSum++;
113                         AT24WriteBytes(CardSum_ADDR,&CardSum,1);
114                         AT24WriteBytes(Card_First_ADDR+4*(CardSum-1),CardId,4);
115                         OLEDShowHz(4 ,32, (u8*)"操作成功");
116                         VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);
117                         break;    
118                     }
119                 }
120             }
121             Delayms(500);
122 n0:        OLED_CLear(0x00);//清屏
123             OSTaskResume (ADM_TASK_PRIO);            
124         }
125         //-----------------------------------------------------------------------
126         ret=OSSemAccept (OSSem4);//无等待获取信号量
127         if(ret)//成功获取指定标志位(删除门卡)
128         {        
129             if(!CardSum)
130             {
131                 OLED_Show_String(2 ,0, (u8*)" No Card");
132             }    
133             else
134             {
135                 char Buff[15]={0};
136                 sprintf(Buff,"CardSum:%d",CardSum);
137                 OLED_Show_String(2 ,0, (u8*)Buff);
138                 OLEDShowHz(0 ,0, (u8*)"请放置卡片");VoiceSend(PUTCARD);while(BUSY_STATE);    
139             }
140             while(CardSum)//已登记的卡数量不是0
141             {
142                 static u8 cd[5]={0};
143                 
144                 if(!MPR_IRQ)
145                 {
146                     key=MPR_GetKey();
147                     if(key=='#')
148                         goto n3;
149                 }
150                 if(MI_OK==Identificate_Card(CardType,CardId))
151                 {
152                     for(i=1;i<=CardSum;i++)//找出是存储的第几张卡
153                     {
154                         AT24ReadBytes(Card_First_ADDR+4*(i-1),cd,4);
155                         if(0==strcmp((const char *)CardId,(const char *)cd))//找到了
156                         {
157                             memset(cd,0,sizeof(cd));
158                             break;
159                         }
160                             
161                         if(i==CardSum)//都没有找到
162                         {
163                             i=0xFA;break;
164                         }    
165                     }
166                     
167                     if(i==0xFA)//没有该卡的记录
168                     {
169                         OLED_Show_String(2 ,0, (u8*)" Not Found");
170                     }
171                     else
172                     {
173                         if(i!=CardSum)//有并且不是最后一张
174                         {
175                             AT24ReadBytes(Card_First_ADDR+4*(CardSum-1),CardId,4);//读出最后一张卡的卡号
176                             AT24WriteBytes(Card_First_ADDR+4*(i-1),CardId,4);//写到要删除的那张卡的地址
177                         }
178                         CardSum--;//卡数量减1
179                         AT24WriteBytes(CardSum_ADDR,&CardSum,1);
180                         OLEDShowHz(4 ,32, (u8*)"操作成功");
181                         VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);
182                     }
183                     
184                     break;    
185                 }
186             }        
187             Delayms(500);
188 n3:   OLED_CLear(0x00);//清屏
189             OSTaskResume (ADM_TASK_PRIO);        
190         }
191         //-----------------------------------------------------------------------
192         ret=OSSemAccept (OSSem5);//无等待获取信号量
193         if(ret)//成功获取指定标志位(登记指纹)
194         {
195             OLEDShowHz(0 ,0, (u8*)"请放手指");
196             while(1)
197             {
198                 VoiceSend(DELETE_ASSIGNFIGNER);//请放手指
199                 while(!MG200_DETECT)
200                 {
201                     if(!MPR_IRQ)
202                     {
203                     key=MPR_GetKey();
204                     if(key=='#')
205                         goto n1;
206                     }
207                 }
208                 ret=Enroll();//录入指纹
209                 if(!ret)
210                 {
211                     VoiceSend(SETTING_SUCCESS);//操作成功
212                     OLEDShowHz(4 ,32, (u8*)"操作成功");VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);
213                     break;
214                 }
215                 else
216                 {
217                     switch(ret)
218                     {
219                         case 0x83:OLED_Show_String(4 ,0, (u8*)"ID error");break;
220                         case 0x91:OLED_Show_String(4 ,0, (u8*)"User full");break;
221                         case 0x93:OLED_Show_String(4 ,0, (u8*)"ID be used");break;
222                         case 0x94:OLED_Show_String(4 ,0, (u8*)"Capture less");break;
223                     }
224                     Delayms(800);
225                     OLED_Show_String(4 ,0, (u8*)"            ");
226                 }
227 
228             }
229             Delayms(500);
230 n1:   OLED_CLear(0x00);//清屏
231             OSTaskResume (ADM_TASK_PRIO);
232         }
233         //-----------------------------------------------------------------------
234         ret=OSSemAccept (OSSem6);//无等待获取信号量
235         if(ret)//成功获取指定标志位(删除指定指纹)
236         {
237             u8 id=0;
238             
239             id=GetUserNum( );
240             if(id&&id!=ACK_ERR)
241             {
242                 //显示指纹数目
243                 char buff[15]={0};
244                 sprintf(buff,"FingerNum:%d",id);
245                 OLED_Show_String(2 ,0, (u8*)buff);
246                 while(1)
247                 {            
248                     OLEDShowHz(0 ,0, (u8*)"请放手指");
249                     VoiceSend(DELETE_ASSIGNFIGNER);//请放手指
250                     while(!MG200_DETECT)
251                     {
252                         if(!MPR_IRQ)
253                         {
254                         key=MPR_GetKey();
255                         if(key=='#')
256                             goto n2;
257                         }
258                     }
259                     id=Match1N( );//比对指纹
260                     if(id>0&&id!=0xFF)
261                     {
262                         Delayms(200);
263                         ret=EraseOne(id);
264                         if(ret==0)
265                         {
266                             OLEDShowHz(4 ,32, (u8*)"操作成功");VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);
267                             goto nx;
268                         }
269                         else
270                         {
271                             OLED_Show_String(4 ,0, (u8*)"NO register id");
272                             Delayms(800);
273                             OLED_Show_String(4 ,0, (u8*)"              ");
274                         }
275                     }
276                     else
277                     {
278                         OLED_Show_String(4 ,0, (u8*)"NO this finger");
279                         Delayms(800);
280                         OLED_Show_String(4 ,0, (u8*)"                ");
281                     }
282                 }
283             }
284             else
285             {
286                 OLED_Show_String(4 ,0, (u8*)"Null finger");
287             }
288             
289 nx:   Delayms(500);
290 n2:      OLED_CLear(0x00);//清屏
291             OSTaskResume (ADM_TASK_PRIO);        
292         }
293         //-----------------------------------------------------------------------
294         ret=OSSemAccept (OSSem7);//无等待获取信号量
295         if(ret)//成功获取指定标志位(删除所有指纹)
296         {
297             OLEDShowHz(0 ,0, (u8*)"删除所有指纹");
298             
299             ret = EraseAll( );
300             if(!ret)
301             {
302                 OLEDShowHz(4 ,32, (u8*)"操作成功");VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);
303             }
304             else if(ret==0x90)
305             {
306                 OLED_Show_String(4 ,0, (u8*)"Null finger");
307             }
308             else
309             {
310                 OLED_Show_String(4 ,0, (u8*)"Delete fail");
311             }
312             Delayms(800);
313             OLED_CLear(0x00);//清屏
314             OSTaskResume (ADM_TASK_PRIO);            
315         }
316         //-----------------------------------------------------------------------
317         ret=OSSemAccept (OSSem8);//无等待获取信号量
318         if(ret)//成功获取指定标志位(修改音量大小)
319         {
320             OLEDShowHz(0 ,48, (u8*)"音量");
321             OLEDShowHz(2 ,0, (u8*)"+:8      Enter:#");
322             OLEDShowHz(4 ,0, (u8*)"-:0");
323             switch(VoicePwr)
324             {
325                 case 7:OLEDDrawLine(6,32+56,0xFF);
326                 case 6:OLEDDrawLine(6,32+48,0xFE);
327                 case 5: OLEDDrawLine(6,32+40,0xFC);
328                 case 4: OLEDDrawLine(6,32+32,0xF8);
329                 case 3: OLEDDrawLine(6,32+24,0xF0);
330                 case 2: OLEDDrawLine(6,32+16,0xE0);
331                 case 1: OLEDDrawLine(6,32+8,0xC0);
332                 case 0: OLEDDrawLine(6,32,0x80);
333             }
334             while(1)
335             {
336                 if(!MPR_IRQ)
337                 {
338                     key=MPR_GetKey();
339                     if(key=='8')
340                     {
341                         VoicePwr++;
342                         if(VoicePwr>=8)
343                             VoicePwr=7;
344                     }
345                     else if(key=='0')
346                     {
347                         VoicePwr--;
348                         if(VoicePwr==0xFF)
349                             VoicePwr=0;
350                     }
351                     else if(key=='#')
352                     {
353                         AT24WriteBytes(Voice_ADDR,&VoicePwr,1);
354                         VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);
355                         break;
356                     }
357                     if(key=='0'||key=='8')
358                     {
359                         VoiceSend(VoiceAC[VoicePwr]);//设置音量大小
360                         while(BUSY_STATE);
361                         Delayms(50);
362                         VoiceSend(Di);
363                         OLED_Show_String(6 ,24, (u8*)"             ");
364                         switch(VoicePwr)
365                         {
366                             case 7:OLEDDrawLine(6,32+56,0xFF);
367                             case 6:OLEDDrawLine(6,32+48,0xFE);
368                             case 5: OLEDDrawLine(6,32+40,0xFC);
369                             case 4: OLEDDrawLine(6,32+32,0xF8);
370                             case 3: OLEDDrawLine(6,32+24,0xF0);
371                             case 2: OLEDDrawLine(6,32+16,0xE0);
372                             case 1: OLEDDrawLine(6,32+8,0xC0);
373                             case 0: OLEDDrawLine(6,32,0x80);
374                         }
375                         
376                     }
377                     
378                 }
379             }
380             OLED_CLear(0x00);//清屏
381             OSTaskResume (ADM_TASK_PRIO);    
382             
383         }
384         //-----------------------------------------------------------------------
385         ret=OSSemAccept (OSSem9);//无等待获取信号量
386         if(ret)//成功获取指定标志位(恢复出厂设置)
387         {
388             OLEDShowHz(0 ,0, (u8*)"恢复出厂设置");
389             
390             EraseAll( );//清除指纹
391             strcpy((char *)DoorKey,"888888");
392             strcpy((char *)AdministratorKey,"123123");            
393             CardSum=0; 
394             VoicePwr=7;
395             AT24WriteBytes(Door_KEY_ADDR,DoorKey,6);
396             AT24WriteBytes(Administrator_KEY_ADDR,AdministratorKey,6);
397             AT24WriteBytes(CardSum_ADDR,&CardSum,1);
398             AT24WriteBytes(Voice_ADDR,&VoicePwr,1);
399             VoiceSend(VoiceAC[VoicePwr]);//设置音量大小
400             
401             OLEDShowHz(4 ,32, (u8*)"操作成功");VoiceSend(SETTING_SUCCESS);while(BUSY_STATE);
402             Delayms(500);
403             OLED_CLear(0x00);//清屏
404             OSTaskResume (ADM_TASK_PRIO);    
405         }
406         
407         
408         OSTimeDly(10);
409     }
410     
411 }
AdministratorWorkTask

2.内部项目的逻辑

 相关面试问题:

模块怎么通信:

指纹模块:usart2,串口(MG200Init( );)

刷卡模块:spi2

电容按键:iic(MPR_Init())

触摸屏和显示屏:spi2

ucosII的好处

项目多少个人做的

USB会·吗·

任务间怎么通信的,信号量,事件标志组,消息邮箱,消息队列

任务都有优先级吗

原文地址:https://www.cnblogs.com/zhouyuqing1024/p/11847404.html