仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include "sys.h"
- #include "led.h"
- #include "lcd.h"
- #include "motor.h"
- #include "delay.h"
- #include "includes.h"
- ////////////////////////事件标志组//////////////////////////////
- #define KEY_FLAG 0x01
- #define KEYFLAGS_VALUE 0X00
- OS_FLAG_GRP *EventFlags; //定义一个事件标志组
- /////////////////////////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); //任务函数
-
-
- //LED0任务:每100ms:完成红色LED的一个周期闪烁、检测一次按键且将结果发送到事件标志组
- #define LED0_TASK_PRIO 9 //设置任务优先级
- #define LED0_STK_SIZE 64 //设置任务堆栈大小
- OS_STK LED0_TASK_STK[LED0_STK_SIZE]; //任务堆栈
- void led0_task(void *pdata); //任务函数
- //LCD任务:每500ms:在屏幕上显示adc、电机转速
- #define LCD_TASK_PRIO 8 //设置任务优先级
- #define LCD_STK_SIZE 64//设置任务堆栈大小
- OS_STK LCD_TASK_STK[LCD_STK_SIZE]; //任务堆栈
- void LCD_task(void *pdata); //任务函数
- //MOTOR任务:每200ms:控制电机换向、测量一次ADC
- #define MOTOR_TASK_PRIO 7 //设置任务优先级
- #define MOTOR_STK_SIZE 64//设置任务堆栈大小
- OS_STK MOTOR_TASK_STK[MOTOR_STK_SIZE]; //任务堆栈
- void MOTOR_task(void *pdata); //任务函数
- //LCD_KEY任务: 每100ms: 在屏幕上显示(事件)开关是否按下
- #define LCD_KEY_TASK_PRIO 6 //设置任务优先级
- #define LCD_KEY_STK_SIZE 64//设置任务堆栈大小
- OS_STK LCD_KEY_TASK_STK[LCD_KEY_STK_SIZE]; //任务堆栈
- void LCD_KEY_task(void *pdata); //任务函数
- int main(void)
- {
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
- delay_init(); //延时函数初始化
- LED_Init(); //初始化与LED连接的硬件接口
- LCD_Init(); //初始化与LCD连接的硬件接口
- MOTOR_Init(); //初始化PWM/GPIO复用硬件接口
- MOTOR_ADC_Init(); //初始化ADC复用硬件接口
- OSInit();
- OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
- OSStart();
- }
-
- //开始任务
- void start_task(void *pdata)
- {
- INT8U err;
-
- OS_CPU_SR cpu_sr=0;
- pdata = pdata;
- OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
-
- //事件创建
- EventFlags = OSFlagCreate (KEYFLAGS_VALUE, //事件标志组初始值
- &err); //错误码
-
- //LED红灯的任务创建
- OSTaskCreate(led0_task,(void *)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);
- //事件标志----LCD_KEY的任务创建
- OSTaskCreate(LCD_KEY_task,(void *)0,(OS_STK*)&LCD_KEY_TASK_STK[LCD_KEY_STK_SIZE-1],LCD_KEY_TASK_PRIO);
- //电机的任务创建
- OSTaskCreate(MOTOR_task,(void *)0,(OS_STK*)&MOTOR_TASK_STK[MOTOR_STK_SIZE-1],MOTOR_TASK_PRIO);
-
- //屏幕的任务创建
- OSTaskCreate(LCD_task,(void *)0,(OS_STK*)&LCD_TASK_STK[LCD_STK_SIZE-1],LCD_TASK_PRIO);
- OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
- OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
- }
复制代码
Keil代码与Proteus仿真求指导:
无刷直流电机.7z
(373.34 KB, 下载次数: 135)
|