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