|
开发环境GCC WINAVR AMTEGA64,使用UCOS-II,目前开了两个线程,一个ADC不停中断循环转换,另外一个中断接受串口数据,发现ADC跑各2-3次就挂了,自动重新启,是不是中断处理不对,或者中断太频繁了,还是其他什么问题,但是我只开一个任务,比如点灯就没有问题,这让我百思不得其解,还望大家指点一下,谢谢
/*
**************************************************************************************************************
**************************************************************************************************************
*/
#include "includes.h"
/*
***************************************************************************************************
* CONSTANTS
***************************************************************************************************
*/
#define TASK_STK_SIZE OS_TASK_DEF_STK_SIZE // 每个任务的堆栈深度
#define N_TASKS 4 // 任务的数量
#define DEBUG
#define UART0_RX_BUF_SIZE 32
/*
***************************************************************************************************
* 变量定义
***************************************************************************************************
*/
OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; // 任务堆栈
OS_STK TaskStartStk[TASK_STK_SIZE];
INT8U UartRxBuf[UART0_RX_BUF_SIZE]; // UART1 接收缓冲区
INT16U UartRxRdPtr; // UART1 接收读指针
INT16U UartRxWrPtr; // UART1 接收写指针
INT16U UartRxCounter; // 收到的字节数
INT8U UartCmdRxComplete; // 串口命令接受完成
OS_EVENT *UartRxSem;
OS_EVENT *ADCOKSem;
OS_EVENT *SendSem;
void sendChar0(INT8U data)
{
while ( ! (UCSR0A & (1 << UDRE0) ) );
UCSR0A |= (1 << TXC0);
UDR0 = data;
while ( ! (UCSR0A & (1 << TXC0 ) ) );
}
/*
***************************************************************************************************
* 创建任务
***************************************************************************************************
*/
//主要任务
void TaskSerialProcess (void *data)
{
INT8U err=0;
data = data; /* Prevent compiler warning */
//INT8U tempstr[10] = {0};
// 把开定时中断0AvrInit()从移到这里
// TCCR1B = (1 << CS02); // 时钟预分频为 CLK/1024
// data = data;
PRINT("Waiting User Input Cmd .......\r
");
for (;;)
{
//发送查询当前状态命令
OSSemPend(UartRxSem,0,&err);
ProcessComand(UartRxBuf);
OSTimeDlyHMSM(0,0,0,1);
}
}
void TaskADCDataDaq (void *data)
{
unsigned char ADChannel=0;
INT8U err;
data = data; /* Prevent compiler warning */
for(ADChannel=0;ADChannel<4;ADChannel++)
{
g_adc_data_point[ADChannel] = 0;
}
ADChannel=0;
ADMUX = 0x40+(ADChannel);//参考源VCC,右对齐,选择0通道。
ADCSRA|=(1<<ADSC);//启动转换
for (;;)
{
OSSemPend(ADCOKSem,0,&err);
g_adc_data_point[ADChannel] = g_adc_data*7;
//PRINT("g_adc_data_point[%d] = %d,g_adc_data = %d\r
",ADChannel,g_adc_data_point[ADChannel],g_adc_data);
g_adc_data = 0;
ADChannel=(ADChannel<3)?(ADChannel+1):0;
ADMUX = 0x40+(ADChannel);//参考源VCC,右对齐,选择0通道。
//_delay_us(1);
OSTimeDlyHMSM(0,0,0,1);
ADCSRA|=(1<<ADSC);//启动转换
}
}
void TaskStart (void *data)
{
INT8U i;
//char s[10];
data = data; /* Prevent compiler warning */
/*
* Enabling of timer interrupt is moved from AvrInit() to here as suggested by to book
* JLu 01/2003 */
PRINT(">>>>>>>>>>The Real-Time Kernel,Vision %d<<<<<<<<<<<<<<<",(INT16U)OSVersion());
g_speaker_time = 5;
Speaker_ON();
OS_ENTER_CRITICAL();
/* TCCR0=0x05; /\* on some processors other than mega128 *\/ */
TCCR0=0x07; /* Set TIMER0 prescaler to CLK/1024 */
TIMSK=_BV(TOIE0); /* Enable TIMER0 overflow interrupt */
//#define TCNT0 _SFR_IO8(0x32)
TCNT0=256-(CPU_CLOCK_HZ/OS_TICKS_PER_SEC/1024); /* Set the counter initial value */
OS_EXIT_CRITICAL();
OSStatInit(); /* Initialize uC/OS-II's statistics */
UartRxSem = OSSemCreate(0);
UsbEventSem = OSSemCreate(0);
ADCOKSem = OSSemCreate(0);
OSTaskCreate(TaskSerialProcess, (void *)0, (void *)&TaskStk[0][TASK_STK_SIZE - 1], 1);
OSTaskCreate(TaskADCDataDaq, (void *)0, (void *)&TaskStk[2][TASK_STK_SIZE - 1], 3);
//PRINT("#TasksID : 0x%05x CPU Usage: %02d%\r
",(INT16U)OSTaskCtr,OSCPUUsage);
//PRINT("#Task switch/sec : %d \r
",(INT16U)OSCtxSwCtr);
OSCtxSwCtr = 0;
/////////////////////////使能看看门狗//////////////////////////////////////
/*
PRINT("Star Watch Dog....\r
");
WDR();
WDTCR = (1<<WDCE)|(1<<WDE);
WDTCR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0);
//g_WatchDogEn = 1;
*/
//////////////////////////////////////////////////////////////////////////
Speaker_OFF();
while(1)
{
WDR();
LedRun_ON();
for(i=0;i<5;i++)
{
OSTimeDlyHMSM(0,0,0,10);
OSTimeDly(1); // 延时0.1秒
if(g_speaker_time>0)
{
g_speaker_time--;
}
}
//OSTimeDlyHMSM(0,0,0,4);
LedRun_OFF();
for(i=0;i<5;i++)
{
OSTimeDly(10); // 延时0.5秒
if(g_speaker_time>0)
{
g_speaker_time--;
}
}
if(g_speaker_time>0)
{
Speaker_ON();
}
else
{
Speaker_OFF();
}
//OSSemPost(UsbEventSem);
}
}
/*
*************************************************************************************************
* 硬件的初始化
*************************************************************************************************
*/
void PortInit(void)
{
//不用的管脚使能内部上拉电阻。
DDRA=0xFF;
PORTA=0xFF;
}
//#define BAUDRATE 57600UL
#define BAUDRATE 115200UL
void AvrInit (void)
{
/////////////////////////关闭看门狗////////////////////////////////////
WDR();
WDTCR = (1<<WDCE)|(1<<WDE);
WDTCR |= 0B00010111;//(0<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0);
//////////////////////////////////////////////////////////////////////////
//串口0初始化
UCSR0B = 0x00;
UCSR0C = (1<<UCSZ1)|(1<<UCSZ0); //(1<<URSEL)|异步,8位数据,无奇偶校验,一个停止位,无倍速
UBRR0L = (F_CPU/BAUDRATE/16-1)%256; //设定波特率
UBRR0H = (F_CPU/BAUDRATE/16-1)/256;
UCSR0A = 0x00;
UCSR0B = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); //使能接收,使能发送
//UCSR0B = (1<<TXCIE)|(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);//使能接收中断,使能接收,使能发送
//外部SRAM/XMEM 使能
MCUCR |= (1 << SRE) | (1 << SRW10);
//等待两个时钟周期
XMCRA |= (1 << SRW11) | (1 << SRW01) | (1 << SRW00);
PortInit();
ADMUX = (0<<REFS1)|(1<<REFS0)|(0<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);//参考源VCC,右对齐,选择0通道。
ADCSRA= (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(0<<ADPS1)|(0<<ADPS0); //使能ADC,时钟128分频 125KHz@8MHz system clock
fdevopen((void*)sendChar0,0); //使用sendChar0作为输出
}
int main (void)
{
AvrInit(); // 硬件初始化
OSInit();
OSTaskCreate(TaskStart, (void *)0, (void *)&TaskStartStk[TASK_STK_SIZE - 1], 0);
PRINT("OS Star.....\r
");
OSStart(); // 开始多任务处理
return 0;
}
/****************************************************************************************/
/************************************OS中断处理******************************************/
/****************************************************************************************/
UCOSISR(SIG_ADC) //ADC中断服务程序
{
PushRS();
OSIntEnter();
if (OSIntNesting == 1)
OSTCBCur->OSTCBStkPtr = (OS_STK *)SP;
//硬件自动清除ADIF标志位
//int data;
g_adc_data=ADC; //读取结果
//g_adcInt_OK=1;
OSSemPost(ADCOKSem);//发送转换完成信号
OSIntExit();
PopRS();
}
//串口1接收到数据
UCOSISR(SIG_UART0_RECV)
{
uint8_t status,data;
PushRS();
OSIntEnter();
if (OSIntNesting == 1)
OSTCBCur->OSTCBStkPtr = (OS_STK *)SP;
// UartRxBuf[UartRxCounter++] = UDR0;
status=UCSR0A;
data=UDR0;
if ((status & (_BV(FE) | _BV(DOR) | _BV(UPE)))==0)
{
UartRxBuf[UartRxCounter]=data;
if (++UartRxCounter == UART0_RX_BUF_SIZE)
{
UartRxCounter=0;
}
}
sendChar0(data);
if(data=='\r')
{
unsigned char i;
if(UartRxCounter<UART0_RX_BUF_SIZE)
{
for(i = UartRxCounter;i<UART0_RX_BUF_SIZE;i++)
UartRxBuf = '\0';
UartRxCounter = 0;
sendChar0('
');
sendChar0('-');
sendChar0('>');
OSSemPost(UartRxSem);//发送数据接受完成信号
}
}
OSIntExit();
PopRS();
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|