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

📄 test.c

📁 在MICROCHIP的PIC18F2520上移植UCOSII操作系统
💻 C
字号:
#pragma config OSC=INTIO67,FCMEN=OFF,IESO=OFF
#pragma config PWRT=OFF,BOREN=SBORDIS,BORV=2  //power-up timer
#pragma config WDT=OFF,WDTPS=32768
#pragma config CCP2MX=PORTC,PBADEN=OFF,MCLRE = ON, LPT1OSC = OFF 
#pragma config STVREN=OFF,LVP=OFF,XINST=OFF
#pragma config CP0=OFF,CP1=OFF
#pragma config DEBUG=ON
#pragma config CPD=OFF,CPB=OFF
#pragma config WRT0=OFF,WRT1=OFF
#pragma config WRTB=OFF,WRTC=OFF,WRTD=OFF
#pragma config EBTR0=OFF,EBTR1=OFF
#pragma config EBTRB=OFF

#include    ".\portable\includes.h"
#include    <timers.h>
#include    <delays.h>
#include    <string.h>
#include    <stdlib.h>
#include    "mydefine.h"

#define TASK_STK_SIZE 60L
#define Qmsg_Size   10

//Application tasks IDs
#define task2RateID		0
#define RateAdjID			1
#define FaultCheckID		2
#define SerialReceiveID		3
//#define SerialSendID		4
// Application tasks priorities
#define task2RatePRIO  	11
#define RateAdjPRIO 		12
#define FaultCheckPRIO 	10
#define SerialReceivePRIO 	13
//#define SerialSendPRIO	14




//定义任务堆栈大小;
OS_STK task2RateStk[TASK_STK_SIZE];
OS_STK RateAdjStk[TASK_STK_SIZE];
OS_STK FaultCheckStk[TASK_STK_SIZE];
OS_STK SerialReceiveStk[TASK_STK_SIZE];
//OS_STK SerialSendStk[TASK_STK_SIZE];
//函数定义声明	
void Systeminitialall(void);//系统初始化函数包括中断,变量,端口状态
void initialUSART(INT8U); 
void Time0initial();
void OS_SEM_Initial(void);

void task2Rate(void *pdata);//
void RateAdj(void *pdata);//
void FaultCheck(void * pdata);//
void SerialReceive(void * pdata);//
void SerialSend(void);//

INT8U eeprom_read(INT8U address);
void eeprom_write(INT8U address,INT8U datavalue);


typedef union //定义字与字节之间的转换结构,便于转换
{
    INT16U intword;
    INT8U charbyte[2];
}wordbyte;

//串口缓冲区结构

SerialBuffer  ReceiveBuf;//串口接收缓冲区
//通信协议部分
//INT8U Uartchar=0;  //Uart temp data;
INT8U ReceiveNum = 0;//接收字符数
INT8U  ReceivedataNum = 0;//接受数据的个数
INT8U SendDateNum= 0 ;

INT8U  ReceiveCheckSum = 0;
INT8U  ReceiveDataError = 0;
INT8U  DoCommand = 0;


//变量定义
//系统状态
INT8U work_state_flag= workinnormal;			//工作状态0为正常工作1为调试状态	

INT16U	splittemp = 0;  
INT16U	realfreq = 0;

INT8U	plus2speed[101];	//表,查表获得值
const rom INT8U plus2speedf[101]={
	0,
	2,4,6,8,10,12,14,16,18,20,
	22,24,26,28,30,32,34,36,38,40,
	42,44,46,48,50,52,54,56,58,60,
	62,64,66,68,70,72,74,76,78,80,
	82,84,86,88,90,92,94,96,98,100,
	102,104,106,108,110,112,114,116,118,120,
	122,124,126,128,130,132,134,136,138,140,
	142,144,146,148,150,152,154,156,158,160,
	162,164,166,168,170,172,174,176,178,180,
	182,184,186,188,190,192,194,196,198,200
};    

INT8U 	TMR3OVERflag = 0;//计数时Timer3的溢出次数
INT8U 	First_plus_flag = 0;//第一个沿标志

INT8U	RateValueGet = 0;//查速度表所得到的速度
INT16U	RateValueGettemp = 0;
INT24U   Rate2adjust = 0;//要调整到的速度给定

INT24U 	RateTested_temp;
INT8U	RateTested;//测到的速度
INT8U 	PWMValue=0;//要赋给PWM值

INT8U	speed_or_temp = 0;//标志位
INT8U	temperature;//温度值
INT8U	temperatureAD = 50;
INT8U	speed_modifyAD =128;//速度修正值
INT16U	speed_modifytemp = 0;
INT8U i;

INT8U err1,err2,err3,err4;
OS_EVENT *plus2speedMutex;//接收与调整之间的信号量
OS_EVENT *S_ReceiveSem;  //接收消息
OS_EVENT *FaultCheckmesQueue;//错误消息队列
void *QmsgTbl[Qmsg_Size];
INT8U Qmsg_Queue[5];
INT8U Qmsg_temp1[2];
INT8U Qmsg_temp2[2];
OS_EVENT *UartSendMutex;//串口发送信号量
void main (void)
{
	//SystemStateCheck();
	//PORTC初始化
	PORTC = 0;
	LATC = 0;
	TRISC = 0x12;	//PC0,PC3,PC2为数字输出,PC1,PC4为数字输入
	if(!PORTCbits.RC4)
	{
/*			Delay10KTCYx(500);
			Delay10KTCYx(500);
			Delay10KTCYx(500);
			Delay10KTCYx(500);
			Delay10KTCYx(500);
			Delay10KTCYx(500);
			Delay10KTCYx(500);
			Delay10KTCYx(500);
			Delay10KTCYx(500);
*/
			if(PORTCbits.RC4)
			{ 
				work_state_flag = workinnormal;//进入正常工作模式
			}
			else
			{
				work_state_flag = workindebug;//进入调试模式
			}
	}
	else  work_state_flag = workinnormal;
	work_state_flag = workinnormal;
	Systeminitialall();	//系统初始化(端口初始化)
	OSInit();//OS系统初始化
	//任务一
	OSTaskCreate(task2Rate,(void *)0,&task2RateStk[TASK_STK_SIZE],task2RatePRIO);
	//任务二
	OSTaskCreate(RateAdj,(void *)0,&RateAdjStk[TASK_STK_SIZE],RateAdjPRIO);
	//任务三
	OSTaskCreate(FaultCheck,(void *)0,&FaultCheckStk[TASK_STK_SIZE],FaultCheckPRIO);
	//创建串口接收函数,
	if(work_state_flag == workindebug)
	{
		OSTaskCreate(SerialReceive,(void *)0,&SerialReceiveStk[TASK_STK_SIZE],SerialReceivePRIO);
	}
	 OSStart();//启动操作系统调度
}

void Systeminitialall(void)
{
	OSCTUNE = 0xC0;//内部时钟,使能PLL
	OSCCON = 0x72;
	//to initial the system include port status ,interrupt,and variable
		//PORTA初始化
	PORTA = 0;
	LATA = 0;
	TRISA = 0x33;	
	ADCON1 = 0x0D;	//PA0,PA1为模拟输入,PA5,PA4为数字输入,PA2,PA3为数字输出
	//PORTB初始化
	PORTB = 0;
	LATB = 0;
	TRISB =0x07;	//PB0,PB1,PB2为中断输入
	//PORTC初始化
	PORTC = 0;
	LATC = 0;
	TRISC = 0x12;	//PC0,PC3,PC2为数字输出,PC1,PC4为数字输入
}

void OS_SEM_Initial(void)
{
		
	S_ReceiveSem= OSSemCreate(0);
	plus2speedMutex = OSMutexCreate(9, &err2);
	FaultCheckmesQueue = OSQCreate(&QmsgTbl[0], Qmsg_Size);
	UartSendMutex= OSMutexCreate(6, &err3);
	OSMutexPend(UartSendMutex, 0, &err3);
}


void Time0initial()
{
	INTCONbits.TMR0IE = 0;
	INTCONbits.TMR0IF = 0;
	INTCON2bits.TMR0IP = 0;                  // clear interrupt flag
    	TMR0H = 0xB1;                           // set the timer to expire in 10 ms. (at 4MHz)
    	TMR0L = 0xDF;
	T0CON = 0x01;//分频器为四分频
	RCON = 0x80;
	INTCONbits.TMR0IE = 1;
	T0CONbits.TMR0ON = 1;
	INTCONbits.PEIE = 1;//开所有低中断
}
void initialUSART(INT8U spbrg)          //207 =>9600//51=>38400
{
  TXSTA = 0;           // Reset USART registers to POR state
  RCSTA = 0;

  SPBRG = spbrg;       // Write baudrate to SPBRG1
  SPBRGH = spbrg >>8; // For 16-bit baud rate generation 
  TXSTAbits.BRGH = 1;    // Baud rate select (asychronous mode only)

  TXSTAbits.SYNC = 0;   // Sync or async operation
  RCSTAbits.SPEN = 1;  // Enable receiver

  PIR1bits.RCIF = 0;
  PIE1bits.RCIE = 1;  // Interrupt on receipt
  PIE1bits.TXIE = 1; 
  PIR1bits.TXIF = 0;

	
  TXSTAbits.TX9 = 0;
  RCSTAbits.RX9 = 0;      // 8- or 9-bit mode
  RCSTAbits.ADDEN = 0;

  TXSTAbits.TXEN = 0;  //发送时再启动这一位

  RCSTAbits.CREN = 1;

  TRISCbits.TRISC5 = 0;
  TRISCbits.TRISC6 = 0;
  TRISCbits.TRISC7 = 1;
  PORTCbits.RC5 = 0;
  LATCbits.LATC5 = 0;

}
void task2Rate(void *pdata)
{
	INT8U ijk = 50;
	pdata = pdata;
	Time0initial();//第一个任务,Timer0初始化
	
	while(1)
	{
		OSTimeDly(100);//延时1秒
	}
}
void SerialReceive(void * pdata)
{	
	INT8U j;
	pdata = pdata;
	//receiver task initialize 
	INTCON3bits.INT2IE = 0;//if in debug mode ,taskcounter if forbid
	INTCON3bits.INT1IE = 0;//plus_number will get from serial given
	PIE1bits.RCIE = 1; 
	while(1)
	{
	OSSemPend(S_ReceiveSem, 0, &err1);
	ReceiveNum = 0;
	PIE1bits.RCIE = 0;
	ReceiveCheckSum = 0;
	ReceiveCheckSum	= ReceiveBuf.RBuffer.S_Begin[0]+ReceiveBuf.RBuffer.S_Begin[1]+ReceiveBuf.RBuffer.S_Command+ReceiveBuf.RBuffer.S_Length;
	if((ReceiveBuf.RBuffer.S_Length>100)||(ReceiveBuf.S_Buffer[ReceiveBuf.RBuffer.S_Length+5]!=DataSendEnd))ReceiveDataError = 1;
	else 
	{
		for(ReceivedataNum=0;ReceivedataNum<ReceiveBuf.RBuffer.S_Length;ReceivedataNum++)
		{
			ReceiveCheckSum +=	ReceiveBuf.S_Buffer[4+ReceivedataNum];
		}
		if(ReceiveCheckSum == ReceiveBuf.S_Buffer[ReceiveBuf.RBuffer.S_Length+4])
		{
			ReceiveDataError = 0;
		}
		else ReceiveDataError = 1;
	}
				
	if(ReceiveDataError == 1)
	{	
		ReceiveBuf.RBuffer.S_Command = ReceiveDataErrorCom;
		ReceiveBuf.RBuffer.S_Length = 1;
		ReceiveBuf.RBuffer.S_Data[0]= 1;
		SerialSend();

	}
	else
	{
		DoCommand = ReceiveBuf.RBuffer.S_Command;
		switch (DoCommand)
		{
			case  3:{	//设置通信端口号,返回01 01 01 代码
					eeprom_write(Comm_Port_ADR,ReceiveBuf.RBuffer.S_Data[0]);
					ReceiveBuf.RBuffer.S_Command  = 1;
					ReceiveBuf.RBuffer.S_Length = 1;
					ReceiveBuf.RBuffer.S_Data[0] = 1;
					SerialSend();
					break; 
					}//set the is left or right
			case  4:{	//读取eeprom 信息//send pc the board information
										
					for(j=0;j<6;j++)
					{
						ReceiveBuf.RBuffer.S_Data[j] = eeprom_read(j+SerialNum_ADRH);
					}
					ReceiveBuf.RBuffer.S_Command = 0x04;
					ReceiveBuf.RBuffer.S_Length = 0x06;
					SerialSend();
					break;
					}
		case  8: {
					
					for(j=0;j<100;j++)
					{
						ReceiveBuf.RBuffer.S_Data[j] = eeprom_read(i+RATETABLESTART);
					}
					ReceiveBuf.RBuffer.S_Command = 0x08;
					ReceiveBuf.RBuffer.S_Length = 100;
					SerialSend();
					break;
				}
									 
		case 9:	{	break;
				 }
		case 10:  {
									break;									
								}
									//

			case  11:{	//写100个数据到EEPROM
						for(j=0;j<100;j++)
						{
							eeprom_write(i+RATETABLESTART,ReceiveBuf.RBuffer.S_Data[j]);
						}
						ReceiveBuf.RBuffer.S_Command  = 1;
						ReceiveBuf.RBuffer.S_Length = 1;
						ReceiveBuf.RBuffer.S_Data[0] = 1;
						SerialSend();
						break;
					}
						

			case  17:{

					}

			case  18:{//测试使用代码段
									
						break;
					}						
						
									
			default:{		

						break; 
				}
		}

	}
	PIE1bits.RCIE = 1;

	}

}

void SerialSend()
{
	
	unsigned char k = 0;
	PIE1bits.RCIE = 0;
	PORTCbits.RC5 = 1;
	ReceiveBuf.RBuffer.S_Begin[0]= DataSendHead1;
	ReceiveBuf.RBuffer.S_Begin[1]= DataSendHead2;
	ReceiveBuf.RBuffer.S_ErrorCheck = 0;
	for(k=0;k<ReceiveBuf.RBuffer.S_Length+4;k++)
	ReceiveBuf.RBuffer.S_ErrorCheck += ReceiveBuf.S_Buffer[k];
	ReceiveBuf.RBuffer.S_END = DataSendEnd;

	SendDateNum  = ReceiveBuf.RBuffer.S_Length+6;
	//for(ReceivedataNum=0;ReceivedataNum< ReceiveBuf.RBuffer.S_Length+6;ReceivedataNum++)
	//{
		TXSTAbits.TXEN = 1; 
		//TXREG = ReceiveBuf.S_Buffer[ReceivedataNum];
		OSMutexPend(UartSendMutex, 0, &err3);

	//} 
	PORTCbits.RC5 = 0;
	if(RCSTAbits.OERR){
	RCSTAbits.CREN = 0;//由于发送时可能出现上下位机的冲突,用此来清除错误位
	RCSTAbits.CREN = 1;}
	PIE1bits.RCIE = 1;
	ReceiveBuf.RBuffer.S_Begin[0] = 0xAA;//任意数值
	ReceiveBuf.RBuffer.S_Begin[1] = 0xBB;	

}
void FaultCheck(void * pdata)
{
	INT8U* qmsg;
	pdata = pdata;
	while(1)
	{
		qmsg = (INT8U*)OSQPend(FaultCheckmesQueue, 0, &err4);
		//OSQPost(FaultCheckmesQueue, (void *)&QmsgTbl[0]);
		switch(*qmsg){
			case 1:break;
			case 2:break;
			case 3:break;
			default:break;
			}
		//voltage alarm
		//temperature alarm 
		//motor  
		OSTimeDly(100);

	}

}


INT8U eeprom_read(INT8U address)
{
	EEADR = address; //write address to EEADR
	EECON1bits.EEPGD = 0;       // EEPROM select
	EECON1bits.RD = 1;           //start eeprom read
	return EEDATA;
}

void eeprom_write(INT8U address,INT8U datavalue)
{
	EEADR = address; //address
	EEDATA= datavalue; //data to write
	EECON1bits.EEPGD = 0; //EEPROM select
	EECON1bits.CFGS = 0;  //access EEPROM
	EECON1bits.WREN = 1;  //write enable
	INTCONbits.GIE = 0;   //close interrupt
	EECON2 = 0x55; 
	EECON2 = 0xAA;//
	EECON1bits.WR = 1;  //start write
	INTCONbits.GIE = 1 ;//open interrupt
	while(EECON1bits.WR);//ClrWdt();//when write over wr=0;
	EECON1bits.WREN = 0;  //forbid write

}
				

⌨️ 快捷键说明

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