📄 main.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 + -