|
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
void Init_Timer0(void);
void delay_ms(unsigned int ums);
void OutputText(void); // 任务0
void ScanKeyboard(void); // 任务1
void LCDDisplay(void); // 任务2
unsigned char uKey_Temp;
// 我定义的变量,用于将任务1中扫描获取的键盘值传递给任务0,但这样的全局变量在各任务间不可用
#define FEQ 15
#define sbi(Port, Bit) Port |= (1<<Bit)
#define cbi(Port, Bit) Port &= ~(1<<Bit)
#define eoi(Port, Bit) Port ^= (1<<Bit)
#define psv(Port, Bit) (Port&(1<<Bit))
// RTOS members
void OS_CreateTask(void (* pEntry)(void), unsigned char *pStack, unsigned char uTaskID);
void OS_StartTask(void);
void OS_ScheduleTask(void);
#define TASK_NUM 10
unsigned char uStack[500];
unsigned char uCurrentTask;
unsigned char uValidTaskIndex;
struct TASK_CONTROL_BLOCK
{
unsigned int uTaskStackEntry;
// add other members
}
TaskCtrlBlock[TASK_NUM];
int main(void)
{
Init_Timer0();
uCurrentTask=0;
uValidTaskIndex=0;
OS_CreateTask(OutputText,&uStack[49],0);
OS_CreateTask(ScanKeyboard,&uStack[99],1);
OS_CreateTask(LCDDisplay,&uStack[149],2);
OS_StartTask();
return 0;
}
void delay_ms(unsigned int ums)
{
while(--ums) _delay_loop_2(FEQ*250-2);
}
void Init_Timer0(void)
{
DDRB=0xFF;
PORTB=0x00;
DDRA = 0xFF;
PORTA = 0xFF;
TCNT0 = 0;
TCCR0 = 0;
TCCR0 = (1<<CS00);
TIMSK |= (1<<TOIE0);
}
SIGNAL(SIG_OVERFLOW0)
{
asm("JMP OS_ScheduleTask");
}
void OutputText(void)
{
for(;;)
{
// if( psv(PORTB,0) && psv(PORTB,1) && psv(PORTB,2) && psv(PORTB,3)) cbi(PORTA,1);
// else sbi(PORTA,1);
if(uKey_Temp == 0x0F) cbi(PORTA,1);
else sbi(PORTA,1);
}
}
void ScanKeyboard(void)
{
unsigned char uKey;
for(;;)
{
DDRD = 0xF0;
PORTD = 0x0F;
asm("nop");
if(PIND != 0x0F)
{
uKey = PIND;
DDRD = 0x0F;
PORTD = 0xF0;
asm("nop");
uKey |= PIND;
switch(uKey)
{
case 0x7E: uKey=0x00; break;
case 0xBE: uKey=0x01; break;
case 0xDE: uKey=0x02; break;
case 0xEE: uKey=0x03; break;
case 0x7D: uKey=0x04; break;
case 0xBD: uKey=0x05; break;
case 0xDD: uKey=0x06; break;
case 0xED: uKey=0x07; break;
case 0x7B: uKey=0x08; break;
case 0xBB: uKey=0x09; break;
case 0xDB: uKey=0x0A; break;
case 0xEB: uKey=0x0B; break;
case 0x77: uKey=0x0C; break;
case 0xB7: uKey=0x0D; break;
case 0xD7: uKey=0x0E; break;
case 0xE7: uKey=0x0F; break;
default: uKey=0xFF; break;
}
// Key down
if(uKey != 0xFF) PORTB = uKey;
uKey_Temp = uKey;
for(;PIND != 0xF0;); // Wait until key is up
// Key up
}
}
}
void LCDDisplay(void)
{
for(;;)
{
eoi(PORTA,0);
delay_ms(100);
}
}
// Real Time OS source code
void OS_CreateTask(void (* pEntry)(void), unsigned char *pStack, unsigned char uTaskID)
{
*pStack-- = (unsigned int)pEntry;
*pStack-- = (unsigned int)pEntry>>8;
TaskCtrlBlock[uTaskID].uTaskStackEntry = (unsigned int)pStack;
uValidTaskIndex++;
}
void OS_StartTask(void)
{
SP = TaskCtrlBlock[0].uTaskStackEntry;
TCNT0 = 0;
asm("reti
\t");
}
void OS_ScheduleTask(void)
{
asm("PUSH R2
\t");
asm("PUSH R3
\t");
asm("PUSH R4
\t");
asm("PUSH R5
\t");
asm("PUSH R6
\t");
asm("PUSH R7
\t");
asm("PUSH R8
\t");
asm("PUSH R9
\t");
asm("PUSH R10
\t");
asm("PUSH R11
\t");
asm("PUSH R12
\t");
asm("PUSH R13
\t");
asm("PUSH R14
\t");
asm("PUSH R15
\t");
asm("PUSH R16
\t");
asm("PUSH R17
\t");
asm("PUSH R18
\t");
asm("PUSH R19
\t");
asm("PUSH R20
\t");
asm("PUSH R21
\t");
asm("PUSH R22
\t");
asm("PUSH R23
\t");
asm("PUSH R24
\t");
asm("PUSH R25
\t");
asm("PUSH R26
\t");
asm("PUSH R27
\t");
asm("PUSH R28
\t");
asm("PUSH R29
\t");
asm("PUSH R30
\t");
asm("PUSH R31
\t");
TaskCtrlBlock[uCurrentTask].uTaskStackEntry = SP+33;
if(uCurrentTask >= uValidTaskIndex-1) uCurrentTask=0;
else uCurrentTask++;
SP = TaskCtrlBlock[uCurrentTask].uTaskStackEntry;
SP -= 33;
asm("POP R31
\t");
asm("POP R30
\t");
asm("POP R29
\t");
asm("POP R28
\t");
asm("POP R27
\t");
asm("POP R26
\t");
asm("POP R25
\t");
asm("POP R24
\t");
asm("POP R23
\t");
asm("POP R22
\t");
asm("POP R21
\t");
asm("POP R20
\t");
asm("POP R19
\t");
asm("POP R18
\t");
asm("POP R17
\t");
asm("POP R16
\t");
asm("POP R15
\t");
asm("POP R14
\t");
asm("POP R13
\t");
asm("POP R12
\t");
asm("POP R11
\t");
asm("POP R10
\t");
asm("POP R9
\t");
asm("POP R8
\t");
asm("POP R7
\t");
asm("POP R6
\t");
asm("POP R5
\t");
asm("POP R4
\t");
asm("POP R3
\t");
asm("POP R2
\t");
asm("POP R0
\t"); // 模拟中断
asm("OUT 0x3F,R0
\t"); // 恢复SREG状态
asm("POP R0
\t");
asm("POP R1
\t");
TCNT0 = 0;
asm("reti
\t");
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|