标题:
基于stm32f103+UCOSII的电子密码锁源程序
[打印本页]
作者:
kjdh
时间:
2018-1-15 02:17
标题:
基于stm32f103+UCOSII的电子密码锁源程序
单片机源程序如下:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "move.h"
#include "beep.h"
#include "touch.h"
#include "includes.h"
#include "24cxx.h"
#include "exti.h"
#include "timer.h"
#include "rtc.h"
#include "joypad.h"
u8 save[4];
u8 save1[4];
u8 save2[4];
//u8 key_point[4];
/////////////////////////UCOSII任务设置///////////////////////////////////
//START 任务
//设置任务优先级
#define START_TASK_PRIO 10 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE 64
//任务堆栈
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);
//设置密码任务
//设置任务优先级
#define MAIN_TASK_PRIO 4
//设置任务堆栈大小
#define MAIN_STK_SIZE 128
//任务堆栈
OS_STK MAIN_TASK_STK[MAIN_STK_SIZE];
//任务函数
void main_task(void *pdata);
//显示时间任务
//设置任务优先级
#define RTC_TASK_PRIO 7
//设置任务堆栈大小
#define RTC_STK_SIZE 64
//任务堆栈
OS_STK RTC_TASK_STK[RTC_STK_SIZE];
//任务函数
void rtc_task(void *pdata);
//解码后任务
//设置任务优先级
#define SHOW_TASK_PRIO 9
//设置任务堆栈大小
#define SHOW_STK_SIZE 64
//任务堆栈
OS_STK SHOW_TASK_STK[SHOW_STK_SIZE];
//任务函数
void show_task(void *pdata);
//按键扫描任务
//设置任务优先级
#define KEY_TASK_PRIO 3
//设置任务堆栈大小
#define KEY_STK_SIZE 64
//任务堆栈
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
//任务函数
void key_task(void *pdata);
//报警任务
//设置任务优先级
#define BEEP_TASK_PRIO 8
//设置任务堆栈大小
#define BEEP_STK_SIZE 64
//任务堆栈
OS_STK BEEP_TASK_STK[BEEP_STK_SIZE];
//任务函数
void beep_task(void *pdata);
//输入密码
//设置任务优先级
#define put_TASK_PRIO 5
//设置任务堆栈大小
#define put_STK_SIZE 64
//任务堆栈
OS_STK put_TASK_STK[put_STK_SIZE];
//任务函数
void put_task(void *pdata);
//重设任务
//设置任务优先级
#define CHANGE_TASK_PRIO 6
//设置任务堆栈大小
#define CHANGE_STK_SIZE 64
//任务堆栈
OS_STK CHANGE_TASK_STK[CHANGE_STK_SIZE];
//任务函数
void change_task(void *pdata);
//数字表
const u8* kbd_tbl[9]={"1","2","3","4","5","6","7","8","9",};
void py_load_ui(u16 x,u16 y);
void py_key_staset(u16 x,u16 y,u8 keyx,u8 sta);
void PWM(void);
//void readfromBKP(void);
//void writetoBKP(void);
//得到触摸屏的输入
//x,y:键盘坐标
//返回值:按键键值(1~9有效;0,无效)
u8 py_get_keynum(u16 x,u16 y)
{
u16 i,j;
static u8 key_x=0;//0,没有任何按键按下;1~9,1~9号按键按下
u8 key=0;
tp_dev.scan(0);
if(tp_dev.sta&TP_PRES_DOWN) //触摸屏被按下
{
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
if(tp_dev.x<(x+j*60+60)&&tp_dev.x>(x+j*60)&&tp_dev.y<(y+i*40+40)&&tp_dev.y>(y+i*40))
{
key=i*3+j+1;
break;
}
}
if(key)
{
if(key_x==key)key=0;
else
{
py_key_staset(x,y,key_x-1,0);
key_x=key;
py_key_staset(x,y,key_x-1,1);
}
break;
}
}
}else if(key_x)
{
py_key_staset(x,y,key_x-1,0);
key_x=0;
}
return key;
}
//////////////////////////////////////////////////////////////////////////////
OS_EVENT * msg_key; //按键邮箱事件块指针
OS_EVENT * sem_beep; //蜂鸣器信号量指针
object move; //移动函数时使用
//加载主界面
//void ucos_load_main_ui(void)
//{
//}
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
LED_Init(); //初始化与LED连接的硬件接口
BEEP_Init(); //蜂鸣器初始化
KEY_Init(); //按键初始化
LCD_Init(); //初始化LCD
TP_Init(); //初始化触摸屏
EXTIX_Init(); //外部中断初始化
JOYPAD_Init();
TIM5_Int_Init(59999,7199);//10Khz的计数频率,计数到60000为6s
TIM3_PWM_Init(899,0); //不分频。PWM频率=72000000/900=80Khz
// ucos_load_main_ui(); //加载主界面
RTC_Init();
//显示时间
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(60,250,200,16,16," - - ");
LCD_ShowString(60,282,200,16,16," : : ");
OSInit(); //初始化UCOSII
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
OSStart();
}
//开始任务
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
pdata = pdata;
msg_key=OSMboxCreate((void*)0); //创建消息邮箱
sem_beep=OSSemCreate(0); //创建信号量
OSStatInit(); //初始化统计任务.这里会延时1秒钟左右
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
OSTaskCreate(main_task,(void *)0,(OS_STK*)&MAIN_TASK_STK[MAIN_STK_SIZE-1],MAIN_TASK_PRIO);
OSTaskCreate(key_task,(void *)0,(OS_STK*)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO);
OSTaskCreate(beep_task,(void *)0,(OS_STK*)&BEEP_TASK_STK[BEEP_STK_SIZE-1],BEEP_TASK_PRIO);
OSTaskCreate(put_task,(void *)0,(OS_STK*)&put_TASK_STK[put_STK_SIZE-1],put_TASK_PRIO);
OSTaskCreate(rtc_task,(void *)0,(OS_STK*)&RTC_TASK_STK[RTC_STK_SIZE-1],RTC_TASK_PRIO);
OSTaskCreate(show_task,(void *)0,(OS_STK*)&SHOW_TASK_STK[SHOW_STK_SIZE-1],SHOW_TASK_PRIO);
OSTaskCreate(change_task,(void *)0,(OS_STK*)&CHANGE_TASK_STK[CHANGE_STK_SIZE-1],CHANGE_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
OSTaskSuspend(9); //挂起显示任务
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
//RTC时间显示任务
void rtc_task(void *pdata)
{
u8 t=0;
while(1)
{
if(t!=calendar.sec)
{
t=calendar.sec;
LCD_ShowNum(60,250,calendar.w_year,4,16);
LCD_ShowNum(100,250,calendar.w_month,2,16);
LCD_ShowNum(124,250,calendar.w_date,2,16);
switch(calendar.week)
{
case 0:
LCD_ShowString(60,266,200,16,16,"Sunday ");
break;
case 1:
LCD_ShowString(60,266,200,16,16,"Monday ");
break;
case 2:
LCD_ShowString(60,266,200,16,16,"Tuesday ");
break;
case 3:
LCD_ShowString(60,266,200,16,16,"Wednesday");
break;
case 4:
LCD_ShowString(60,266,200,16,16,"Thursday ");
break;
case 5:
LCD_ShowString(60,266,200,16,16,"Friday ");
break;
case 6:
LCD_ShowString(60,266,200,16,16,"Saturday ");
break;
}
LCD_ShowNum(60,282,calendar.hour,2,16);
LCD_ShowNum(84,282,calendar.min,2,16);
LCD_ShowNum(108,282,calendar.sec,2,16);
}
delay_ms(10);
}
}
//蜂鸣器任务
void beep_task(void *pdata)
{
u8 err;
while(1)
{
OSSemPend(sem_beep,0,&err);
BEEP=1;
delay_ms(60);
BEEP=0;
delay_ms(940);
}
}
//游戏任务
void show_task(void *pdata)
{
u8 k;
delay_ms(10);
move.position_x=100;
move.position_y=150;
move.size=7;
move.color=RED;
LCD_Draw_Circle(move.position_x,move.position_y, move.size);
POINT_COLOR=RED;
LCD_DrawLine(0, 248,240, 248);
LCD_DrawLine(0,25,240,25);
LCD_DrawLine(1,25,1, 248);
LCD_DrawLine(239,25,239,248);
gui_fill_circle(50,80,7,BLUE);
gui_fill_circle(40,40,4,RED);
gui_fill_circle(80,200,10,GREEN);
while(1)
{
k=JOYPAD_Read();
switch(k)
{
case 254:
move=move_right(move);break;
case 253:
move=move_left(move);break;
case 247:
move=move_forward(move);break;
case 251:
move=move_back(move);break;
}
if(move.position_y-move.size==25)
{BEEP=1;
delay_ms(60);
BEEP=0;
delay_ms(940);
move=move_back(move);
LCD_DrawLine(0,25,240,25);
}
if(move.position_y+move.size==248)
{BEEP=1;
delay_ms(60);
BEEP=0;
delay_ms(940);
move=move_forward(move);
LCD_DrawLine(0, 248,240, 248);
}
if(move.position_x-move.size==1)
{BEEP=1;
delay_ms(60);
BEEP=0;
delay_ms(940);
move=move_right(move);
LCD_DrawLine(1,25,1, 248);
}
if(move.position_x+move.size==239)
{BEEP=1;
delay_ms(60);
BEEP=0;
delay_ms(940);
move=move_left(move);
LCD_DrawLine(239,25,239,248);
}
}
}
//设置密码任务
void main_task(void *pdata)
{
int m;
u32 key1=0;
u8 err;
u8 i=0;
u8 key;
u8 inputstr[3]; //最大输入6个字符+结束符
u8 inputlen; //输入长度
POINT_COLOR=BLUE; //电量界面
LCD_DrawRectangle(198,2,239,22);
LCD_DrawRectangle(195,7,198,17);
LCD_Fill(200,3,208,21,GREEN);
LCD_Fill(210,3,218,21,GREEN);
LCD_Fill(220,3,228,21,GREEN);
LCD_Fill(230,3,238,21,GREEN);
OSTaskSuspend(6); //挂起起始任务.
m=BKP_ReadBackupRegister(BKP_DR6);
if(m==1)
{
OSTaskSuspend(4); //挂起起始任务.
}
OSTaskSuspend(5); //挂起起始任务.
py_load_ui(20,75);
inputlen=0;
POINT_COLOR=RED;
LCD_ShowString(10,10,110,16,24,"Please set ");
LCD_ShowString(20,50,110,16,24,"your code ");
POINT_COLOR=BLUE;
while(1)
{
i++;
delay_ms(10);
key=py_get_keynum(20,75);
if(key)
{
key1=(u32)OSMboxPend(msg_key,10,&err);
if(key1==4)//删除
{
if(inputlen)inputlen--;
inputstr[inputlen]='\0';//添加结束符
Show_Str(140,55,35,16,inputstr,16,0); //显示有效的数字串
}
if(inputlen<4)
{
save[inputlen]=key;
inputstr[inputlen]=key+'0';//输入字符
inputlen++;
}
LCD_DrawRectangle(138,53,175,73);
Show_Str(140,55,35,16,inputstr,16,0); //显示有效的数字串
if(inputlen==4)
{
BKP_WriteBackupRegister(BKP_DR6,1);
BKP_WriteBackupRegister(BKP_DR2,save[0]);
BKP_WriteBackupRegister(BKP_DR3,save[1]);
BKP_WriteBackupRegister(BKP_DR4,save[2]);
BKP_WriteBackupRegister(BKP_DR5,save[3]);
OSTaskResume (5); //解挂
OSTaskSuspend(4); //挂起起始任务.
}
}
}
}
//按键扫描任务
void key_task(void *pdata)
{
u32 key1;
while(1)
{
key1=KEY_Scan(0);
if(key1)OSMboxPost(msg_key,(void*)key1);//发送消息
delay_ms(10);
}
}
//后加
//加载键盘界面
//x,y:界面起始坐标
void py_load_ui(u16 x,u16 y)
{
u16 i;
LCD_Fill(0,50,240,200,WHITE);
LCD_Fill(0,0,190,50,WHITE);//清屏
POINT_COLOR=RED; //键盘界面
LCD_DrawRectangle(x,y,x+180,y+120);
LCD_DrawRectangle(x+60,y,x+120,y+120);
LCD_DrawRectangle(x,y+40,x+180,y+80);
POINT_COLOR=BLUE; //在键盘上加载数字
for(i=0;i<9;i++)
{
Show_Str_Mid(x+(i%3)*60,y+4+40*(i/3),(u8*)kbd_tbl[i],24,60);
}
}
//按键状态设置
//x,y:键盘坐标
//key:键值(0~11)
//sta:状态,0,松开;1,按下;
void py_key_staset(u16 x,u16 y,u8 keyx,u8 sta)
{
u16 i=keyx/3,j=keyx%3;
if(keyx>9)return;
if(sta)LCD_Fill(x+j*60+1,y+i*40+1,x+j*60+59,y+i*40+39,GREEN);
else LCD_Fill(x+j*60+1,y+i*40+1,x+j*60+59,y+i*40+39,WHITE);
Show_Str_Mid(x+j*60,y+4+40*i,(u8*)kbd_tbl[keyx],24,60);
}
//输入密码任务
void put_task(void *pdata)
{
u32 key1=0;
u8 err;
u8 key;
u8 inputstr[3]; //最大输入6个字符+结束符
u8 inputlen; //输入长度
u8 t=0;
u8 T[3];
py_load_ui(20,75);
inputlen=0;
while(1)
{
delay_ms(10);
PWM();
if(c)
{
OSTaskResume (6); //解挂
LED1=!LED1;
OSTaskSuspend(5); //挂起起始任务.
}
POINT_COLOR=RED;
LCD_ShowString(10,10,140,16,24,"Please input ");
LCD_ShowString(20,50,110,16,24,"your code ");
LCD_Fill(138,53,175,73,WHITE);
POINT_COLOR=BLUE;
key=py_get_keynum(20,75);
if(key)
{
key1=(u32)OSMboxPend(msg_key,10,&err);
if(key1==4)//删除
{
if(inputlen)inputlen--;
inputstr[inputlen]='\0';//添加结束符
}
if(inputlen<4)
{
save1[inputlen]=key;
inputstr[inputlen]=key+'0';//输入字符
inputlen++;
}
Show_Str(140,55,35,16,inputstr,16,0); //显示有效的数字串
LCD_DrawRectangle(138,53,175,73);
if(t<4)
{
T[t]='*';//显示*
t++;
}
Show_Str(140,55,35,16,T,16,0); //显示成* 的形式
}
if(a) //中断判断
{
LCD_DrawRectangle(138,53,175,73);
Show_Str(140,55,35,16,inputstr,16,0); //显示有效的数字串
}
else
{
LCD_DrawRectangle(138,53,175,73);
Show_Str(140,55,35,16,T,16,0); //显示成* 的形式
}
if(inputlen==4)
{
save2[0]=BKP_ReadBackupRegister(BKP_DR2);
save2[1]=BKP_ReadBackupRegister(BKP_DR3);
save2[2]=BKP_ReadBackupRegister(BKP_DR4);
save2[3]=BKP_ReadBackupRegister(BKP_DR5);
key1=(u32)OSMboxPend(msg_key,0,&err);
if(key1==2)//确定
{
if(save2[0]==save1[0]&&save2[1]==save1[1]&&save2[2]==save1[2]&&save2[3]==save1[3])
{
LED1=!LED1;
LCD_Fill(0,50,240,200,WHITE);
LCD_Fill(0,0,190,50,WHITE);//清屏
USART_SendData(USART1, 1);//向串口1发送数据
OSTaskSuspend(5); //挂起起始任务.
}
else
{
LED0=!LED0;
OSSemPost(sem_beep);
USART_SendData(USART1, 2);//向串口1发送数据
delay_ms(1000);
OSTaskSuspend(5); //挂起起始任务.
}
}
}
}
}
void PWM(void) //PWM呼吸灯
{
u8 dir=1;
u16 led0pwmval=0;
if(b==1)
{
while(1)
{
delay_ms(10);
if(dir)led0pwmval++;
else led0pwmval--;
if(led0pwmval>300)dir=0;
if(led0pwmval==0)dir=1;
TIM_SetCompare2(TIM3,led0pwmval);
}
}
}
//重新设置密码任务
void change_task(void *pdata)
{
u32 key1=0;
u8 err;
u8 key;
u8 inputstr[3]; //最大输入6个字符+结束符
u8 inputlen; //输入长度
POINT_COLOR=RED; //电量界面
LCD_DrawRectangle(198,2,239,22);
LCD_DrawRectangle(195,7,198,17);
LCD_Fill(200,3,208,21,GREEN);
LCD_Fill(210,3,218,21,GREEN);
LCD_Fill(220,3,228,21,GREEN);
LCD_Fill(230,3,238,21,GREEN);
py_load_ui(20,75);
inputlen=0;
POINT_COLOR=RED;
LCD_ShowString(10,10,110,16,24,"Please set ");
LCD_ShowString(20,50,110,16,24,"your code ");
POINT_COLOR=BLUE;
while(1)
{
delay_ms(10);
key=py_get_keynum(20,75);
if(key)
{
key1=(u32)OSMboxPend(msg_key,10,&err);
if(key1==4)//删除
{
if(inputlen)inputlen--;
inputstr[inputlen]='\0';//添加结束符
Show_Str(140,55,35,16,inputstr,16,0); //显示有效的数字串
}
if(inputlen<4)
{
save[inputlen]=key;
inputstr[inputlen]=key+'0';//输入字符
inputlen++;
}
LCD_DrawRectangle(138,53,175,73);
Show_Str(140,55,35,16,inputstr,16,0); //显示有效的数字串
if(inputlen==4)
{
BKP_WriteBackupRegister(BKP_DR6,1);
BKP_WriteBackupRegister(BKP_DR2,save[0]);
BKP_WriteBackupRegister(BKP_DR3,save[1]);
BKP_WriteBackupRegister(BKP_DR4,save[2]);
BKP_WriteBackupRegister(BKP_DR5,save[3]);
c=0;
OSTaskResume (5); //解挂
LED1=!LED1;
OSTaskSuspend(6); //挂起起始任务.
}
}
}
}
复制代码
所有资料51hei提供下载:
ARM实验密码锁.rar
(530.04 KB, 下载次数: 133)
2018-1-15 02:59 上传
点击文件名下载附件
stm32的电子密码锁
下载积分: 黑币 -5
作者:
啦啦啦111111
时间:
2018-1-26 17:50
大佬!!我这个矩阵按键程序单独按一个键好用,但我现在想把它弄成密码的样子,利用FOR循环在主程序里,可是for循环只会扫描到我的一次按键,六次循环就结束了,,该用什么办法解决呢?
作者:
9291806
时间:
2019-9-16 10:52
谢谢,正学习UCOS,
作者:
qqq1234561
时间:
2020-7-8 18:08
有这个密码锁的proues电路图可以传一下吗,大佬,
作者:
呵..呵
时间:
2020-10-20 09:28
有原理图可以参考下吗
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1