⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.c

📁 这是一个UCOS的AVR移植程序
💻 C
字号:
/*
**************************************************************************************************************

**************************************************************************************************************
*/

#include "includes.h"

/*
***************************************************************************************************
*                                               CONSTANTS
***************************************************************************************************
*/

#define  TASK_STK_SIZE  OS_TASK_DEF_STK_SIZE          // 每个任务的堆栈深度
#define  N_TASKS        3                             // 任务的数量


#define DEBUG

#define RLED_OFF ( PORTB |= (1 << PB2) )
#define RLED_ON  ( PORTB &= ~(1 << PB2) )


#define GLED_OFF ( PORTB |= (1 << PB1) )
#define GLED_ON ( PORTB &= ~(1 << PB1) )


/***********************************************************/
/* 485输出输入控制宏  */
/***********************************************************/
#define SERIAL_SEND       	(  PORTB |= (1 << PB6) )
#define SERIAL_RECEIVE     	(  PORTB &= ~(1 << PB6) )


#define UART0_RX_BUF_SIZE 32


/*
***************************************************************************************************
*                                        变量定义
***************************************************************************************************
*/

OS_STK          TaskStk[N_TASKS][TASK_STK_SIZE];        // 任务堆栈



INT8U           UartRxBuf[UART0_RX_BUF_SIZE];           // UART1 接收缓冲区
INT16U          UartRxRdPtr;                            // UART1 接收读指针
INT16U          UartRxWrPtr;                            // UART1 接收写指针
INT16U          UartRxCounter;                            // 收到的字节数
OS_EVENT       *UartRxSem;


OS_EVENT       *ButtonSem;

OS_EVENT       *TestSem;
OS_EVENT       *SendSem;



//拷贝接收缓存数据
INT8U stringCopy( INT8U tempstr[])
{
	INT8U i,temp;
	for (i=0,temp=0;(UartRxBuf[i+1] != 0 || UartRxBuf[i+2] != 0);i++)
	{
		temp ^= UartRxBuf[i];			
	}
	if(temp == UartRxBuf[i])//传输校验正确
	{
		strcpy(tempstr,UartRxBuf);
		return 1;
	}
	else 
	{
		return 0;
	}
}



//*************************************************/
//名称:sendChar1
//功能:字符输出函数
//说明:只适合单个字节的发送
//输入:data
//输出:无
//调用:无
//*************************************************/

void sendChar1(INT8U data)
{
	OS_ENTER_CRITICAL();
	SERIAL_SEND;
	while ( ! (UCSR1A & (1 << UDRE1) ) );
	UCSR1A |= (1 << TXC1);
	UDR1 = data;
	while ( ! (UCSR1A & (1 << TXC1 ) ) );
	SERIAL_RECEIVE;
	OS_EXIT_CRITICAL();
}

//*************************************************/
//名称:clearBuf
//功能:清空接收缓存
//说明:
//输入:无
//输出:无
//调用:无
//*************************************************/

void clearBuf(void)
{
	INT8U i;
	for (i=0;i<UartRxCounter;i++)
	{
		UartRxBuf[i] = 0;
	}
	UartRxCounter = 0;
}

//*************************************************/
//名称:Printf
//功能:字符串输出函数
//说明:只适合发送字符串数据
//输入:pointer
//输出:无
//调用:sendChar1
//*************************************************/

void Printf(INT8U *pointer)
{
	while(*pointer || *(pointer+1))
	{	
		sendChar1(*pointer++);
	}
}

//*************************************************/
//名称:HexToAscii
//功能:将十六进制数转为ASCII码
//说明:无
//输入:data
//输出:无
//调用:无
//*************************************************/

INT8U HexToAscii(INT8U data)
{
	if (data > 9)
		return (data + 0x37);
	else 
		return (data + 0x30);
}
	


#ifdef DEBUG

void sendChar0(INT8U data)
{
	while ( ! (UCSR0A & (1 << UDRE0) ) );
	UCSR0A |= (1 << TXC0);
	UDR0 = data;
	while ( ! (UCSR0A & (1 << TXC0 ) ) );
}

void  Put_Byte(INT8U data)
{
	sendChar0(HexToAscii( (data >> 4) & 0x0F) );
	sendChar0(HexToAscii( (data & 0x0F) ) );
}


//串口0发送字符串
void Print(INT8U *pointer)
{
	while (*pointer)
	{
		sendChar0(*pointer++);
	}
}

#endif



/*
***************************************************************************************************
*                                              创建任务
***************************************************************************************************
*/


//主要任务
void Task1 (void *data)
{
	INT8U err=0;
	INT8U tempstr[10] = {0}; 
	
	//	把开定时中断0AvrInit()从移到这里
	TCCR1B = (1 << CS02);                                   	 // 时钟预分频为 CLK/1024   

	
	data = data;
	
	
	for (;;)
	{
		
		//发送查询当前状态命令
		Printf("testState");
		OSSemPend(UartRxSem,0,&err);
		if(stringCopy(tempstr))//传输校验正确
		{
			Printf("do something");//发送动作的命令
		}
		OSTimeDlyHMSM(0,0,1,0);
	}
}


void Task2 (void *data)
{
	//INT8U err;
	
	data = data;
	
	
	for (;;)
	{
		
		GLED_ON;
		OSTimeDly(50);            // 延时0.5秒
		GLED_OFF;
		OSTimeDly(50);            // 延时0.5秒
		
	}
}

void Task3 (void *data)
{
	INT8U rdata[8];//从1302中读出的数据
	
	data = data;
	
	chipClockStart(1);//打开时钟
	
	for (;;)
	{
		burstModeTimeRead(rdata);
		Print("\n date: ");
		Put_Byte(rdata[6]);
		Print("/");
		Put_Byte(rdata[4]);
		Print("/");
		Put_Byte(rdata[3]);
		Print("  time:  ");
		Put_Byte(rdata[2]);
		Print(":");
		Put_Byte(rdata[1]);
		Print(":");
		Put_Byte(rdata[0]);
		OSTimeDlyHMSM(0,0,5,0);
	}
	
}


/*
*************************************************************************************************
*                                           硬件的初始化
*************************************************************************************************
*/

void AvrInit (void)
{
	
	//串口1初始化
	UBRR1L = 95;//波特率设为9600 晶振14.7456MHz      
	UCSR1B = (1 << TXEN1) | (1 << RXEN1) | (1 << RXCIE1); //允许发送和接收并允许接收中断
	
	UBRR0L = 47;//波特率设为19200 晶振14.7456MHz      
	UCSR0B = (1 << TXEN0) ; //允许发送
	
	//外部SRAM/XMEM 使能	
	MCUCR |= (1 << SRE) | (1 << SRW10);
	//等待两个时钟周期
	XMCRA |= (1 << SRW11) | (1 << SRW01) | (1 << SRW00);
	
	//定时器 1 (系统时钟)/ 2 (串口超时判断) 初始化
	TCCR1B = 0;                                        	//  暂停计数
	TCCR2 = 0;                                        	//  暂停计数
	TIMSK = (1 << TOIE1) | (1 << TOIE2) ;                //  允许定时器 0 / 2 溢出中断         
	TCNT1 = 65535 - (CPU_CLOCK_HZ / OS_TICKS_PER_SEC / 256);   	//  定时常数              
	TCNT2 = 195;											//  初值
	
	//485输出控制端口
	DDRB |= (1 << PB6);//输出
	PORTD |= (1 << PD2); //RX0引脚使用内部上拉电阻
	
	
	//LED控制
	DDRB |= ( 1<< PB1);//GLED
	DDRB |= ( 1<< PB2);//RLED
	GLED_OFF;
	RLED_OFF;
	
	//DS1302控制线
	DDRB |= (1 << PB3);//SCK
	DDRB |= (1 << PB5);//RST
}




int main (void)
{
	AvrInit();                                          // 硬件初始化
	OSInit();
	UartRxSem  = OSSemCreate(0);         				// 初始化发送缓冲区
	OSTaskCreate(Task1, (void *)0, (void *)&TaskStk[0][TASK_STK_SIZE - 1], 1);
	OSTaskCreate(Task2, (void *)0, (void *)&TaskStk[1][TASK_STK_SIZE - 1], 2);
	OSTaskCreate(Task3, (void *)0, (void *)&TaskStk[2][TASK_STK_SIZE - 1], 3);
	OSStart();                                          // 开始多任务处理
	return 0;
}


/****************************************************************************************/
/************************************OS中断处理******************************************/
/****************************************************************************************/

//串口1接收到数据
UCOSISR(SIG_UART1_RECV)
{
	
	PushRS();
	OSIntEnter();
	if (OSIntNesting == 1)
	OSTCBCur->OSTCBStkPtr = (OS_STK *)SP;
	
	UartRxBuf[UartRxCounter++] = UDR1;
	TCNT2 = 195;
	TCCR2 =  (1 << CS22);//256分频

	OSIntExit();
	PopRS();
}

//定时器2中断,判断串口接收完成
UCOSISR(SIG_OVERFLOW2)
{
	PushRS();
	OSIntEnter();
	if (OSIntNesting > 0)
	OSTCBCur->OSTCBStkPtr = (OS_STK *)SP;
	
	TCCR2 = 0;//关闭定时器
	OSSemPost(UartRxSem);
	
	OSIntExit();
	PopRS();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -