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