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

📄 main.c

📁 基于微芯力公司的STR71x开发平台的ARM7
💻 C
字号:
#include "71x_lib.h"
#include "ledkey.h"
#include "lcdlib.h"
#include <ucos_ii.h>

extern void OSLedCodeDisp(u8 digit,u8 num);
extern void OSEnableLedKey(void);


#define UART0_Rx_Pin (0x0001<<8)   // TQFP 64: pin N?63 , TQFP 144 pin N?143
#define UART0_Tx_Pin (0x0001<<9)   // TQFP 64: pin N?64 , TQFP 144 pin N?144


//#define STKSIZE 128
//#define STACKSIZE 128
#define STACKSIZE 256


//注意最低优先级已经在OS_CFG.H中设定为15

///******************任务定义***************///

OS_STK Main_Stack[STACKSIZE]={0, };   //Main_Test_Task堆栈
void Main_Task(void *Id);               //Main_Task
#define Main_Task_Prio     10			//Main_Task优先级


OS_STK Key_Scan_Stack[STACKSIZE]= {0, }; //key scan stack
void Key_Scan_Task(void *Id);            //key scan任务
#define Key_Scan_Prio        5			//key scan优先级

OS_STK Task1_Stack[STACKSIZE]= {0, }; 	//task1 stack
void Task1(void *Id);            	  	//task1 任务
#define Task1_Prio           6			//task1优先级

OS_STK Task2_Stack[STACKSIZE]= {0, }; 	//task2 stack
void Task2(void *Id);            		//task2 任务
#define Task2_Prio           7			//task2优先级


//////////////////////////////////////////////////////////

OS_EVENT *QSem;
void     *QMsgTbl[100];//max 100

//***************************************/////////
//u16 key_code=0,new_key=0;

//=======================================================
//未校准,假定电压0-2.5V对应0-4095
//#define N1	0
//#define N2	4095
//校准值,电压0-2.5V对应N1-N2
#define N1	0x1B6
#define N2	0xD07

void Task1(void *Id) 	      	// Task1
{
	int n,m,i;
	char txmsg;

	UART_StringSend(UART0,(u8*)"Task1 Start ! Prio = 6\r\n");

	//设置P1.0位高阻三态模拟输入方式
	GPIO_Config(GPIO1, 0x0001, GPIO_HI_AIN_TRI);
	//初始化ADC转换器寄存器
	ADC12_Init();
	//用设定好的PCLK参数配置ADC的分频器寄存器,使得采样率为100Hz
	ADC12_PrescalerConfig(100);
	//选定转换模式为单通道
	ADC12_ModeConfig(ADC12_SINGLE);
	//选定要转换的通道为通道0
	ADC12_ChannelSelect(ADC12_CHANNEL0);
	//启动转换器
	ADC12_ConversionStart();
	
	while(1)
	{
	  	OSTimeDly(32);               	// 延时0.125秒

  		if((++i&0x03)==0) LedLightSet(0,2);


		//等待转换数据有效,用特定的标志判断
		if(ADC12_FlagStatus(ADC12_DA0) == RESET) continue;
		
		//从相应的数据寄存器中取出转换结果
		n = ADC12_ConversionValue(ADC12_CHANNEL0);
		//清除数据有效标志,新版函数库将此动作放到上面的函数中了
		ADC12->CSR &= ~ADC12_DA0;
		//补码转换成原码0-4095
		m=(n+0x800)&0xfff;		
		
		//在LCD上显示ADC结果的原码m和补码n
		LCD_GotoXY(10, 0);
		LCD_Printf("ADC raw value = 0x%03X (0x%03X)\n",m,n);
		
		//增益校准,转换成1000倍实际电压值		
		n=(2500*(m-N1))/(N2-N1);
		LCD_Printf("ADC Voltage = %04d mV\n",n);

		if(n>2000){	//over high limit
			txmsg='H';
	        OSQPost(QSem, (void *)&txmsg);
       		OSTimeDly(64);		//add extra delay
		}
		if(n<1000){	//below low limit
			txmsg='L';
	        OSQPost(QSem, (void *)&txmsg);
       		OSTimeDly(64);		//add extra delay
		}

	}
}
void Task2(void *Id) 	      	// Task2
{
	int k,n=0;
	char txmsg;
	float f; 

	UART_StringSend(UART0,(u8*)"Task2 Start ! Prio = 7\r\n");

	//Configure SDA & SCL pin of I2C0 to alternate function Open Drain
	GPIO_Config(GPIO1, 0x6000, GPIO_AF_OD);
	
	//Configure I2C0 module
	I2C_Init(I2C0);
	I2C_FCLKConfig(I2C0);
	I2C_OnOffConfig(I2C0, ENABLE);
	I2C_SpeedConfig(I2C0, 100000);
	
	while(1){
		LedLightSet(1,2);
		OSTimeDly(32);
	  	
		//Enable I2C acknowledge feature
		I2C_AcknowledgeConfig(I2C0, ENABLE);
		//Enable Start generation
		I2C_STARTGenerate(I2C0, ENABLE);
		while(!I2C_FlagStatus(I2C0,DIRECT,I2C_SB));		//wait for start condition

		//Send the slave address
		I2C_AddressSend(I2C0,0x90,I2C_Mode7,I2C_RX);
		while(SET!=I2C_FlagStatus(I2C0,DIRECT,I2C_ENDAD));	//wait for End of address transmission
		I2C_FlagClear(I2C0,I2C_ENDAD);	//clear the flag

		//Read MSbyte from the slave LM75A 
		k=I2C_ByteReceive(I2C0);

		//Disable I2C acknowledge feature
		I2C_AcknowledgeConfig(I2C0, DISABLE);
			
		//Read LSByte from the slave & stop the communication
		I2C_STOPGenerate(I2C0, ENABLE);		
		n=I2C_ByteReceive(I2C0);
		while(I2C0->CR & I2C_STOP_Mask);	//wait until STOP condition is sent, 
											//seems no lib function for this

	//===========================================================		
		//calculate 10*temperature
		n+=(k<<8);	//merge MSByte and LSByte
		n=n>>5;		//right justifying
		n=10*n;		//*10
		n=n>>3;		//*0.125 

		LCD_GotoXY(13, 0);
		
		//======
		//当使用浮点数时,Task2_Stack占用为146个字,不用浮点数为79个字
		//使用浮点数,STACKSIZE=128时,运行中发生堆栈溢出,程序异常
		
		//--使用整数运算的代码
		LCD_Printf("Temperature = %2d.%1d ^C \n",n/10,n%10);
		
		//--使用浮点运算的代码 
		//f=n;
		//f/=10; 
		//LCD_Printf("Temperature = %3.1f \n",f);
		//--!
		
		if(n>250){	//over high temp
			txmsg='T';
	        OSQPost(QSem, (void *)&txmsg);
       		OSTimeDly(64);		//add extra delay
		}
					
	}	//loop forever	

}


void Main_Task(void *arg)
{
	char *rxmsg=0;
	u8 err;
	int i,j,MsgCnt=0;


	UART_StringSend(UART0,(u8*)"Main Task Start ! Prio = 10\r\n");

	//用RTC产生256Hz时钟节拍
	RTC_PrescalerConfig(127);	//127
	RTC_FlagClear(RTC_OWIR);
	RTC_FlagClear(RTC_AIR);
	RTC_FlagClear(RTC_SIR);
	RTC_FlagClear(RTC_GIR);

	EIC_IRQChannelConfig(RTC_IRQChannel, ENABLE);
	EIC_IRQChannelPriorityConfig(RTC_IRQChannel, 1);
	EIC_IRQConfig(ENABLE);

	RTC_ITConfig(RTC_SIT | RTC_GIT, ENABLE);

	OSTimeDly(1);
//	OSStatInit();	

	for(i=0;i<STACKSIZE;i++) Task2_Stack[i]=0x55555555;	//将Task2的栈给定初值,以便观察其被占用情况

	QSem = OSQCreate(&QMsgTbl[0], 100);		//创建消息队列

	//建立其他任务
	OSTaskCreate(Task1, 0, Task1_Stack + (STACKSIZE - 1), Task1_Prio);
	OSTaskCreate(Task2, 0, Task2_Stack + (STACKSIZE - 1), Task2_Prio);
	OSTaskCreate(Key_Scan_Task,  (void *)0,  (OS_STK *)&Key_Scan_Stack[STACKSIZE-1],  Key_Scan_Prio  );//Key scak任务


	while(1)
	{
		rxmsg=(char *)OSQPend(QSem, 0, &err); //等待队列中的消息

		//更新消息计数显示
		MsgCnt++;
		for(j=0,i=MsgCnt;j<6;j++,i=i>>4)
			TLedCodeDisp(j,i&0x0f);
				
		//假定每个消息都是一个字节
		if(*rxmsg<16){	//key code
			UART_StringSend(UART0,(u8*)"你按键盘了 !\r\n");
		}
		else if(*rxmsg=='T'){		//temp over high
			UART_StringSend(UART0,(u8*)"温度超过25度了 !\r\n");
		}
		else if(*rxmsg=='H'){		//ADC voltage > high limit 
			UART_StringSend(UART0,(u8*)"ADC电压高过2V了 !\r\n");
		}
		else if(*rxmsg=='L'){		//ADC voltage < low limit 
			UART_StringSend(UART0,(u8*)"ADC电压低过1V了 !\r\n");
		}
		
		OSTimeDly(300);	//50
	}
}

static u8 KeyCode[16]={4,8,0xb,0xf,3,7,0xa,0xe,2,6,0,0xd,1,5,9,0xc};
u16 key_code=0;
void Key_Scan_Task(void *Id) 
{
	int i;
	u16 key,oldkey=0;
	u8 keystatus=0,keycnt=0;
	u32 bit;
	
	char txmsg;
	
	UART_StringSend(UART0,(u8*)"Task Scan key Start ! Prio = 5\r\n");
	for(;;){
		bit=1;
	
		while(1){
			while(1){
				key=ScanKey();
				if(key!=0)//有按键按下
					break;
				OSTimeDly(20);
				oldkey=0;
			}
			OSTimeDly(10);//Delay(500);
			if(key!=ScanKey())
				continue;

			if(oldkey!=key){
				keystatus=0;
			}
			if(keystatus==0){	//第一次按下此键
				keycnt=0;
				keystatus=1;
			}
			else if(keystatus==1){	//第二次重复此键
				keycnt++;
				if(keycnt==20)
					keystatus=2;
				else
					continue;
			}

			oldkey=key;
			break;
		}
		
		for(i=0;i<16;i++){	//查找一个按键
			if(key&bit)
				break;
			bit<<=1;
		}
		if(i>15) continue;
		key_code=KeyCode[i];

		//=====================================================
		txmsg=key_code;
        OSQPost(QSem, (void *)&txmsg);

		//=====================================================

//		new_key=1;
		if(keystatus==2) OSTimeDly(200);
	}
}

int main(void)
{
	#ifdef DEBUG
		debug();
	#endif

	EIC_Init();
	LedLightInit();
	LedLightSet(0,0);
	LedLightSet(1,0);
	LedLightSet(2,0);
	LedLightSet(3,0);

	EnableLedKey();
	TLedCodeDisp(0,0);
	TLedCodeDisp(1,0);
	TLedCodeDisp(2,0);
	TLedCodeDisp(3,0);
	TLedCodeDisp(4,0);
	TLedCodeDisp(5,0);

	
	LCD_Init();
	gClearScreen(LCD_BLUE);
	gSetBkColor(LCD_BLUE); 
	gSetColor(LCD_WHITE);

	LCD_GotoXY(0, 0);
	LCD_Printf("Message Queue Demo\n");
	LCD_Printf("Task1 : ADC Voltage\n");
	LCD_Printf("Task2 : I2C Temperature\n");
	LCD_Printf("Scan Key Task: Scan key pad\n");
	LCD_Printf("Main Task: send UART message\n");

	// Configure the GPIO pins
	GPIO_Config(GPIO0, UART0_Tx_Pin, GPIO_AF_PP);
	GPIO_Config(GPIO0, UART0_Rx_Pin, GPIO_IN_TRI_CMOS);

	// Configure the UART X
	UART_OnOffConfig(UART0, ENABLE);		// Turn UARTX on
	UART_FifoConfig(UART0, DISABLE);		// Disable FIFOs
	UART_FifoReset(UART0, UART_RxFIFO);		// Reset the UART_RxFIFO
	UART_FifoReset(UART0, UART_TxFIFO);		// Reset the UART_TxFIFO
	UART_LoopBackConfig(UART0, DISABLE);	// Disable Loop Back
		/* Configure the UARTX as following:
			- Baudrate = 57600 Bps
			- No parity
			- 8 data bits
			- 1 stop bit */
	UART_Config(UART0, 57600, UART_NO_PARITY, UART_1_StopBits, UARTM_8D);
	UART_RxConfig(UART0, ENABLE);          // Enable Rx

	UART_StringSend(UART0, (u8 *)"Hello, Multi-task Test!\r\n");


	OSInit();

	OSTaskCreate(Main_Task, 0, Main_Stack + (STACKSIZE - 1), Main_Task_Prio);

	OSStart();
}

⌨️ 快捷键说明

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