|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
我采用的是iicavr编译器,用C编写的应用程序.
(1)操作系统已经能在板子上跑起来
(2)创建两个任务通过邮箱实现对灯的控制也已经实现.
(3)串口收发函数在不运行操作系统时已经实现收发自如了.(采用1002,1003数据格式的传输)
(4)运行操作系统后,发一串数,半天才能返回,有时返回还是错误的.
(5)如果运行操作系统又运行任务邮箱通信,则收发数据就没响应了.
大虾帮我啊,跪谢!!.
应用程序如下:
#include "includes.h"
#define CPU_CLK_FREQ 3686400
#define OS_TASK_STK_SIZE 240
#define OS_TASK_HARD_STK_SIZE 64
#define OS_TASK_START_STK_SIZE OS_TASK_STK_SIZE
#define OS_TASK_START_HARD_STK_SIZE OS_TASK_HARD_STK_SIZE
#define OS_TASK_1_STK_SIZE OS_TASK_STK_SIZE
#define OS_TASK_1_HARD_STK_SIZE OS_TASK_HARD_STK_SIZE
#define OS_TASK_2_STK_SIZE OS_TASK_STK_SIZE
#define OS_TASK_2_HARD_STK_SIZE OS_TASK_HARD_STK_SIZE
#define OS_TASK_2_STK_SIZE_HARD OS_TASK_HARD_STK_SIZE
#define OS_TASK_1_STK_SIZE_HARD OS_TASK_HARD_STK_SIZE
OS_STK AppTaskStackStk[OS_TASK_START_STK_SIZE];
OS_STK ReceiverTaskStk[OS_TASK_2_STK_SIZE];
OS_STK SenderTaskStk[OS_TASK_1_STK_SIZE];
OS_EVENT *pReceiverMailBox; /*接收邮箱*/
OS_EVENT *pSenderMailBox; /*发送邮箱*/
INT8U receive[50];
INT8U n=0;
INT8U a=0;
INT16U crcw;
INT16U cal_crc(INT8U *ptr, INT8U len);
void TimeDly_1ms(void);
void uart0_tx(INT8U data);
void OSTimeDlyHM(INT16U n);
void ReceiverTask(void *p_arg);
void SenderTask(void *p_arg);
void OSTickISR_Init(void);
void OSTickISR_Handler (void);
void OSTickISR_Handler (void)
{
TCNT0 = 256 - (CPU_CLK_FREQ / OS_TICKS_PER_SEC / 1024); /* TCNT0为8位T/C寄存器*/
OSTimeTick();
}
void port_init(void)
{
DDRA = 0xFF;
PORTA = 0xFF;
DDRC = 0xFF;
PORTC = 0xFF;
DDRB = 0xFF;
PORTB = 0xFF;
DDRD = 0xFF;
PORTD = 0xFF;
DDRE = 0xFD;
PORTE = 0xFF;
DDRF = 0xFF;
PORTF = 0xFF;
DDRG = 0x1F;
PORTG = 0x1F;
}
//UART0 initialisation
// desired baud rate: 9600
// actual: baud rate:9600 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00;
UCSR0C = 0x06;
UBRR0L = 0x17; //set baud rate lo
UBRR0H = 0x00; //set baud rate hi
UCSR0B = 0x98;
}
#pragma interrupt_handler uart0_rx_isr:19
void uart0_rx_isr(void)
{
INT16U i;
receive[n]=UDR0;
n++;
//CLI();
PORTF^=0x02;
switch (n)
{
case 1:
if (receive[0]!=0x10) n=0;
break;
case 2:
if(receive[1]!=0x02) n=0;
break;
default:
if(receive[n-1]==0x10) a++;
if((receive[n-1]==0x10)&&(receive[n-2]==0x10)&&(a==2))
{
n--;
a=0;
break;
}
if((receive[n-2]==0x10)&&(receive[n-1]==0x02)&&(a==1))
{
receive[0]=0x10;
receive[1]=0x02;
n=2;
a=0;
break;
}
if((receive[n-2]==0x10)&&(receive[n-1]==0x03)&&(a==1))
{
for(i=0;i<(n-4);i++)
receive=receive[i+2];
n-=4;
a=0;
crcw=cal_crc(receive,n);
if(crcw==0)
{
for(i=0;i<n;i++)
uart0_tx(receive);
n=0;
}
else {
uart0_tx(0xff);
n=0;
}
break;
}
break;
}
}
//call this routine to initialise all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
XDIV = 0x00; //xtal divider
XMCRA = 0x00; //external memory
port_init();
uart0_init();
MCUCR = 0x00;
EICRA = 0x00; //extended ext ints
EICRB = 0x00; //extended ext ints
EIMSK = 0x00;
TIMSK = 0x00; //timer interrupt sources
ETIMSK = 0x00; //extended timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialised
}
//
void main(void)
{
init_devices();
/*while (1)
{
}*/
//SREG|=0x80;
//设置初始栈的大小
OSTaskStkSize = OS_TASK_STK_SIZE;
OSTaskStkSizeHard = OS_TASK_HARD_STK_SIZE;
//Initialize the OS
OSInit();
pReceiverMailBox = OSMboxCreate((void*)0); //创建接收邮箱
pSenderMailBox = OSMboxCreate((void*)0); //创建发送邮箱
//Create the SenderTask
OSTaskStkSize = OS_TASK_1_STK_SIZE; // Setup the default stack size
OSTaskStkSizeHard = OS_TASK_1_HARD_STK_SIZE; // Setup the default hardware stack size
OSTaskCreate(ReceiverTask, (void *)0, (OS_STK *)&ReceiverTaskStk[OSTaskStkSize - 1], 1);
// Create the ReceiverTask
OSTaskStkSize = OS_TASK_2_STK_SIZE; // Setup the default stack size
OSTaskStkSizeHard = OS_TASK_2_HARD_STK_SIZE; // Setup the default hardware stack size
OSTaskCreate(SenderTask, (void *)0, (OS_STK *)&SenderTaskStk[OSTaskStkSize - 1], 0);
OSStart();
}
void OSTickISR_Init (void)
{
TCCR0 = 0x07; // Set TIMER0 prescaler to CLK/1024
TIMSK = 0x01; // Enable TIMER0 overflow interrupt
}
/*
//*********************************************************************************************************
//* 发送任务
//*********************************************************************************************************
*/
void SenderTask (void *p_arg)
{
INT16U count=0;
INT8U error;
INT8U count1=0xfd;
INT8U count2=0xff;
p_arg = p_arg;
while (1)
{ //asm("cbi 0x18,7"); // PORTB^=0x80,PB7控制看门狗,因PB1,PB2控制灯,所以直接异或影响灯的闪烁,这里采用嵌入式编实现,该句为置0
count=abs(count-1);
switch(count)
{
case 0:
OSMboxPost(pSenderMailBox, (void*)&count1);
break;
case 1:
OSMboxPost(pSenderMailBox, (void*)&count2);
break;
}
//asm("sbi 0x18,7"); //该句为置1
OSMboxPend(pReceiverMailBox, 0, &error);
}
}
/*
*********************************************************************************************************
* 接收任务
*********************************************************************************************************
*/
void ReceiverTask (void *p_arg)
{ INT8U c;
INT8U *temp;
INT8U error;
p_arg = p_arg;
OSTickISR_Init();
while (1)
{
temp = (INT8U*)OSMboxPend(pSenderMailBox, 0, &error);
//PORTF=*temp;
OSTimeDlyHM(500);
OSMboxPost(pReceiverMailBox, (void*)1);
}
}
void TimeDly_1ms(void)
{
INT16U i;
for (i = 1 ; i< (INT16U)((CPU_CLK_FREQ/1000000) * 143 - 2) ; i++ )
{
}
}
void OSTimeDlyHM(INT16U n)
{
INT16U i;
for (i = 0; i < n; i++)
{
TimeDly_1ms();
}
}
void uart0_tx(INT8U data)
{
UDR0=data;
while (!(UCSR0A & 0x40))
{
}
UCSR0A|=0X40;
}
//CCITT-16 CRC;(X16+X12+X5+1)
INT16U cal_crc(INT8U *ptr, INT8U len)
{
INT8U i;
INT16U crc=0;
while(len--!=0)
{
for(i=0x80; i!=0; i/=2)
{
if((crc&0x8000)!=0)
{
crc*=2; crc^=0x1021;
}
else crc*=2;
if((*ptr&i)!=0) crc^=0x1021;
}
ptr++;
}
return(crc);
}
是不是#pragma interrupt_handler uart0_rx_isr:19不行啊?
谢谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[ 本帖最后由 wangbaocai1984 于 2006-10-17 17:02 编辑 ] |
|